Skip to content

DailyDataPerUnit テーブル(db2023)のスキーマ前提

概要

日別データ(台単位)を格納するテーブルは DatabaseTableConstants::DAILY_DATA(値: db2023)で、実際のテーブル名は環境ごとの WordPress テーブル接頭辞を付与した {$wpdb->prefix}db2023 となる(例: 接頭辞が wp_ の場合は wp_db2023)。

差枚(samai): マイナス値を数値(INT 型)で格納する場合、samai カラムは SIGNED である必要がある(INT 型で UNSIGNED のまま負の値を INSERT すると MySQL が 0 に変換する)。

DAY 列の型と日付形式

項目正本備考
列型date NOT NULLDBML・ローカル・本番とも date(Issue #2297 時点で確認)
DB 格納・クエリバインドYYYY-MM-DDRepository は DateUtil::normalize_date_for_db() で統一
アプリ内契約(Entity・インポート map キー等)Y/n/j(例: 2025/1/10DateUtil::normalize_date_for_import()。読取時に Repository が正規化

DailyDataPerUnitRepository::insert_or_update_batch()INSERT ... ON DUPLICATE KEY UPDATE を使用しており、一意キー (DAY, dainum, hall) が DB に存在する前提で動作する。本ドキュメントはその制約の確認方法と、未定義時の対応方針をまとめる。

kishu 列の意味とアプリ利用方針

物理列名 kishu は「表示名」と「取得元機種名」を区別していない。アプリでは次のように扱う。

概念格納先アプリでの利用
表示用機種名db_kishu_master.namekishu_id JOIN)読取・表示・集計の正本
取得元機種名(raw)db2023.kishu書込のみ(インポート時)。Repository 読取 SQL では t.kishu を参照しない
既存行の db2023.kishu過去データ表示名が入っている場合がある。データ移行は行わない
  • インポート時: DailyDataImportService がマッピング前の raw 名称を db2023.kishu に書き込む(kishu_id は表示名ベースで解決)。
  • 重複キー更新時: kishu(取得元名)は incoming 値で上書きする。kishu_id は incoming が NULL のとき既存値を保持する(IFNULL(VALUES(kishu_id), kishu_id))。KishuIdResolver が解決失敗時に NULL を付与するため、既存の非 NULL kishu_id を誤って消さない。
  • 読取時: select_daily_data_per_unit.sql 等は m.name AS kishu とし、Entity の get_kishu_name()マスタの表示名 を返す(db2023.kishu 列の値ではない)。
  • SQL エイリアス kishu は歴史的経緯により表示名を指す。物理列 db2023.kishu とは別物である。

前提とする一意制約

  • カラムの組み合わせ: (DAY, dainum, hall)
  • 制約種別: UNIQUE KEY または PRIMARY KEY のいずれかがテーブルに定義されていること

RANGE パーティショニングの前提

Issue #2341 では、db2023PARTITION BY RANGE (YEAR(DAY)) を導入する方針とする。パーティション導入時は以下を前提にする。

  • DAYdate NOT NULL であること。varchar のまま式パーティションを導入しない。
  • すべての UNIQUE KEY / PRIMARY KEY がパーティション式に使う DAY を含むこと。
  • 本番適用は直接 ALTER TABLE ではなく、原則として pt-online-schema-change 等のオンライン DDL で行うこと。
  • 年次で翌年パーティションを追加し、p_future に通常データが溜まり続けないようにすること。導入後は月次 WP-Cron(DailyDataRangePartitionScheduler)が当年・翌年パーティションを自動確保する(初回 PARTITION 自体は自動しない)。

本番手順と計測 SQL は db2023 RANGE パーティショニング本番導入手順 を参照する。

スキーマ確認方法

本番または開発 DB に接続し、以下いずれかで制約の有無を確認する。以下ではテーブル名を {prefix}db2023 で表す。{prefix} は自環境の WordPress テーブル接頭辞(例: wp_)に読み替えて実行すること。

方法1: SHOW CREATE TABLE

sql
SHOW CREATE TABLE `{prefix}db2023`;

出力に UNIQUE KEY または PRIMARY KEYDAY, dainum, hall が含まれることを確認する。

方法2: information_schema

sql
SELECT `INDEX_NAME`, `COLUMN_NAME`, `NON_UNIQUE`
FROM information_schema.STATISTICS
WHERE `TABLE_SCHEMA` = DATABASE()
  AND `TABLE_NAME` = '{prefix}db2023'
ORDER BY `INDEX_NAME`, `SEQ_IN_INDEX`;

(DAY, dainum, hall) の組み合わせで一意制約(NON_UNIQUE = 0)または PRIMARY が存在するかを確認する。

関連コード

制約が未定義の場合の対応

スキーマ確認の結果、(DAY, dainum, hall) の UNIQUE KEY / PRIMARY KEY が存在しない場合は、以下を検討する。実際のマイグレーション実施は別 Issue に切り出してよい(Issue #686 の備考に従う)。

1. 既存データの重複調査

重複行が存在すると UNIQUE 追加時にエラーになるため、事前に確認する。

sql
SELECT `DAY`, `dainum`, `hall`, COUNT(*) AS cnt
FROM `{prefix}db2023`
GROUP BY `DAY`, `dainum`, `hall`
HAVING COUNT(*) > 1;

結果が 0 件であることを確認したうえで UNIQUE 追加を検討する。

2. UNIQUE KEY 追加のマイグレーション方針

  • 重複が存在する場合は、データ整理(どれを残すかの方針と SQL)を別途検討する。
  • 重複が存在しない場合、以下のように UNIQUE KEY を追加する。
sql
ALTER TABLE `{prefix}db2023`
ADD UNIQUE KEY uk_day_dainum_hall (`DAY`, `dainum`, `hall`);
  • 本番適用時はバックアップ取得・メンテナンス窓の確保を行う。
  • スキーマ変更は WordPress 側の Installer(core_src/Infrastructure/Database/dbDelta)で配布する方針とし、本番での手動 DDL が必要な場合は当該 *Installer.php の定義と手順書をドキュメント化することを推奨する。

3. ドキュメントの記載

制約が未定義であることが判明した場合は、本ドキュメントの「前提とする一意制約」の直後に「現状は未定義。insert_or_update_batch の期待動作のため、制約追加を推奨する。」などの注記を追記し、上記「制約が未定義の場合の対応」セクションとあわせて運用する。