【入門編】 外部キー制約 – Cloud Spanner

やあ。Cloud Spannerの世界へようこそ。
大規模システムの心臓部を支えるこのデータベースについて学ぼうとしている君は、とても素晴らしい選択をしたね。

今日は、Spannerの中でも「外部キー(Foreign Key)」という、データの「秩序」を守るための門番について話をしよう。専門用語に溺れる必要はない。日常の風景を借りて、その本質を紐解いていくよ。

—

1. 外部キーって、結局なに?

君が図書館の管理システムを作っていると想像してみてほしい。「本」と「貸出記録」という2つのテーブル(管理表)があるとするよね。

もし、「まだ図書館に登録されていない本」の貸出記録が作られたらどうなるだろう?「どの本を貸したか分からない」という大混乱が起きるはずだ。

外部キー制約とは、いわば「登録されていない本は貸し出し禁止!」という図書館の厳格なルールのことだ。「貸出記録」に書かれる「本のID」が、ちゃんと「本」のリストに存在しているか、データベースが自動で見張ってくれる仕組みなんだ。

これがあるおかげで、システムの中に「幽霊のようなデータ(親のいない子)」が生まれるのを防げる。これが「参照整合性(データのつじつまが合っていること)」の正体だよ。

—

2. 「ON DELETE CASCADE」という名の強力な自動掃除機

外部キーには、便利なオプションがある。それが `ON DELETE CASCADE` だ。

例えば、図書館から「本」を廃棄したとする。普通なら「その本が貸し出されていた記録」が迷子になってしまうよね。でも、`ON DELETE CASCADE` を設定しておくと、「親(本)が消えたら、連動して子(貸出記録)も自動的に削除する」という魔法が働くんだ。

— 本のテーブル
CREATE TABLE Books (
BookId INT64 NOT NULL,
Title STRING(MAX),
) PRIMARY KEY (BookId);

— 貸出記録テーブル(親が消えたら、子も一緒に消える設定)
CREATE TABLE Loans (
LoanId INT64 NOT NULL,
BookId INT64 NOT NULL,
CONSTRAINT FK_Book FOREIGN KEY (BookId) REFERENCES Books (BookId) ON DELETE CASCADE
) PRIMARY KEY (LoanId);

  • ポイント: これを設定しておけば、手作業で「本を消す→関連する貸出記録を消す」という二度手間をしなくて済む。非常に便利だよね。

—

3. 注意!「便利さ」の裏側にあるコスト

さて、ここからがエンジニアとしての「極限の知見」だ。
便利だからといって、何も考えずに外部キーを詰め込むのは危険だよ。

  • 書き込みのコスト: データベースは、データを書き込むたびに「このIDは本当に存在するか?」というチェックを裏で行っている。つまり、チェックの回数分だけ、データベースの仕事が増えるということだ。
  • ロックの連鎖: `ON DELETE CASCADE` で大量のデータを一気に消すと、関連するテーブルまでロックがかかり、他の処理が一時的に待たされてしまうことがある。

Spannerは世界規模で動く超高性能なデータベースだ。でも、「制約を強固にすればするほど、データベースは慎重に動くようになる」という物理法則は変わらない。

「本当にこの整合性はシステム的に必須か?」を常に自問自答してほしい。もしパフォーマンスが最優先で、多少の不整合はアプリケーション側で吸収できるなら、あえて外部キーを使わないという設計判断も、プロの現場では大いにあり得るんだ。

—

4. まとめ:君はもうマスターした

ここまでの話を整理しよう。

1. 外部キーは「データの秩序」を守る門番。
2. `ON DELETE CASCADE` は、連動して掃除してくれる自動掃除機。
3. ただし、便利さと引き換えに書き込みの負担(コスト)が少し増えることを忘れないこと。

これさえ押さえておけば、君はもうCloud Spannerの設計における「一番大切な門」をくぐり抜けたも同然だよ。

データベース設計は、パズルに似ている。ルール(制約)を厳しくすれば安心感は増すけれど、複雑になりすぎる。どこまでをシステムに任せ、どこからをアプリケーションの知恵で解決するか。そのバランス感覚こそが、優れたアーキテクトへの第一歩だ。

今の君なら、きっと素晴らしいシステムを作れるはずだよ。応援しているよ!何か迷ったら、いつでも聞きに来てね。

コメント

タイトルとURLをコピーしました