5 ポイント 投稿者 GN⁺ 2024-06-06 | 2件のコメント | WhatsAppで共有
  • 自然(Natural)キーは、データベースで一意性を保証するために使われるキー
  • 自然キーは、名前、都市、年などの実データに基づいている
  • たとえば、世界最高のレストラン50店のデータベースでは、restaurantNamecityNameyear を自然キーとして使うことができる
  • しかし自然キーは、一意性を保証できない場合がある。たとえば、同じ名前のレストランが複数の都市に存在することがある

同一性

  • 自然キーは、一意性を保証するだけでなく、同一性も保証しなければならない
  • たとえば、自動車の車台番号や個人識別番号(CPR番号)を自然キーとして使うことができる
  • しかし、同じ人物が複数の識別番号を持つことがある。たとえば、デンマークでは性別移行をした人が新しい CPR 番号を受け取ることがある

書類上の誤り

  • 自然キーは、書類上の誤りに弱い
  • データ入力ミス、ユーザーのタイプミス、データ変換エラーなどが発生する可能性がある
  • システムはこうした誤りを修正できなければならない。したがって、外部キーをデータベースキーとして使うのは適切ではない

結論

  • データベース設計で自然キーを使うのは、よい考えではない
  • データエラーは起こり得るため、そうしたエラーを修正できなければならない
  • したがって、データベーステーブルでは常に人工キーを使うのがよい

GN⁺の意見

  • 自然キーの問題点: 自然キーは一意性と同一性を保証できない場合があり、データ入力ミスにも弱い。
  • 人工キーの利点: 人工キーは一意性と同一性を保証し、データエラーを容易に修正できる。
  • ORM 使用時の考慮点: ORM ライブラリを使う場合は、人工キーを使うほうが簡単。ORM はデータベース構造をある程度決定するため、人工キーを使うほうが効率的。
  • 類似機能の製品: 他のデータベース設計ツールや ORM ライブラリでも、人工キーの使用が推奨されている。たとえば、Hibernate、Entity Framework など。
  • 技術導入時の考慮点: 新しいデータベース設計を導入する際は、自然キーの欠点を考慮し、人工キーを使うのがよい。人工キーはデータの完全性を保証し、誤りを容易に修正できる。

2件のコメント

 
GN⁺ 2024-06-06
Hacker Newsの意見
  • 固有で短く、人が読みやすいID: Stripeで使われている cus_MJA953cFzEuO1z のようなIDが好まれている。JavaScript/TypeScriptで生成する方法もある。
  • 個人識別番号: デンマークのCPR番号と米国のSSNを比較。SSNは一意ではなく、変更される可能性があり、米国市民でなくても発行されうる。データベースキーとして使わないことが推奨される。
  • 別名と監査ログ: デンマークのCPR番号のような自然キーを使う場合、変更履歴を記録する別テーブルが必要になる。URLも自然キーとして使えるが、変更時にはリダイレクト用テーブルを作る必要がある。
  • 自然キーの限界: 一意識別子が変更されると、関連するすべての情報を追跡しなければならない。人為キーを追加すると、追跡すべき情報はさらに増える。データモデリングは現実世界を反映すべきだ。
  • 自然キーとプライバシー保護: 自然キーに個人情報が含まれていると、外部キーを通じて他のテーブルにも伝播しうる。
  • ゲームタグの例: PlayStation Networkのゲームタグを自然キーとして使う例。ゲームタグが変更されないなら、一意識別子として使用できる。
  • 医療分野の例: 登録担当者が誤った個人健康番号(PHN)を入力すると問題が発生する。人為キーを使えば後から訂正できる。
  • 自然キーの制御不能性: 名前、住所、公式登録番号などは制御できないため信頼できない。固有キーシステムを使うべきだ。
  • 人為キーの使用: すべてのテーブルに固有IDフィールドを使えば問題解決が容易になる。データと関係は頻繁に変わるため、自然キーは信頼しにくい。
  • 変更可能性と固有ID: 変更可能性があるなら、時間をまたいで共通する識別子が必要になる。データベースは明示的な代理キーをスキーマに含めるべきだ。
 
jsonobject 2024-06-07

人工キーも、グローバルリージョンなどに対応する分散環境への備えができている TSID を使うことをおすすめします。私は MySQL と DynamoDB で PK として TSID を使っています。

https://jsonobject.hashnode.dev/using-tsid-as-database-pk