5

個人を表すテーブル (クライアント、ユーザー、顧客、従業員など) の主キーとして何を選択しますか? 私の最初の選択肢は、社会保障番号 (SSN) です。ただし、プライバシーの問題やさまざまな規制のため、SSN の使用は推奨されていません。SSN は生涯を通じて変更される可能性があるため、これも使用しない理由の 1 つです。

よく選ばれた自然主キーの機能の 1 つは、重複を避けることだと思います。個人がデータベースに 2 回登録されることは望ましくありません。一部の代理キーまたは生成された主キーは、エントリの重複を回避するのに役立ちません。これにアプローチする最良の方法は何ですか?

個人エンティティのアプリケーションで一意性を保証する最善の方法は何ですか?これは主キーまたは一意性制約を使用してデータベース レベルで処理できますか?

4

8 に答える 8

7

I don't know which Database engine you are using, but (at least with MySQL -- see 7.4.1. Make Your Data as Small as Possible), using an integer, the shortest possible, is generally considered best for performances and memory requirements.

I would use an integer, auto_increment, for that primary key.
The idea being :

  • If the PK is short, it helps identifying each row (it's faster and easier to compare two integers than two long strings)
  • If a column used in foreign keys is short, it'll require less memory for foreign keys, as the value of that column is likely to be stored in several places.

And, then, set a UNIQUE index on an other column -- the one that determines unicity -- if that's possible and/or necessary.


Edit: Here are a couple of other questions/answers that might interest you :

于 2009-12-24T12:44:02.873 に答える
3

どのような属性を利用できますか?あなたのアプリケーションはどれを気にしますか?たとえば、まったく同じ場所でまったく同じ秒に2人が生まれることはできませんが、おそらくそのレベルの精度でそのデータにアクセスすることはできません。したがって、モデリングする属性から、許容可能なレベルのデータ整合性を提供するのに十分な属性を決定する必要があります。どちらを選択しても、選択したデータの整合性の側面(同じ人物に複数の行が挿入されないようにする)に焦点を当てることができます。

他のテーブルの結合/外部キーの場合は、代理キーを使用するのが最適です。

私は、主キーという単語の使用を誤称、またはせいぜい混乱させるものと見なすようになりました。主キー代替キー一意キー、または一意インデックスとしてフラグを立てているかどうかに関係なく、すべてのキーは引き続きキーであり、テーブルのすべての行にキーの属性の一意の値が含まれている必要があります。その意味で、すべてのキーは同等です。さらに重要なのは(最も)、それらが自然キー(意味のある実ドメインモデルのデータ属性に依存)であるか、代理(実データ属性の独立)であるかです。

次に、キーの使用目的も重要です。代理キーは狭くて単純で、変更されることはありません(理由はありません-何も意味しません)。したがって、結合または他の依存関係の外部キーに適しています。テーブル。

しかし、データの整合性を確保し、同じドメインエンティティに複数の行が挿入されるのを防ぐために、それらはまったく役に立ちません...そのためには、利用可能なデータから選択され、アプリケーションがモデリングしているある種の自然キーが必要です。いくつかの目的。

キーは100%不変である必要はありません。(例として)名前と電話番号と生年月日を使用する場合、たとえば、人が名前や電話番号を変更した場合でも、テーブルの値を変更するだけで済みます。キー属性に新しい値が含まれている行が他の行にない限り、問題はありません。

選択したキーが99.9%のケースでしか機能しない場合でも(同じ名前と電話番号の2人に遭遇し、偶然に同じ日に生まれたとしましょう)、少なくとも99.9%のケースでデータは正確で一貫性があることが保証されます。たとえば、誕生日に時間を追加して一意にするか、キーに他の属性を追加して区別することができます。変更のためにデータベース全体で外部キーのデータ値を更新する必要がない限り(他の場所でこのキーをFKとして使用していないため)、重大な問題に直面することはありません。

于 2009-12-24T15:28:50.700 に答える
3

前述のように、主キーとして自動インクリメントを使用します。しかし、これがあなたの本当の質問だとは思いません。

あなたの本当の質問は、エントリの重複を避ける方法です。理論的には、2 人が同じ日に生まれ、同じ名前で、同じ世帯に住んでいて、どちらかが社会保険番号を持っていない可能性があります。(その国を訪れる外国人かもしれません)。

ただし、氏名、生年月日、住所、および電話番号の組み合わせは、通常、重複を避けるために十分です。住所の入力方法が異なる場合や、複数の電話番号を持っている場合、ミドルネームを省略したりイニシャルを使用したりする場合があることに注意してください。エントリの重複を避けることの重要性と、ユーザーベースの規模 (および衝突の可能性) によって異なります。

もちろん、SSN/SIN を取得できる場合は、それを使用して一意性を判断します。

于 2009-12-24T12:57:05.327 に答える
1

自動生成された整数の主キーを使用し、一意である必要があると思われるものに一意の制約を設定します。ただし、SSN は現実の世界では一意ではないため、データベースが顧客を受け入れないという理由で顧客を断ることが良いビジネス モデルであると考えない限り、この列に一意性制約を設定することはお勧めできません。

于 2009-12-24T12:45:20.110 に答える
1

私は自然キーを好みますが、テーブルpersonはロスト ケースです。SSN は一意ではなく、誰もが持っているわけではありません。

于 2009-12-24T12:53:20.487 に答える
1

代理キーをお勧めします。他の候補キーに必要なすべてのインデックスを追加しますが、ビジネス ロジックをキーから除外することをお勧めします。

于 2009-12-24T13:22:34.230 に答える
1

信頼できる場合は、自然キーを好みます。

銀行などを経営している場合を除き、クライアントやユーザーが有効な SSN を提供する必要はありません。したがって、ビジネス上の理由から、概要を説明した場合、SSN を信頼しないことを余儀なくされます。同様の主張は、「人」への任意の自然キーにも当てはまります。

人為的な (「代理」と読む) キーを割り当てるしかありません。整数でも構いません。すぐに拡張する必要がないように、十分な大きさの整数であることを確認してください。

于 2009-12-25T09:52:01.030 に答える
0

@Mark および @Pascal に追加するには (自動インクリメント整数が最善の策です) - SSN は便利であり、正しくモデル化する必要があります。セキュリティの問題は、アプリケーション ロジックの一部です。それらを別のテーブルに正規化することができ、発行日フィールドを提供することでそれらを一意にすることができます。

ps、「アプリケーションのセキュリティ」の点に同意しない人のために、エンタープライズ DB には詳細な ACL モデルがあります。したがって、これは問題になることはありません。

于 2009-12-24T12:51:44.920 に答える