0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初めてのDB設計【unique制約について】

Posted at

DB設計におけるunique制約

ポートフォリオ作成にあたって、各エンティティやカラムの抽出を行っていきました(DBMLへの書き起こし)。その中でunique制約について触れる事がありましたが、疑問に思うことがいくつかあったので本記事にまとめます。

そもそもunique制約とは?

unique制約は「DB上において、同じ値を複数行に含めない」という制約です。

例えば、ユーザー情報テーブルでのemailカラムは、重複防止のためにunique制約をつけることで、一意性をもたせることができます。

複合的・部分的unique制約

以下のような場合、unique制約はどうなるでしょうか。
・「my_set_id」に「A」テーブル、「B」テーブルそれぞれから「item_id」を追加する。(両方NULLはNG)
・1つのテーブルにおいて、追加するアイテムの重複のみ禁止する。

 
ただ単に各テーブルの「item_id」カラムに対してuniqueをつけると、全マイセットまたいで、Aのアイテム重複が禁止されてしまいます。
→「my_set_id」とAの「item_id」を組み合わせ、全体で一意性をもたせる複合unique制約で回避可能です。

UNIQUE(my_set_id, item_id)

 

また、NULLが含まれる場合、同じ値でも別行として許可されるPostgreSQLの仕様もあるみたいです。
つまり「A」「B」それぞれがNULLの場合を制約から除外しなければなりません。
複合unique制約に条件を足して、一部の行のみ制御対象とする方法を部分的unique制約といいます。

UNIQUE(my_set_id, item_id) WHERE item_id IS NOT NULL
UNIQUE(my_set_id, custom_item_id) WHERE custom_item_id IS NOT NULL

部分的uniqueはDBの依存性が強く、古いバージョンのMySQLなどは直接制約を使用することができないようです。

このように、カラムの重複性によって適切なunique制約を割り当てる必要があることがわかりました。

最後に

かなりコンパクトになってしまいましたが、基礎的な部分をまとめてみました。他にも大規模開発向けの「部分的unique index」なるものがあるようですが、これはまた別の記事でまとめようと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?