← メディア一覧

データの「幽霊」を防ぐ参照整合性制約

13分04秒 | DB基礎FE

基本情報技術者試験の頻出テーマを解説した音声コンテンツです。

トランスクリプト(字幕テキスト)

今回のテーマはですね、データベースをクリーンでこう、論理的に保つためのいわば門番のようなルールについてです。 データの幽霊が現れるのを防ぐ、非常に重要でありながら、実はとてもエレガントな仕組みを掘り下げていこうと思います。 今回扱う資料は、参照整合性制約という考え方を解説したテキストなんですが、 一見なんかこう専門的に聞こえますけど、大丈夫です。これは私たちの現実世界に、ええ、とてもよく似た直感的なルールなんですよ。 では早速ですが、あなたに質問です。もし存在しない未来戦略部みたいな部署に 新入社員を配属させようとしたら、データベースの中では一体何が起きるべきだと思いますか? 今日はこの疑問から話を始めてみましょう。では早速中身を見ていきましょうか。 えっと、ここに社員名簿と部署名簿っていう2つのデータ表があると想像してみてください。 社員名簿にはもちろん社員の名前とかIDがあって、それに加えてどの部署に所属しているかを 示すための部署コードが記録されています。ここで問題が起きるわけです。 もし私が新しい社員を登録するときに、部署名簿には存在しない、全くのでたらめな 部署コード999番とかを割り当ててしまったら、どうなるんでしょう。 資料ではこれを幽霊社員と呼んでいますが、まさに言い得て妙ですよね。 ええ、ええ。所属先が実在しない、なんかこう宙に浮いたデータが生まれてしまう。 これは後々大変なことになりそうです。まさに出航なんです。その大変なことを未然に防ぐのが、 今回の革新である参照整合性制約なんですね。参照整合性制約。 はい。これはデータベース自身がデータの論理的な正しさを守るために持っている、 まあ自己防衛機能のようなものだと考えてください。ここで少しだけ専門用語を解説させてください。お願いします。 部署名簿にある部署を1つに特定するための部署コード、これを主キーと呼びます。主キー。 はい。そして社員名簿側でその部署を参照するために使われる部署コード、こちらを外部キーと呼びます。 なるほど。この制約が課すルールは驚くほどシンプルで、 外部キーに入れる値は必ず参照先の主キーに存在する値でなければならない。たったこれだけなんですよ。 なるほど。つまり社員の所属部署コードは必ず部署名簿に実在する部署のコードでなければいけないってことですね。 でもここで1つ疑問が湧いてきました。はい。そういうチェックってデータを登録するアプリケーション側でやればいい話じゃないですか? なぜわざわざデータベース自体にそんなルールを持たせる必要があるんでしょう。あー、非常に良い質問ですね。 昔のまあシンプルなシステムならそれでも良かったのかもしれないんですが、ただ現代のシステムはデータが入ってくる経路が一つじゃないんですよ。 ああ。ユーザーが画面から入力するデータもあれば、他のシステムからAPI経由で流れてくるデータ、 あるいは管理者が一括でインポートするデータもある。その全ての入り口で 完璧に同じチェックを間違いなく実装し続けるのって、実は非常に難しいんです。確かに。 どこか1つでもチェックが漏れれば、その幽霊は生まれてしまいますからね。ああ、なるほど。 アプリケーションはたくさんあるかもしれないけど、データベースはただ一つだと。だからその最後の砦であるデータベース自身が、 私の中に入るデータは論理的に正しくなければ絶対に受け入れませんという、こう強い意志を持つ必要があるわけですね。 まさにその通りです。だから門番という例えは非常に的確なんですよ。どの経路からデータが来ようとも、 この門番が部署名簿をしっかりと確認して、部署999番名簿にありませんね、このデータは通せません。 うんうん。矛盾したデータが入り込むのを防いでくれる。このおかげで私たちはデータベースの中のデータが、 少なくとも関係性においては常に正しいと信頼できるわけです。入り口のチェックが完璧だということはよくわかりました。 門番がしっかり仕事をしてくれるんですね。でも話はこれで終わりませんよね。 もし後からその親である部署自体がなくなったらどうなるんですか?ええ。 例えば業績不振で営業部が廃止になったとします。部署名簿から営業部のデータを削除したら、 そこにいた社員のデータは一体どうなってしまうんでしょう。そこがこの話のもう一つの重要な側面です。 ここで親子関係という考え方が出てきます。親子関係。はい。 参照される側の部署名簿が親、そして参照する側の社員名簿が子という関係ですね。 親である部署が突然いなくなってしまったら、そこに所属していた子である社員たちは、 まあ路頭に迷ってしまいますよね。うわー、それはまずいですね。データベースの中に孤児が大量に生まれてしまうみたいな。 システムはそれをどうやって防ぐんですか?何か警告が出るんでしょうか。それとも気づかないうちにデータが静かに壊れちゃうとか。 最も標準的で、まあ安全な動作は、データが壊れるのを防ぐことです。 専門的にはレストリクト、つまり制限と呼ばれていて。レストリクト。 ええ。子である社員が一人でもその部署に紐付いている限り、親である部署のデータは削除できないようにがっちりとブロックします。 あ、ブロックしてくれるんだ。そうです。削除を実行できません。この部署にはまだ所属社員がいますというエラーが返ってくるわけです。 なるほど。でもそれって管理者からすると少し面倒じゃないですか?とにかくこの部署を消したいのにシステムに止められたみたいな。 ええええ。なぜもっと柔軟に対応できないんでしょう。ええ、まさにそこがデータベース設計における 利便性とデータの整合性の、まあトレードオフなんです。データベースはデフォルトでは何よりも整合性を優先します。ほうほう。 このエラーは単にダメですと言っているだけじゃなくて、先に所属社員を全員別の部署に移動させるか、 退職処理を完了させてくださいと。この部署を空っぽにしてからもう一度削除しに来てくださいねと、 データベースが私たちに正しい手順を促してくれていると解釈できるんです。なるほど。 意図しないデータの孤立化という最悪の事態を防ぐための、まあ親切心とも言えますね。 親のデータを消す前に、まずこの面倒をちゃんと見なさいよと。そういうことですね。はい、その通りです。 非常に理にかなっています。でも資料にはもう一つ、もっと強力で少し過激に聞こえる選択肢も書かれていました。 カスケード、カスケードというものです。ええ。滝のように連鎖するという意味の言葉ですけど、これはどういう動きなんですか? カスケードはですね、その名の通り、連鎖的な動きを定義する設定なんです。連鎖的な。 はい。具体的には親を削除すると、それに関連する子が自動的に全て削除されるという非常に強力なものです。え? 自動的に?そうなんです。先ほどの例で言うと、もしこの設定が有効になっていれば、 営業部を部署名簿から削除する操作一つで、営業部に所属していた全社員のデータも、同時に社員名簿から削除されてしまいます。 それはすごくパワフルですけど、正直に言ってかなり怖いですね。ですよね。 ボタン一つで関連するデータがごっそり消えてしまうわけですから。もしそれが何百人、何千人という社員データだったらと思うとゾッとします。 おっしゃる通り、これは諸刃の剣です。だから資料にも取り扱い注意と明記されているんですね。 このレストリクトとカスケードの選択は、単なる技術的な設定の違いではないんです。 その裏にあるビジネス上の判断を反映するものなんですよ。ビジネス上の判断ですか。ええ。 例えばブログシステムを考えてみてください。あるブログ記事、これが親ですね。それが削除されたとき、 それに付随するコメント、つまり子は、単体で存在していても意味がないじゃないですか。 ああ、確かに。こういう場合はカスケード設定にして、記事と一緒にコメントも自動で消すのが理にかなっています。 一方で、先ほどの社員と部署の例ではどうでしょう。部署がなくなったからといって、社員の存在自体を消してしまうのは ビジネスロジックとして明らかにおかしいですよね。おかしいですね。はい。だからこういう場合はレストリクトが適切なんです。 なるほど。つまり設計者はこの子データは親がいなくなったら存在する価値がなくなるのか、 それとも独立した価値を持ち続けるのかを、こう自問自答しなきゃいけないってことですね。まさに。 その判断を誤ると大惨事を引き起こします。例えばある地域の営業所、親ですね、これを廃止したときに、 そこに紐づく顧客データ、子までカスケードで削除してしまったら、会社は計り知れない損害を被ります。 うわー。データベースのホラーストーリーの多くは、このカスケードの誤用から始まると言っても過言ではないかもしれません。 いや、深いです。単なる設定じゃなくてビジネスの哲学がそこにあるわけですね。よくわかりました。 ではこの知識を私たちはどう活用すればいいんでしょう。資料の最後には実務に役立つヒントが挙げられていました。 ええ。まずはこの少し複雑な関係性を他の人にわかりやすく伝えるための工夫についてです。 はい。これは特にエンジニアでない人にデータベースの構造を説明する際に非常に有効です。 言葉だけで部署が親で社員が子と説明しても、なかなかピンとこない。うーん、難しいです。 そこで資料が推奨しているように、図解を使うんです。参照する親テーブル、つまり部署と、参照する子テーブル、社員を、 それぞれ四角い箱で描いて、この外部キーから親の主キーに向かって一本の矢印を引きます。 ああ、それなら一目でわかりますね。ああ、この矢印の根本にあるデータは矢印の先にあるデータが 存在しないと存在できないんだなっていう依存関係が直感的に理解できます。ええ。 こういう図を、例えば社内のポータルサイトとか、仕様書の目立つところに載せておくだけで、チーム内の共通認識が格段に深まりますからね。 この矢印のルールを破るようなデータは作れませんよというメッセージにもなりますしね。その通りです。 そしてもう一つは、開発の現場でよくあるあるネタだと書かれています。これは共感する人が多そうですね。 ええ、これは多くのエンジニアが何度も経験することだと思います。私も告白しますが、いまだにやってしまいますよ。 ははは、そうなんですか。ええ。特に急いでテスト用のデータを作っているときです。 手作業でデータを投入していると、本来の順番を忘れがちになるんですね。つまり先に親である部署のデータを作るのを忘れて、 いきなり子である社員のデータを作ろうとしちゃうんです。あー、営業部に所属するテスト太郎さんというデータを入れたいのに、 肝心の営業部のデータがまだ存在しないという状況ですね。そうなんです。 すると当然ながらデータベースはこの参照整合性制約に引っかかって、そんな部署は存在しませんとエラーを返してきます。 怒られるわけですね。はい。その瞬間、ああ、またやっちゃったと思うわけですけど、 同時にこの門番がしっかりと仕事をしてくれていることの証拠でもあるんです。なるほど。 少しイラッとしつつも、どこか安心する瞬間ですね。このルールがなければ気づかないうちに矛盾したテストデータを 作り込んでしまって、後で原因不明のバグに悩まされることになっていたかもしれないわけですから。 つまり参照整合性制約というのは、単なる技術的な難しいルールなのではなくて、データベース全体の論理性を守り、 データの幽霊や孤児といった矛盾を防ぐための、非常に重要で頼もしい門番だということですね。 データとデータの間を関係性を常に正しく、健全に保つための根幹的な仕組みなんです。 ええ、その通りです。これがあるおかげでアプリケーションが、この社員は営業部に所属していると画面に表示するとき、 私たちはその裏側で営業部というデータが本当に部署名簿に存在することを100%信頼できるんです。 うん。データの品質と信頼性を根底から支える重要な規律と言えます。これが内容データベースは、 見た目は立派でも中身はグラグラの砂上の楼閣みたいなものかもしれません。 それでは最後に、この話をさらに一歩進めて、あなたに考えてみてほしいテーマを投げかけたいと思います。 今回私たちが見てきたのは、一つの部署に多数の社員が所属するといういわゆる一対多の関係でした。 はい。ではこれが多対多の、より複雑な関係になったらどうでしょう。 例えば一人の学生が多数の授業を履修し、かつ一つの授業には多数の学生が参加する、といったケースです。 データベースはこのような網の目のなような複雑な関係性をどうやって矛盾なく管理するのでしょうか。 この参照整合性の考え方を応用して、ぜひ考えてみてください。

このコンテンツは Web society で視聴・学習できます。