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設計】PrimaryKey設定時のアンチパターン

Posted at

公共系の案件でDB定義書を見る機会があり、「本当にこれでいいのか?」と思って調べていたらアンチパターンだった例がいくつかありました。
今回は主キーに関するアンチパターンで、web開発でも使えそうなものを調べたのでまとめたいと思います。

ユーザーからの入力値を主キーにしている

問題点

  1. 入力ミスなどにより、一意性が崩れる可能性がある(主キーとして機能しないので論外)

改善案

  1. サロゲートキーを主キーにする

ナチュラルキーを主キーにしている

問題点

  1. 入力値であることが多いため、意図せず変更される可能性がある(今回は入力値でした)
  2. 仕様変更によりキーの体系自体が変わる可能性がある
  3. 業務的な通し番号(注文番号など)でもNG

UUIDや長大な文字列を主キーにする

  1. MySQLでは文字列のインデックスは数値より重く、パフォーマンス低下につながる
  2. UUIDはソート順がランダムになるので、INSERT字にページ分割が頻発する

改善案

  1. 数値型のAUTO_INCREMENTやバイナリ形式UUID(BYNARY(16))を使用する。

  2. サロゲートキーを主キーとする

サロゲートキーとは:業務知識とは直接関係のない、システム側が自動で決定するキー

複合主キー(ケースバイケース)

問題とならない場合

  1. 業務的に自然なキーの組み合わせで一意となる場合(テーブル定義変更の可能性や参照先が少ない場合に限る)
  2. 多対多の中間テーブル(student_id, course_idのstudent_courseテーブルだと、自然に「同じ学生が同じ講義を2回登録できない」という制約となり、IDの裁判が不要でシンプル)

問題となる場合

  1. 将来的に主キーの構成が変わる可能性がある場合(全参照テーブルで修正が必要になる)
  2. 複数のテーブルで参照される可能性が高い場合(外部キーで参照する側も復号キーを持たなければならず、JOINやSQL設計が煩雑になる)
  3. 開発でORMを利用する場合(LaravelのEloquentなど、ORMは単一カラムPKを前提としていることが多い)

理論的に複数キーの組み合わせで一意になるからと言って、複合主キーを使うべきとは限らないのがポイント。

まとめ

  1. 主キーは「変わらない」「短い」「機械的に一意」が理想。
  2. ORM使用+MySQLの現場では、「主キーはサロゲートキー(id)」+「業務上のユニーク条件は別途UNIQUE制約」で分離するのが実務的に安全。
  3. 自然キーやUUIDを使う場合は、ドメイン情報や機能要件の変更・パフォーマンスまで見通したうえで慎重に。
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?