ケース 1: UserName フィールドを主キー (PK) として使用しないのはなぜですか? [自動的に増加する] 別のフィールドの like ID を PK として使用するのはなぜですか?
はこのUserTable.UserName
データ モデルに固有の意味を持ち、「自然キー」と呼ばれます。一方UserTable.id
、 は「代理キー」です。
モデルに自然キーがある場合、代理キーでそれを削除することはできません。単に置き換えることができます。問題は、自然キーだけを使用するのか、それとも自然キーと代理キーを使用するのかということです。どちらの戦略も実際には有効であり、長所と短所があります。
代理キーの一般的な理由:
- 子テーブルのFK をスリムに保ち(この場合は整数と文字列)、ストレージを小さくしてキャッシュを改善します。
- ON UPDATE CASCADE の必要性を回避します。
- ORM ツールに対する親しみやすさ。
一方で:
- キーが 1 つではなく 2 つになり、追加のインデックスが必要になり、親テーブルが大きくなり、キャッシュに適していなくなり、インデックスのメンテナンスのために INSERT/UPDATE//DELETE が遅くなります。1
- より多くの JOIN-ing 2が必要になる場合があります。
- また、クラスタリングではうまくいかない場合があります。3
UserName と Email だけの場合、Email を PK として使用しないのはなぜですか?
設計者はおそらく、ユーザーが電子メールを変更した場合に必要になる ON CASCADE UPDATE を避けたかったのでしょう。
ケース 2: UserRoleTable で、UserName と RoleID の両方を PK として使用しないのはなぜですか?
同じユーザー/ロールのペアに対して複数の接続が存在できない場合は、いずれにしてもそのキーが必要です。
FK を参照している子テーブルがないUserTableRole
か、不適切な ORM が使用されていない限り、追加の代理 PK を使用する理由はありません。
1また、クラスタリングが使用されている場合、自然キーの下のセカンダリ インデックスは余分な「太い」ものになる可能性があり (通常は PK であるクラスタリング キーのコピーが含まれているため)、クエリを実行するときにダブル ルックアップが必要になる場合があります (クラスター化されたテーブルの行安定した物理的な場所がないため、Oracle の「ROWID 推測」などの DBMS 固有の最適化を除いて、クラスタリング キーを介して配置する必要があります)。
2UserName
たとえば、ジャンクション テーブルを読み取るだけでは見つけることができませんUserTable
。
3サロゲートは通常、クライアント アプリケーションにとって意味のない順序で並べられます。自動インクリメント代理キーの順序は INSERT の順序に依存し、クエリは通常、「挿入順序によるユーザーの範囲」では行われません。GUID などの一部のサロゲートは、ランダムに並べられることが少なくなる場合があります。