SQL Server で Nullable列にユニーク制約を付けるときは要注意

 

SQL Server で NULL に対する INDEX は一定の値として認識される仕様です。

引用 from MSDN

NULL 値の処理


インデックスの作成という目的では、NULL 値は同じ値と見なされます。したがって、複数行のキー値が NULL である場合は、一意インデックスまたは UNIQUE 制約を作成できません。一意インデックスまたは一意制約の列を選択する場合は、NOT NULL と定義された列を選択します。

つまり、Unique制約を付けた列の複数行にNULLを持たせることはできないということです。なんかおかしいと思いますが、そう言う仕様のようです。

回避策は下記の方法で。

引用 from microsoftサポート

使用できる解決策の一覧

ANSI UNIQUE 制約を作成するために使用できる解決策は 3 つあります。データベース システムはそれぞれ構成が異なるため、どの解決策がユーザーの環境に最適であるかを評価する必要があります。以下に 3 つの解決策を示します。

  • null を許可するテーブルを作成し、null を除外する WITH SCHEMABINDING 句を使用してビューを作成します。その後、そのビューの一意のインデックスを作成します。
  • null を許可する列に基づいた計算される列を作成し、計算される列に UNIQUE 制約を定義します。
  • EXISTS 演算子を使用するトリガを作成し、null 以外の値が既に列に存在するかどうかを判断します。

まぁ、Null撲滅しておけばこんな事を考える必要はないです。

2 Replies to “SQL Server で Nullable列にユニーク制約を付けるときは要注意”

  1. Nullを撲滅する=存在自体を否定する事だと思います。

    全ての要素には「存在する」という事実がある限り、その逆である「存在しない」という事実もまたついて回ります。
    システムとはそういう世界ではないですか。

    1. > 全ての要素には「存在する」という事実がある限り、
      > その逆である「存在しない」という事実もまたついて回ります。
      > システムとはそういう世界ではないですか。
      そうですね。仰るとおりです。
      ただ、NULLの意味は「不明な値」であって「存在しない」ではありません。つまり、「Nullを撲滅する≠存在を否定する」ということです。
      「存在しない」は、例えば文字列なら“”(空文字)が、数値なら0が概念的にはより適当でしょう。
      NULL撲滅の意味と方法論についてはリンク先が大変参考になりますので、ぜひご参照ください。

コメントを残す