MW211 EXIT

devlog
データベース/削除済みフラグと一意性制約
2014年10月20日
削除レコードを直接DELETEしたくない場合には、削除済みフラグなんかを設ける。
この時問題となるのが、自然キーの一意性制約を邪魔することだ。

例えば、会員№が自然キーでそれが「1」のレコードを削除した場合、
居座ってしまうので、再び会員№「1」のレコードを追加することはできない。

それじゃ、自然キーと削除済みフラグをまとめて一意性制約にするとする。
この場合、二回目以降の削除をすると、削除レコードが重複するので、
削除ができなくなる。

ということで、削除レコードは制約のない履歴テーブルへ移して…と考える訳だが
それをしなくても解決する方法がある。

(1) 部分インデックス(MSSQLやPostgreSQLの場合)
  条件に該当する中で一意性制約をつけるということができる。
  MSSQLではこんな感じ。
┌──────────────────────────────────────┐
│CREATE UNIQUE NONCLUSTERED INDEX [一意性制約]                               │
│    ON [dbo].[表] (                                                         │
│        [自然キー]          ASC                                             │
│    )                                                                       │
│    WHERE ([削除済フラグ] = 0);                                             │
└──────────────────────────────────────┘
  削除レコード(削除済フラグ=1)については、一意性制約が効かないので
  ちょうど、別履歴テーブルに移動したのと同じような感じになる。

(2) 一意性制約中のNULL特性(MySQLやOracleの場合)
  複合キーにNULLが混じっていると、一意性制約の範疇外となる特性を利用する。
  つまり制約を「自然キー+削除済みフラグ」にして、
  削除済みの場合は「TRUE」ではなく「NULL」としてしまうのだ。
  「自然キー+NULL」となれば一意性制約が効かないので、
  「自然キー」の部分が重複していてもいけてしまうというわけだ。
分類:SQL