データベースの構造は実際どこにあるのか
この記事の内容
このサービスがすることは、すべてバージョン管理の中にある。少なくともコードは。動いている先のデータベースは 32 の表で、そのうち 15 はリポジトリのどこにも定義がない — CREATE TABLE もなければ、スキーマのファイルもなく、何もない。バックアップは 32 すべてを形ごと戻す。リポジトリにないのは、その形の二つめの、独立した写しである。
これらの数字は、動いているデータベースを 736 ファイル・5,671,710 文字のリポジトリと突き合わせて出したものだ。見積もりではない。
構造の半分はこうして消える
ずさんさではない。だからこそ書き留める値打ちがある。一つ一つの手順は、どれも理にかなっていた。
いまのコードより前に作られた表は、書き留められたことがない。当時はただそこにあったからだ。以後に足された表は移行スクリプトで入り、それらはリポジトリにある — 17 の定義はそこから来ている。あとから足された列は、一行の ALTER TABLE を端末で打って入った。一秒で終わる変更のためにスクリプトを書くより、打つほうが速かったからだ。
いちばん厄介なのは索引である。索引は何かが遅いときに、遅いその場で足され、その場で直る。あとには何も残らない。見直すものもなく、忘れても落ちるものがない。ここにある三十二の二次索引のうち十一は、まさにそれで生まれ、どこにも記録がない。
カウンターそのものが入っている表、166,438 行あるそれも、定義のない十五のうちの一つだ。
本当に壊れるのはどこか
ほとんど壊れない — ある一点までは。データベースをダンプから戻すときである。
ダンプは構造も運ぶので、素直に戻すぶんには問題ない。危ないのは、表を戻すのではなく作り直す道すじだ。別の機械への引っ越し、選んだ表だけの取り込み、スクリプトからの再作成。データは戻り、索引は黙って戻らない。何も失敗しない。問い合わせは正しい答えを返す。ただ時間がかかるようになるだけで、原因は見えない。その索引が何だったかの唯一の記録は、もうそれを持っていない機械の上にあるからだ。
これこそ名前をつけておくべき壊れ方である。欠けた索引はエラーを出さない。遅い正しい答えを出す。これを捕まえる試験はない。試験は通ってしまうからだ。
それまでのあいだ何をするか
構造は今日、リポジトリにない。それが状態の正確な記述である。備わっているものは完全な修正より狭く、実際に費えの出る場合を覆っている。
壊す操作の前には必ずダンプを取り、ウェブの公開場所の外に置く。実際に一度は行った復元 — 済んだつもりではなく。そして復元のたびに確かめる短い一覧、動いているデータベースにしかないと分かっている索引の一覧。機械には「どんな索引を持っているか」と尋ねられるし、その答えは前回のものと比べられる。
一般化した話は、データベースにとどまらない。システムの一部が動いている系の中にしかないなら、その二つめの写しは存在しない。どんな設備についても問う値打ちがあるのは、控えがあるかどうかではなく、この機械が消えたらリポジトリから組み直せないものは何か、である。ここでの答えは十五の表と十一の索引で、それを定めるのに午後が一つかかり、それは未知ではなく一覧になっている。
更新:2026 年 9 月
この記事の五日後、作業ディレクトリがコミットされました。26 ファイル、4,058 行。そのうち十一本は 8 月 28 日から 9 月 1 日までに書かれた移行スクリプトで、それまでは動いている機械の上にしかありませんでした。これは易しいほうの半分です — 書かれたのに記録されなかったコードです。
2026 年 9 月 1 日、同じやり方で測り直しました。動いているデータベースを、git が知っているすべてと突き合わせます。
| テーブル | 46 | 30 はリポジトリに CREATE TABLE があり、16 はどこにもない |
| 二次索引 | 43 | 32 はリポジトリのコードが作り、11 は動いているデータベースにしかない |
| 移行スクリプト | 109 | バージョン管理下 |
肝心の数は動いていません。8 月 27 日、動いているデータベース以外のどこにも存在しない二次索引が十一ありました。9 月 1 日、やはり十一です。その間に十一の索引が新たに加わり、そのどれもが移行スクリプトを伴っていました。習慣は変わり、負債は変わりませんでした。
その十一は五つのテーブルに載っています — カウンター、言語、参照元、除外リスト、そして出来事の記録です。五つとも今のコードより古く、だからこそ何も書き留められませんでした。いまファイルを起こすとは、何年も前にプロンプトで打たれたものを、動いているサーバーから復元するということです。
8 月の立場はそのままです。スキーマは相変わらずリポジトリになく、テーブルを戻すのではなく作り直す復旧なら、いまも十一の索引を何も言わずに失います。変わったのはもっと小さなことです。以降に加わったものは、すべてファイルを残しました。