【注記】 2026-09-03、TeamWorks 提供の実DDL(
clean_watch_20260902.sql)と手書きprisma/schema.prismaの答え合わせのために作成した記録です(DDL文を直接パースする方法)。prisma db pullによる照合結果ddl-diff-dbpull.mdと対になる相互検証の記録です。両者を独立に突き合わせるために両方を残しています。 当時の記録であり、現行方針ではありません。 以降の決定はdocs/decisions.mdとdocs/handoff.mdを参照してください。
C:\Users\daich\Downloads\clean_watch_20260902.sql(46,390 bytes / mysqldump 10.13, MySQL 8.0.41, DB名 clean_watch)C:\Users\daich\dev\d-watch\prisma\schema.prisma(790行 / 28 model / 手書き版)01-master.md / 02-clean-error.md / 03-schedule-summary.mdprisma db pull)の成果物(pulled.prisma / diff.json / diff.txt / 30-dbpull-diff.md)は読んでいない。mine/parse_ddl.py)正規表現による分割は使わず、文字単位の状態機械で処理した。
CREATE TABLE \x` (を起点に、開き括弧から**括弧深度を数えて** depth が 0 に戻る位置までを1テーブルのブロックとして切り出す。 走査中は次を読み飛ばすため、decimal(12,6)やenum('a','b')` の内側の括弧・カンマでは壊れない。
\ エスケープ と '' 二重化の両方に対応)/* */ ブロックコメント、-- 行コメント、# 行コメントunsigned / zerofill / NOT NULL / DEFAULT / AUTO_INCREMENT / ON UPDATE / COMMENT / 生成列を抽出した。; までを table_options として ENGINE / CHARSET / AUTO_INCREMENT=n の取得に使った。結果: 39テーブル / 372カラム、パース失敗 0件。
健全性チェック(別手段での裏取り): DDL 本文の ^ \名前` 行を grep すると 368 行。 差の 4 行は列名に数字を含むaddr1/addr2`(customers と facilities に各2列)で、grep の文字クラスが数字を含まなかったための取りこぼし。 368 + 4 = 372 でパース結果と一致。取りこぼし・二重取りは無い。
model X { ... } を波括弧深度で切り出し、フィールド行ごとに @@map(物理テーブル名)/ @db.*(MySQL型)/ ?(NULL許容)/ @default(...)(括弧対応で抽出)/ @id / @updatedAt / @relation(fields:..., references:...) / @@index / @@unique を読んだ。 Type[] の配列フィールドと @relation 属性を持たない非スカラーフィールドは DB カラムではないので除外した。
結果: 28 model / 311 カラム、パース失敗 0件。
@db.* → MySQL 型の対応は UnsignedBigInt→bigint unsigned 等の表引きで正規化し、 @db.Timestamp(0) / @db.DateTime(0) の (0) は MySQL 既定精度なので型名からは落として比較した(誤差分を出さないため)。
DDL・prisma いずれもパース失敗は 0 件。ただし次の 3 点は解析上の制約として明記する。
| # | 箇所 | 内容 |
|---|---|---|
| P-1 | 定義書転記 md の「auto increment」 | 定義書は auto increment を初期値欄ではなく備考欄に書いている。素朴に初期値欄だけを比較すると22テーブルの id が「定義書に初期値なし / DDLはauto increment」という偽の差分になる。備考欄側を見て除外した(§7-8 の件数はこれを除外済み)。 |
| P-2 | 定義書 controls の id 行 |
定義書側の通し番号(#)欄が空欄のため、行番号が数字である前提のパーサでは行が落ちる。空欄も許容するよう修正して取り込んだ。 |
| P-3 | decimal の unsigned |
Prisma には unsigned decimal を表現する native type が無い。よって §4 の decimal 6件は「Prisma で表現できない差」であり、手書き版のミスとは言い切れない(ただし DB の実態としては unsigned なので差分として計上する)。 |
出力先 scratchpad\ddl\ は相手担当(db pull 側)と共有ディレクトリだった。 作業中に相手担当が同名の compare.py を同ディレクトリへ書き込み、当方のスクリプトが上書きされた。 その時点の比較結果 JSON は残っていたため結果への影響は無いが、以後は当方の成果物を scratchpad\ddl\mine\ に隔離した。 なお prisma/schema.prisma の md5 は a1d48b7927c2b93171d3394986abbdf1 で、相手担当が取ったバックアップ schema.prisma.HANDWRITTEN.bak と一致しており、手書き版の本体は書き換えられていないことを確認済み(比較には手書き版を使用)。
Laravel 基盤10テーブル(users / sessions / jobs / migrations / cache / cache_locks / failed_jobs / job_batches / password_reset_tokens / personal_access_tokens、DDL側で計60カラム)は比較から除外。
| 区分 | 件数 | テーブル |
|---|---|---|
| 実DDL にあり手書きに無い | 1 | clean_link_schedules |
| 手書きにあり実DDL に無い | 0 | (なし) |
| 両方にある | 28 | — |
カラム総数の整合(取りこぼしが無いことの確認): 共通カラム 300 + 実DDLのみ3 + clean_link_schedules 9 = 312(DDL業務側と一致)/ 共通カラム 300 + 手書きのみ11 = 311(prisma側と一致)。
clean_link_schedules について実DDL 上で link_schedules と構造が完全一致(列順まで一致、全カラムの型・unsigned・NULL許容・既定値・AUTO_INCREMENT・ON UPDATE がすべて同一、PK も id、FK も section_id → sections(id) の1本のみ)。詳細は §7-4。
| テーブル | カラム | 実DDL の定義 |
|---|---|---|
robot_error_reports |
responded_at |
datetime DEFAULT NULL |
control_error_histories |
responded_at |
datetime DEFAULT NULL |
control_reports |
serial_number |
varchar(100) NOT NULL |
| テーブル | カラム | 手書きの定義 | 判定 |
|---|---|---|---|
robot_error_reports |
responsed_at |
DateTime? @db.DateTime(0) |
綴り違い(実物は responded_at) |
control_error_histories |
responsed_at |
DateTime? @db.DateTime(0) |
綴り違い(実物は responded_at) |
control_reports |
sireal_number |
String @db.VarChar(100) |
綴り違い(実物は serial_number) |
section_robot_statuses |
indicatived_at |
DateTime? @db.Timestamp(0) |
実DDLに該当列が存在しない(改名先も無し) |
section_robot_statuses |
deleted_at |
DateTime? @db.Timestamp(0) |
実DDLに無い(論理削除なし) |
clean_statuses |
deleted_at |
DateTime? @db.Timestamp(0) |
実DDLに無い(論理削除なし) |
clean_schedules |
started_at |
DateTime? @db.DateTime(0) |
実DDLに無い |
clean_schedules |
ended_at |
DateTime? @db.DateTime(0) |
実DDLに無い |
clean_timetable_histories |
inactive |
Int @default(0) @db.UnsignedTinyInt |
実DDLに無い |
robots |
task_id |
String? @db.VarChar(20) |
実DDLに無い(robot_task_versions 側にのみ存在) |
robots |
version |
String? @db.VarChar(20) |
実DDLに無い(robot_task_versions 側にのみ存在) |
うち 3 件(responsed_at×2 / sireal_number)は単純な改名で、実質のカラム欠落は 8 件。
controls / customers / customer_contacts / customer_error_summaries / customer_summaries / devices / facilities / facility_contacts / facility_error_summaries / facility_summaries / groups / link_schedules / robot_instruct_histories / robot_task_versions / sections / security_statuses / security_status_histories / clean_status_histories / clean_task_reports / clean_timetables
カラム集合が一致しなかった 8テーブル(§3-1 / §3-2 の内訳): robot_error_reports / control_error_histories / control_reports / section_robot_statuses / clean_statuses / clean_schedules / clean_timetable_histories / robots
(型・既定値などの差分はカラム集合が一致していても存在する。§4 を参照。)
| テーブル | カラム | 実DDL | 手書き prisma | 影響 |
|---|---|---|---|---|
customer_contacts |
contact_type |
bigint unsigned |
Int @db.UnsignedTinyInt(= tinyint unsigned) |
大(Int↔BigInt。§7-6 参照) |
facility_contacts |
email |
varchar(255) |
String @db.VarChar(100) |
中(100超の値が読める/書けない不整合) |
robot_error_reports |
serial_number |
varchar(20) |
String @db.VarChar(50) |
中(21〜50文字を書くと切り詰め/エラー) |
robot_error_reports |
product_code |
varchar(20) |
String? @db.VarChar(50) |
中(同上) |
clean_statuses |
task_area |
decimal(12,6) unsigned |
Decimal @db.Decimal(12,6) |
小(P-3。Prisma で表現不可) |
clean_statuses |
clean_area |
decimal(12,6) unsigned |
Decimal @db.Decimal(12,6) |
小(P-3) |
clean_status_histories |
task_area |
decimal(12,6) unsigned |
Decimal @db.Decimal(12,6) |
小(P-3) |
clean_status_histories |
clean_area |
decimal(12,6) unsigned |
Decimal @db.Decimal(12,6) |
小(P-3) |
clean_task_reports |
task_area |
decimal(12,6) unsigned |
Decimal @db.Decimal(12,6) |
小(P-3) |
clean_task_reports |
clean_area |
decimal(12,6) unsigned |
Decimal @db.Decimal(12,6) |
小(P-3) |
customer_summaries |
task_area |
decimal(14,6) unsigned |
Decimal @db.Decimal(14,6) |
小(P-3) |
customer_summaries |
clean_area |
decimal(14,6) unsigned |
Decimal @db.Decimal(14,6) |
小(P-3) |
facility_summaries |
task_area |
decimal(14,6) unsigned |
Decimal @db.Decimal(14,6) |
小(P-3) |
facility_summaries |
clean_area |
decimal(14,6) unsigned |
Decimal @db.Decimal(14,6) |
小(P-3) |
手書き版が実DDLと型・unsigned まで完全一致していた点(差分ゼロだった箇所)で特筆すべきもの:
customers.prefecture_cd は実DDL も tinyint(unsigned なし)、facilities.prefecture_cd は tinyint unsigned。 手書き版のコメントにある「テーブル間で型が違う」という指摘は実DDLでもそのままで、手書き版の記述が正しい。robots.status / section_robot_statuses.robot_status はいずれも実DDL も smallint(符号あり)。一致。clean_statuses.clean_status / clean_status_histories.clean_status はいずれも実DDL も tinyint(符号あり)。一致(§7-3)。clean_task_reports.clean_time は実DDL も int unsigned。一致。| テーブル | カラム | 実DDL | 手書き prisma | 影響 |
|---|---|---|---|---|
robot_error_reports |
errored_at |
datetime DEFAULT NULL(NULL可) |
DateTime @db.DateTime(0)(必須) |
大。DB には NULL が入り得るのに型は非 null。読み出し時に実行時エラーになる |
| テーブル | カラム | 実DDL | 手書き prisma | 影響 |
|---|---|---|---|---|
robots |
battery |
DEFAULT '0' |
@default(100) |
大。満充電で作られる想定が実際は 0 |
clean_timetables |
precheck |
DEFAULT '0' |
@default(9) |
大。9 は「本清掃」ではない(§7-7) |
robots |
device_id |
既定値なし | @default(0) |
中。INSERT 時に明示必須 |
clean_timetables |
parent_id |
既定値なし | @default(0) |
中。同上 |
clean_task_reports |
created_at |
既定値なし(timestamp NOT NULL) |
@default(now()) |
中。アプリ側で必ず値を渡す必要がある |
clean_task_reports |
updated_at |
既定値なし(timestamp NOT NULL、ON UPDATE も無し) |
@default(now()) @updatedAt |
中。同上 |
security_status_histories |
reported_at |
既定値なし(timestamp NOT NULL) |
@default(now()) |
中。同上 |
clean_status_histories |
id |
AUTO_INCREMENT なし | @default(autoincrement()) |
大。採番されない(§4-4) |
clean_timetable_histories |
id |
AUTO_INCREMENT なし | @default(autoincrement()) |
大。採番されない |
updated_at について: 実DDL では clean_task_reports と section_robot_statuses の updated_at だけ ON UPDATE CURRENT_TIMESTAMP が付いていない(他の全テーブルは付いている)。 手書き版はどちらにも @updatedAt を付けているが、@updatedAt は Prisma 側で値を作るので実害は無い。ただし DB 直更新では自動更新されない点に注意。
| テーブル | 実DDL | 手書き prisma |
|---|---|---|
clean_status_histories |
PRIMARY KEY なし。UNIQUE KEY clean_status_histories_id_unique (id) のみ。id は bigint unsigned NOT NULL(AUTO_INCREMENT なし) |
id BigInt @id @default(autoincrement()) |
robot_error_reports |
PRIMARY KEY なし。UNIQUE KEY robot_error_reports_report_id_unique (error_id) のみ。id は varchar(50) NOT NULL で制約なし |
id String @id @db.VarChar(50)(error_id 側に @unique なし) |
この2件は実装への影響が大きい。
robot_error_reports は Prisma が id を一意識別子として扱うが、DB 上の一意制約は error_id にしかない。 id の重複を DB が止めないため、findUnique({ where: { id } }) が「一意でないキーでの検索」になる。 逆に error_id に @unique が無いので findUnique({ where: { error_id } }) は書けない。id は AUTO_INCREMENT でないため、採番はアプリ責任。| テーブル | 実DDL にのみある KEY | 手書きにのみある @@index |
|---|---|---|
clean_timetable_histories |
clean_schedule_id, start_at, end_at |
— |
control_reports |
control_id |
— |
link_schedules |
section_id |
— |
robot_task_versions |
— | clean_schedule_id |
robot_task_versions.clean_schedule_id は実DDL ではインデックスも外部キーも無い(robot_id にしか KEY が無い)。 この列での絞り込みはフルスキャンになる。
実DDL の業務テーブル FK は計 48本(KEY 67本 / UNIQUE 2本)。 48本すべてが ON DELETE / ON UPDATE の指定なし(= RESTRICT 相当)。 手書き版も onDelete を一切指定していないため、この点は一致。
| 区分 | 件数 | 内容 |
|---|---|---|
| 実DDL にあって手書きに無い FK | 0 | (なし) |
| 手書きにあって実DDL に無い FK | 3 | 下表 |
| テーブル | 手書きのリレーション | 実DDL の状態 |
|---|---|---|
clean_statuses |
clean_timetable_id → clean_timetables(id) |
FK なし(KEY も無い) |
clean_status_histories |
clean_timetable_id → clean_timetables(id) |
FK なし(KEY も無い) |
robot_task_versions |
clean_schedule_id → clean_schedules(id) |
FK なし(KEY も無い) |
いずれも「参照整合性が DB では担保されていない」方向の差分。 Prisma のリレーションとしては動作するが、DB 側は孤児行を許す。
一方、手書き版が clean_timetable_id をあえてリレーションにしなかった robot_error_reports と clean_task_reports は、実DDL でも FK なし・KEY なしで判断が正しかった。 clean_timetables.parent_id の自己参照を張らなかったのも実DDL と一致(FK なし、KEY はある)。
controls.facility_id は実DDL に FK あり。手書き版(TeamWorks B-2 回答を反映済み)と一致。
カラム集合・型・unsigned・NULL許容・既定値・PK・UNIQUE・FK のすべてが一致した 11テーブル:
controls / customers / customer_error_summaries / devices / facilities / facility_error_summaries / groups / link_schedules / robot_instruct_histories / sections / security_statuses
ただし link_schedules は @@index([section_id]) が手書きに無い(§4-5)。 インデックスまで含めて完全一致なのは残り 10テーブル。
customer_summaries / facility_summaries は decimal の unsigned(P-3、Prisma 表現不可)以外は一致。 facility_contacts は email のサイズ以外は一致。customer_contacts は contact_type の型以外は一致。
定義書転記の集計: 29テーブル / 317カラム(makers を含む)。
responsed_at の実際のカラム名 → responded_at(正しい綴り)| 定義書 | 実DDL | 該当テーブル |
|---|---|---|
responsed_at |
responded_at |
robot_error_reports(datetime DEFAULT NULL) |
responsed_at |
responded_at |
control_error_histories(datetime DEFAULT NULL) |
定義書の綴りが誤記だった。 TeamWorks 確認項目 C-1 はこれで解決。 手書き版は「実DDL 入手まで定義書表記のまま」という方針で responsed_at としているので、2箇所とも改名が必要。
| 定義書の綴り | 実DDL | 判定 |
|---|---|---|
control_reports.sireal_number |
serial_number |
定義書が誤記。定義書の索引欄が fk_control_reports_serial_number だった方が正しく、定義書内の矛盾は serial_number 側で決着 |
clean_timetables の索引対象 secction_id |
section_id(索引名も clean_timetables_section_id_foreign) |
定義書が誤記。手書き版が section_id と解釈したのは正しい |
section_robot_statuses.indicatived_at |
該当列が存在しない | 綴り違いではなく列そのものが廃止(indicated_at という列も無い)。§7-5 |
clean_status)が実DDL でどう解決されているか定義書は clean_status を unsigned tinyint としながら、備考に -1: 清掃完了(セキュリティ無効) と書いており、 unsigned では格納できない値を要求する自己矛盾があった(clean_statuses と clean_status_histories の2箇所)。
実DDL の答え: 両テーブルとも clean_status tinyint NOT NULL DEFAULT '0'(unsigned なし = 符号あり)。 -1 は格納可能。定義書の型表記が誤りで、備考の値定義が正しかった。
-1 があるため符号あり tinyint)は実DDL で裏が取れた。Int @db.TinyInt にしており、実DDL と一致。この箇所は修正不要。clean_status_trans / clean_error は実DDL でも tinyint unsigned(負値なし)。手書き版と一致。robots.clean_status / section_robot_statuses.clean_status は実DDL でも tinyint unsigned のままで、 A-2 の -1 再定義はこの2テーブルには及んでいない。手書き版も unsigned のままで一致。clean_link_schedules は何をするテーブルか事実(DDL から確定できること):
| カラム | 型 | NULL | 既定値 | 備考 |
|---|---|---|---|---|
id |
bigint unsigned |
NOT NULL | — | AUTO_INCREMENT, PRIMARY KEY |
section_id |
bigint unsigned |
NOT NULL | — | FK → sections(id)、KEY あり |
type |
tinyint unsigned |
NOT NULL | 1 |
|
weeks |
varchar(7) |
NOT NULL | — | |
intervals |
varchar(120) |
NOT NULL | — | |
inactive |
tinyint unsigned |
NOT NULL | 0 |
|
created_at |
timestamp |
NOT NULL | CURRENT_TIMESTAMP |
|
updated_at |
timestamp |
NOT NULL | CURRENT_TIMESTAMP |
ON UPDATE CURRENT_TIMESTAMP |
deleted_at |
timestamp |
NULL | NULL |
link_schedules(定義書では「通信スケジュール」)と構造が完全一致。 列名・列順・型・unsigned・NULL許容・既定値・AUTO_INCREMENT・ON UPDATE がすべて同一、PK も id、FK も section_id → sections(id) の1本のみ。機械的に照合済み。link_schedules は AUTO_INCREMENT=10、 clean_link_schedules は AUTO_INCREMENT= の記載自体が無い。 mysqldump は次回採番値を出すので、これは clean_link_schedules に一度も行が挿入されていないことを示す。★以下は推測(DDL からは確定できない)★
link_schedules から分離する目的で作られた、 もしくは link_schedules を clean_link_schedules へ改名する移行の途中である可能性が高い。 構造が完全一致で中身が空という組み合わせは、改名・複製の作りかけに典型的なパターン。clean_ 接頭辞は他の清掃系テーブル(clean_schedules / clean_timetables / clean_statuses)の命名に揃えたものと見える。 ただし clean_schedules への FK は無く、section_id しか持たないので、清掃スケジュールとの直接の紐付けは DDL 上に存在しない。link_schedules にのみデータがあるため、実装は link_schedules を使うのが安全。テーブル 1件:
| 定義書 | 実DDL | 補足 |
|---|---|---|
makers(メーカー) |
無い | TeamWorks 回答 A-1「makers テーブルは提供されない」が実DDLで裏付けられた。devices.maker_id は実DDL でも tinyint unsigned で FK なし。手書き版の扱いと一致 |
カラム 11件(うち3件は §7-1/7-2 の改名なので、実際の廃止は 8件):
| テーブル | 廃止されたカラム | 定義書での定義 |
|---|---|---|
robots |
task_id |
varchar(20) — robot_task_versions 側にのみ残る |
robots |
version |
varchar(20) — robot_task_versions 側にのみ残る |
clean_schedules |
started_at |
datetime(定義書のキー欄は idx だが索引欄に対応行が無かった列) |
clean_schedules |
ended_at |
datetime(同上) |
clean_statuses |
deleted_at |
timestamp — 論理削除が廃止 |
section_robot_statuses |
deleted_at |
timestamp — 論理削除が廃止 |
section_robot_statuses |
indicatived_at |
timestamp(状態変更日時) |
clean_timetable_histories |
inactive |
unsigned tinyint — 履歴に無効フラグは不要という判断か |
clean_schedules.started_at / ended_at の廃止は、定義書側の「キー欄は idx なのに索引欄に対応エントリが無い」という 不整合が「列自体が無くなった」形で決着したことを意味する。手書き版が @@index を書かずに保留したのは結果的に妥当だった。
同様に clean_timetable_histories の索引 idx_..._started_at / idx_..._ended_at は、 実DDL では clean_timetable_histories_started_at_index (start_at) / clean_timetable_histories_ended_at_index (end_at) として存在する。 つまり索引名は started_at / ended_at のまま、対象カラムは start_at / end_at。 定義書の「索引名と実カラム名が一致しない」という指摘は実DDL でもそのまま残っている(索引名だけが古い)。
| テーブル.カラム | 定義書 | TeamWorks 回答 (B-6) | 実DDL | 手書き版 |
|---|---|---|---|---|
customer_contacts.contact_type |
unsigned bigint |
「typo。unsigned tinyint に修正」 | bigint unsigned |
Int @db.UnsignedTinyInt |
facility_contacts.contact_type |
unsigned tinyint |
「unsigned tinyint」 | tinyint unsigned |
Int @db.UnsignedTinyInt |
customer_contacts.email |
varchar(100) |
— | varchar(100) |
@db.VarChar(100) |
facility_contacts.email |
varchar(255) |
「typo。varchar(100) に修正」 | varchar(255) |
@db.VarChar(100) |
定義書の記載(両テーブルで型・サイズが不揃い)が実DB の実態と一致していた。 TeamWorks が「typo なので揃える」と回答した2点は、実DB には適用されていない。 手書き版は回答を信じて揃えてしまったため、この2箇所が実DDL とずれている(§4-1)。
これは「定義書 vs 実DDL」ではなく「TeamWorks 回答 vs 実DDL」の食い違いであり、 回答が将来の修正予定なのか、回答が誤りなのかを確認する必要がある。
precheck 逆転問題の決着定義書では clean_timetables.precheck の既定値が 9(備考: 0: 本清掃, 1: 1回目, 2: 2回目 ...)、 clean_timetable_histories.precheck の既定値が 0(備考: 0: 未設定, ... 9: 本清掃)で、 初期値とコード値の対応がテーブル間で逆転していた。
実DDL の答え: 両テーブルとも precheck tinyint unsigned NOT NULL DEFAULT '0'。
TeamWorks 回答 B-1(0: 本清掃 / 1: 1回目 / 2: 2回目、clean_timetables の定義が正)と整合する。 定義書の clean_timetables 側の既定値 9 が誤り。 手書き版は「既定値 9 の意図は未確認」として @default(9) を維持しているので、@default(0) へ修正が必要。
(P-1 の「auto increment が備考欄」による偽陽性 22件を除外した実差分)
| テーブル.カラム | 定義書 | 実DDL |
|---|---|---|
robots.battery |
100 |
0 |
clean_timetables.precheck |
9 |
0(§7-7) |
robots.device_id |
0 |
既定値なし |
clean_timetables.parent_id |
0 |
既定値なし |
clean_task_reports.created_at |
システム日付 | 既定値なし |
clean_task_reports.updated_at |
システム日付 | 既定値なし |
security_status_histories.reported_at |
システム日付 | 既定値なし |
(表は7行。clean_timetables.precheck を §7-7 と重複計上しない場合は 6件。)
robots.battery の 100 → 0 は定義書と実DDL の実質的な食い違いで、 手書き版も定義書に従って @default(100) としているため要修正。
| テーブル.カラム | 定義書 | 実DDL | 備考 |
|---|---|---|---|
clean_statuses.clean_status |
unsigned tinyint |
tinyint |
§7-3。定義書の型が誤り |
clean_status_histories.clean_status |
unsigned tinyint |
tinyint |
§7-3。同上 |
clean_status_histories.task_area |
decimal(12,6) |
decimal(12,6) unsigned |
定義書内で表記が不統一だった箇所(clean_statuses だけ unsigned decimal)。実DDL は3テーブルすべて unsigned |
clean_status_histories.clean_area |
decimal(12,6) |
decimal(12,6) unsigned |
同上 |
clean_task_reports.task_area |
decimal(12,6) |
decimal(12,6) unsigned |
同上 |
clean_task_reports.clean_area |
decimal(12,6) |
decimal(12,6) unsigned |
同上 |
robot_error_reports.serial_number |
varchar(50) |
varchar(20) |
定義書の方が大きい |
robot_error_reports.product_code |
varchar(50) |
varchar(20) |
同上 |
robot_error_reports.errored_at |
必須(○) | DEFAULT NULL(NULL可) |
§4-2 |
定義書の decimal 表記の不統一(転記者が「矛盾点7」として挙げていた箇所)は、 実DDL では6カラムすべて unsigned で決着した。
| テーブル.カラム | 定義書のキー欄 | 実DDL |
|---|---|---|
clean_statuses.clean_timetable_id |
fk | FK なし(KEY も無し) |
clean_status_histories.clean_timetable_id |
fk | FK なし(KEY も無し) |
robot_task_versions.clean_schedule_id |
fk | FK なし(KEY も無し) |
controls.facility_id |
(空欄) | FK あり → facilities(id) |
controls.facility_id は定義書内でも矛盾していた(カラム表のキー欄は空欄、索引欄には fk_controls_facility_id あり)。 実DDL は索引欄の側が正しく、FK は存在する。 TeamWorks 回答 B-2 と整合。
逆に clean_timetable_id / clean_schedule_id の3本は、定義書が fk と書いているのに実DB には無い。 手書き版は定義書に従ってリレーションを張っているため、実DDL とずれている(§5)。
DDL 自身の中に残っている命名のズレ。実害は無いが、索引名で列を推測すると誤る。
| テーブル | 索引 | 名前から推測される列 | 実際の対象列 |
|---|---|---|---|
clean_timetable_histories |
KEY clean_timetable_histories_started_at_index |
started_at |
start_at |
clean_timetable_histories |
KEY clean_timetable_histories_ended_at_index |
ended_at |
end_at |
robot_error_reports |
UNIQUE KEY robot_error_reports_report_id_unique |
report_id |
error_id |
3件目は特に紛らわしい。robot_error_reports に report_id という列は無く(report_id は clean_task_reports の PK)、 一意制約が乗っているのは error_id。
| 種類 | 件数 |
|---|---|
| テーブル(定義書のみ / 実DDLのみ) | 2(makers / clean_link_schedules) |
| カラム(定義書のみ) | 11(うち改名3・実質廃止8) |
| カラム(実DDLのみ) | 3(すべて §7-1/7-2 の改名先) |
| 型・unsigned | 6 |
| サイズ | 2 |
| NULL許容 | 1 |
| 既定値 | 6 |
| 外部キー | 4 |
| 合計 | 35 |
(別枠)TeamWorks 回答が実DB に反映されていない箇所: 2(§7-6) (別枠)実DDL 内部の索引名と対象列の不一致: 3(§7-11)
| 種類 | 件数 |
|---|---|
| テーブル(実DDLのみ) | 1 |
| テーブル(手書きのみ) | 0 |
| カラム(実DDLのみ) | 3 |
| カラム(手書きのみ) | 11 |
| 型・サイズ・unsigned | 14 |
| NULL 許容 | 1 |
| 既定値 | 9 |
| 主キー | 2 |
| ユニークキー | 2 |
| 外部キー(手書きのみ) | 3 |
| 外部キー(実DDLのみ) | 0 |
| インデックス | 6 |
| 合計 | 52 |
robot_error_reports.responsed_at → responded_at に改名(列が存在しないためクエリが即エラー)control_error_histories.responsed_at → responded_at に改名(同上)control_reports.sireal_number → serial_number に改名(同上)robot_error_reports の PK / UNIQUE: DB の一意制約は error_id のみ。id に一意制約なし。@id の置き方とアプリ側の採番方針を決める必要があるrobot_error_reports.errored_at を nullable に(DB は NULL 可。非 null 型のままだと読み出しで実行時エラー)clean_status_histories / clean_timetable_histories の id から @default(autoincrement()) を外す(DB は AUTO_INCREMENT でない。採番はアプリ責任)clean_status_histories の PK: DB は PRIMARY KEY を持たず UNIQUE(id) のみcustomer_contacts.contact_type は bigint unsigned(Int → BigInt に変更。TeamWorks B-6 回答と実DB が食い違っており要確認)robots.battery の既定値 100 → 0clean_timetables.precheck の既定値 9 → 0facility_contacts.email は varchar(255)(B-6 回答と実DB が食い違っており要確認)robot_error_reports.serial_number / product_code は varchar(20)(50 のまま書くと切り詰め・エラー)robots.task_id / robots.version / clean_schedules.started_at / clean_schedules.ended_at / clean_statuses.deleted_at / section_robot_statuses.indicatived_at / section_robot_statuses.deleted_at / clean_timetable_histories.inactiveclean_statuses.clean_timetable_id / clean_status_histories.clean_timetable_id / robot_task_versions.clean_schedule_id。参照整合性が担保されていないので孤児行を前提にしたコードが必要clean_task_reports.created_at / updated_at、security_status_histories.reported_at に DB 既定値が無い(INSERT で必ず値を渡す)clean_link_schedules の扱いを TeamWorks に確認(link_schedules と構造完全一致・データ0件。改名途中の可能性)robot_task_versions.clean_schedule_id はインデックスすら無い(この列での絞り込みはフルスキャン)scratchpad\ddl\mine\)parse_ddl.py — DDL を括弧対応でパースし ddl_parsed.json を生成cmp2.py — インデックス差分 / DDL内部の索引名不一致 / 定義書 vs DDL のテーブル・カラム・型差分cmp3.py — 定義書 vs DDL の初期値差分 / fk 指定差分cmp4.py — clean_link_schedules と link_schedules の構造一致検証