遊戯王MDリミットレギュレーションをデータベースで表現する
公式ページのような、改訂日で区切って見られるほうがおもしろそうなので作ってみるあんも.icon
いい感じに処理を組んだら動作の再現もできそうあんも.icon
改定日を選んで表示する
改定日ごとにファイルを事前に生成しておく?
テーブル構成
カードマスター
公式データベースのカードIDを流用する
一意であることは保証されている
海外先行にもちゃんと振られていて都合がよい
ID順にするとリストの確認も簡単にできるようになったあんも.icon
実装日あたりが怪しいあんも.icon
サービス開始時の2022-01-19で埋めておく
規制履歴
カードIDで紐づける
マスターデータから情報が不足しているものを抽出する
リストにして入力させる
一度に完璧なマスターデータを作らなくてすむ
カード名のみのリストにIDを振るのにも使えそうあんも.icon
一発でできるようにしたあんも.icon
$ chmod +x scripts/build_db.sh
$ scripts/build_db.sh
ファイルを用意する
最近更新分あんも.icon
Twitterのリンクも情報として残しておきたい?
table:2025-06-24
card_id revision_date status
9095 2025-06-24 unlimited
4984 2025-06-24 unlimited
table:2025-07-04
card_id revision_date status
19150 2025-07-04 forbidden
20181 2025-07-04 limited
12906 2025-07-04 unlimited
15262 2025-07-04 unlimited
table:2025-08-04
card_id revision_date status
10354 2025-08-04 forbidden
11195 2025-08-04 forbidden
13824 2025-08-04 forbidden
20575 2025-08-04 semi_limited
8602 2025-08-04 unlimited
table:2025-09-10
card_id revision_date status
11840 2025-09-10 unlimited
12433 2025-09-10 unlimited
table:2025-10-08
card_id revision_date status
13163 2025-10-08 forbidden
20584 2025-10-08 limited
6161 2025-10-08 limited
20588 2025-10-08 limited
4343 2025-10-08 unlimited
19902 2025-10-08 unlimited
12292 2025-10-08 unlimited
15138 2025-10-08 unlimited
15141 2025-10-08 unlimited
18013 2025-10-08 unlimited
規制履歴の結合
code:bash
first=$(ls | grep -E '^0-9{4}-0-9{2}-0-9{2}\.csv$' | head -n1) head -n1 "$first" > combined_regulation.csv
for f in $(ls | grep -E '^0-9{4}-0-9{2}-0-9{2}\.csv$' | sort); do tail -n+2 "$f" >> combined_regulation.csv
done
データベースを構成する
UNIQUE (card_id, revision_date)
改訂一度につきカードは一度しか変更されない
同じ改訂日のデータを読ませないため
code:bash
sqlite3 regulation.db <<EOF
-- カードマスター(cards)
DROP TABLE IF EXISTS cards;
CREATE TABLE cards (
card_id INTEGER PRIMARY KEY,
card_name TEXT,
card_type TEXT CHECK(card_type IN ('monster', 'spell', 'trap')),
release_date TEXT
);
-- 規制履歴(regulation_changes)
DROP TABLE IF EXISTS regulation_changes;
CREATE TABLE regulation_changes (
card_id INTEGER NOT NULL,
revision_date DATE NOT NULL,
status TEXT CHECK(status IN ('forbidden', 'limited', 'semi_limited', 'unlimited')) NOT NULL,
FOREIGN KEY (card_id) REFERENCES cards(card_id),
UNIQUE (card_id, revision_date)
);
EOF
カードマスターのインポート
code:bash
sqlite3 regulation.db <<EOF
.mode csv
.import --skip 1 cardlist.csv cards
EOF
未登録カードに注意して新しい規制履歴をインポートする
code:bash
sqlite3 regulation.db <<EOF
PRAGMA foreign_keys = ON;
DROP TABLE IF EXISTS tmp_regulation_changes;
CREATE TEMP TABLE tmp_regulation_changes (
card_id INTEGER NOT NULL,
revision_date DATE NOT NULL,
status TEXT NOT NULL
);
.mode csv
.import --skip 1 combined_regulation.csv tmp_regulation_changes
# 一時テーブルを見て不足しているカードIDをカードマスターに補完してダミーデータで埋める
INSERT INTO cards (card_id, card_name, card_type, release_date)
SELECT DISTINCT t.card_id,
'UNKNOWN_' || t.card_id AS card_name,
'trap' AS card_type,
'1900-01-01' AS release_date
FROM tmp_regulation_changes t
LEFT JOIN cards c ON t.card_id = c.card_id
WHERE c.card_id IS NULL;
# 一時テーブルを規制履歴にインサート
INSERT OR IGNORE INTO regulation_changes (card_id, revision_date, status)
SELECT card_id, revision_date, status
FROM tmp_regulation_changes;
EOF
ダミーデータで埋められたカードIDを抽出して補完用CSVを出力
ダミー部分は空にしておく
code:bash
sqlite3 regulation.db <<EOF
.headers on
.mode csv
.once missing_cards_to_fill.csv
SELECT card_id,
'' AS card_name,
'' AS card_type,
'' AS release_date
FROM cards
WHERE card_name LIKE 'UNKNOWN_%';
EOF
補完CSVからカードマスターを更新する
code:bash
sqlite3 regulation.db <<EOF
CREATE TEMP TABLE cards_update (
card_id INTEGER PRIMARY KEY,
card_name TEXT,
card_type TEXT,
release_date TEXT
);
.mode csv
.import --skip 1 missing_cards_to_fill.csv cards_update
UPDATE cards
SET card_name = u.card_name,
card_type = u.card_type,
release_date = u.release_date
FROM cards_update u
WHERE cards.card_id = u.card_id;
EOF
更新したカードマスターを出力
code:bash
sqlite3 regulation.db <<EOF
.headers on
.mode tabs
.once cards_output.tsv
SELECT * FROM cards;
EOF
テスト用データ
table:cardlist
card_id card_name card_type release_date
12441 妖精伝姫-シラユキ monster 2022-01-19
7445 超融合 spell 2022-01-19
6901 簡易融合 spell 2022-01-19
13622 レッド・リブート trap 2022-01-19
table:combined_regulation
card_id revision_date status
12441 2024-12-06 limited
7445 2023-04-10 unlimited
6901 2023-05-01 forbidden
13622 2022-09-30 semi_limited
table:new_regulation
card_id revision_date status
4861 2025-05-09 semi_limited
13622 2022-01-19 limited
現行のレギュレーションをCSVで出力
code:bash
sqlite3 regulation.db <<EOF
.headers on
.mode csv
.output current_regulation.csv
SELECT
c.card_id,
c.card_name,
c.card_type,
c.release_date,
rc.status,
rc.revision_date
FROM
cards c
JOIN (
SELECT card_id, MAX(revision_date) AS latest_date
FROM regulation_changes
GROUP BY card_id
) latest
ON c.card_id = latest.card_id
JOIN regulation_changes rc
ON rc.card_id = latest.card_id AND rc.revision_date = latest.latest_date
WHERE
rc.status != 'unlimited'
ORDER BY
rc.status,
c.card_type,
c.card_name;
.output stdout
EOF