2015年11月19日木曜日

DB設計 PKは複合キーかサロゲートキーか?自分なりの判断基準。

PKを複合キーにするか、サロゲートキーにするか。
今後迷った時のために、現時点での自分なりの判断基準を残しておこう。

複合キーを許可するのは以下を全てのいずれかを満たす場合のみ。
1. PKが(将来的にも)変更されないこと。
2. 最終テーブルであること。
3. トランケートされるテーブルであること。 // 2016/01/29追加

根拠
1. PKが(将来的にも)変更されないこと。
F/Wが推奨していない場合もある。
規約としてPKの変更は不可としているプロジェクトがある。
その場合、更新処理なのにdelete/insert処理することになる。
関連する全テーブルの更新も発生する。

(将来的にも)と書いたのは、開発時点では変更されない予定だが、バージョンアップにより変更される可能性を考える必要があるから。

例えばグループ内の項目を一覧表示する場合で、テーブルにグループIDと項目表示順を持っている。
開発時点で「表示順の変更はないと聞いていたから、PKをグループIDと表示順にしました。」
みたいな。
バージョンアッップで「やっぱり表示順変更したいよね。」となったら辛い。

この場合はPKをグループIDと項目ID(ただの連番)とし、表示順はただの項目にすることで防げる。
将来を見据えて、PKの変更が発生しそうな所は事前に潰すこと。


2. 最終テーブルであること。
PKを他のテーブルで参照している場合、テーブルの項目が増えるので。
1テーブルのPKだけならまだいいけれど、大抵は複数テーブルへのキーを持っているし。
結合キーが増えるだけ間違いは起きやすい。

PKでの他テーブルへの結合がない、ぼぼ単独で存在するテーブルならOK。
例えば帳票出力のためのワークテーブルとかかな。

3. トランケート後にデータを再投入する際、サロゲートキーが振りなおされるため。
自然キーに対するPKが変更されてしまう。

ex)
事前データ
サロゲートキー, 親キー, 子キー, 名称
1, A, a, 名称A-a
2, B, b, 名称B-b

トランケート後にデータ再投入
サロゲートキー, 親キー, 子キー, 名称
1, A, a, 名称A-a
2, A, b, 名称A-b
3, B, b, 名称B-b

サロゲートキー=2のデータが変わってしまうため、関連するテーブルに影響がでる。

0 件のコメント:

コメントを投稿