1

次のようなデータベース設計をよく見かけます。

ケース 1:

ユーザーテーブル

--id[自動増加]

-- ユーザー名

- パスワード

- Eメール

ケース 2:

ユーザーテーブル

-- ユーザー名

- パスワード

- Eメール

役割テーブル:

-- 役割 ID

-- 役割名

ユーザー テーブル ロール:

--id[自動増加]

-- ユーザー名

-- 役割 ID

次のような質問があります。

ケース 1: UserNameフィールドを主キー ( PK )として使用しないのはなぜですか? [自動的に増加する] 別のフィールドの like IDを PK として使用するのはなぜですか? UserNameEmailだけの場合、 Email をPKとして使用しないのはなぜですか? それで、最善のアプローチは何ですか?

ケース 2: UserRoleTable で、UserNameRoleIDの両方を PK として使用しないのはなぜですか? [自動的に増加する]別のフィールドの like idをPKとして使用するのはなぜですか? では、この場合の最善のアプローチは何ですか?

4

4 に答える 4

4

ケース 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 などの一部のサロゲートは、ランダムに並べられることが少なくなる場合があります。

于 2012-12-20T03:28:11.070 に答える
0

あなたの質問は、本質的に自然対代理キーを使用することの長所と短所です。

柔軟性が主な関心事です。代理キーを使用すると、ユーザー名をより簡単に変更できます。また、将来的には、合併などでユーザー名の重複を許可する必要が生じる可能性があります。

ユーザー テーブルのような頻繁にアクセスされるテーブルでは、通常、文字列よりも整数を結合する方が高速です。

もう 1 つはテーブル サイズです。外部キーとして使用する場合、キーの値全体を格納する必要があります。サロゲートは非常にコンパクトで、自然キーよりもはるかに小さいです。

ほとんどの ORM では、テーブル間の一貫性を提供するため、サロゲートの使用も必要です。

また、多くのシステムでは、電子メールが一意であると想定することが必ずしも安全であるとは限りません。

UserRole のような関係テーブルでは、通常、外部キーからプライマリ複合キーを使用するのが最善であることに同意します。

于 2012-12-20T02:45:13.040 に答える
0

ユーザー名に代理主キー (Id) を使用する例で考えられる理由がいくつかあります。

  1. id フィールドが更新されることはほとんどありません。ユーザー名が主キーである場合、更新時にユーザー名が外部キーとして使用されたすべてのテーブルにカスケードする必要があります。
  2. パフォーマンス。int 比較は string 比較よりも優れています。
  3. id キーは、それが他のテーブルの外部キーであった場合、より少ないストレージ スペースを占有します。
  4. id フィールドを使用すると、おそらく機密データを公開しないようにすることができます。たとえば、Web アプリの URL domain/posts/user/1242 と domain/posts/user/myusername を検討してください。

2 番目の質問については、UserTableRole のユーザー名よりもユーザー ID を使用することをお勧めします。この多対多テーブルに代理キーを含める方がよいかどうかは、意見の問題です。私は多対多のテーブルにサロゲート ID キーを使用するのが嫌いで、通常は 2 つの外部キー ID の複合主キーを作成するだけです。ここで代理キーを検討するのは、それをさらに別のテーブルで外部キーとして使用する必要がある場合だけです。

于 2012-12-20T02:56:59.227 に答える
0

UserName などを主キーとして使用しない理由の 1 つは、それらが変更される可能性があることです。主キーとして外部に公開されているものを使用すると、それらが変更されるリスクが発生するため、安定した主キーを使用することをお勧めします。

ユーザーが電子メールまたはユーザー名を変更した場合はどうなりますか。すべての関係のキーを本当に変更しますか? IMO、誰もが何も知らない外界を見ない安定したキーを持つことが最善です。したがって、データベースでどのような変更が発生しても安定した状態を保つことができます。

于 2012-12-20T02:22:46.980 に答える