2

ライセンスの使用状況を記録するテーブルがあります。各ライセンスの使用状況は、ユーザーとホスト マシンに関連付ける必要があります。テーブル定義は次のようになります。

create table if not exists  per_user_fact
(
    per_user_fact_id        int unsigned        not null    auto_increment,
    time_of_day             char(16)            not null,
    license_served_id       smallint unsigned   not null,
    license_hours           numeric(10,2)       not null,
    role_name               varchar(64)         null,
    user                    varchar(128)        not null,
    host                    varchar(128)        not null,
    primary key (per_user_fact_id),
    foreign key (license_served_id) references served_license(served_license_id),
    foreign key (user, host) references user_host(username, hostname)
);

このテーブルを正規化して、反復的なユーザー/ホストの値がこのような新しいテーブルに移動されるようにします。

create table if not exists  user_host
(
    username                varchar(64)         not null,
    hostname                varchar(128)        not null,
    primary key (username, hostname)
);

user_hostテーブルの場合、自然または代理のどの種類の主キーを選択する必要がありますか? 以下の支配要因が考えられます。

  1. 主キーが自然な場合、つまりユーザー名とホスト名の合成である場合、親テーブルper_user_factは、ユーザー名とホスト名を見つけるために追加の結合を必要としません。
  2. 主キーが自然な場合、ユーザー名とホスト名の値が両方のテーブルで重複するため、ストレージが無駄になります。
  3. 主キーがサロゲートの場合、親テーブルがユーザー名とホスト名の値を取得するには、追加の結合が必要になります。
  4. 主キーがサロゲートの場合、user_host テーブルのインデックス作成は高速になります。

お知らせ下さい。

4

3 に答える 3

6

この場合でも、私は代理主キーを使用するのが大好きです。クラスター化された主キーに参加している場合、追加の参加のコストはごくわずかです。

さらに、usernamehostnameが (合わせて) 4 文字程度より長いと仮定すると、代理キーによってスペースが節約されます。実際、代理キーを使用すると、データが小さくなるため、クエリが高速になることがあります。per_user_factテーブルが小さいほど占有するデータ ページが少なくなるため、I/O が少なくなります。

代理キーのもう 1 つの利点は、他のテーブルを変更せずにユーザー名とホスト名を変更できることです。結合にデータ フィールドを使用している場合、値を変更するには、複数のテーブルを更新する必要があります。これは、より面倒な操作です。

また、サロゲート ID/シリアル/自動インクリメント キーも好きです。これらのキーは、テーブルへの挿入順序もキャプチャするからです。もちろん、他の方法もあります (私のテーブルには通常、CreatedAtデフォルトで挿入時間の列があります)。ただし、代理キーもその役割を果たすことができます。

これらの理由は、質問に対する「正しい」答えを構成するものではありません。サロゲートを使用しない正当な理由があります。ただし、私にとっては、ほとんどすべてのテーブルにそのような主キーがあります。

于 2015-12-19T15:41:32.753 に答える