2011-01-08 3 views
3

何百万もの行があり、フィールドユーザー名(varchar)があるユーザーテーブルがあります。一意のインデックスではなくプライマリキーにする必要がありますか?余分なフィールドuser_id(int)を追加してプライマリキーにする利点と欠点は何ですか?私は、どこで私がuser_idを使用するのか分からないのですが、intの結合がvarcharの結合より速いという結合条件について言う以外は?またはそれですか?(両方のフィールドがインデックスに登録されているため)データベースプライマリキー

update:変更するユーザー名はオプションではありません。

+1

ユーザは自分のユーザ名を変更できますか? VARCHARはどのくらいの期間ですか? INTEGERに基づくルックアップは、後者がより長いキー長を持つ場合、VARCHARのルックアップより高速です。 – Rob

+0

いいえ私はそれらのユーザー名を変更しないようにします – user157195

+1

あなたは絶対に、それは決して必要となることはないと確信していますか?私は未来を予測することができたらいいと思っています... – Rob

答えて

3

まず第二に、フレデリクのコメントです。私は、ビジネスや機能の価値をテーブルの主キーに帰さないことを確信しています。今ユーザ名を変更するオプションはないかもしれませんが、おそらく後になります。そうでない場合でも、パラダイムを混ぜるのではなく、習慣に慣れて、すべてのテーブルと一致する方が良いです。

主キーを何らかの方法で使用する主な理由は、挿入と更新の速度です。これは変更できますが、デフォルトでは、表の主キーもクラスタード・インデックスになります。クラスタード・インデックスはテーブル内の行の物理的な順序を決定するため、値を順不同で挿入すると、データベース・エンジンはその行をすべて削除して適切な位置に挿入できるようにします。何百万行ものテーブルを持つテーブルでは、簡単な挿入操作や更新操作が可能です。

+0

私はビジネス関連の主キーを使う理由を打ち明けたと思います。バッチの更新とインポートを有効にする。例えば。惑星のデータベース。外に出てデータを取得し、一時データベースに行を作成する非同期クラウドベースのアプリケーションがあるとします。次に、これらはインポートを介して本番データベースとマージされます。新しい惑星のメタデータテーブルのレコードは、惑星の名前(例えば)にキーイングされていれば簡単にインポートすることができます。しかし、それらがplanet_idにキーイングされていれば、それはうまくいかず、データベース間で同じではありません。さらに、惑星の名前のようなものはほとんど変わらないでしょう。思考? – Dogweather

+0

@Dogweather:価値のあることについては、代理キーに関する私の見解が変わった。データが独自のもの、必要なもの、安定したものを定義している場合は、確かに有効なキーです。 –

2

私が数字のPKを好むのは、私が簡単にユーザー名を変更できるようにするためです。

ユーザ名がプライマリキーでもある場合、ユーザ名の変更時にそのユーザに関連するすべてのレコードも変更する必要があることを意味します。

データベースでは、数値PKの正しいIDをいくつかの方法で生成できます。 MySQLではフィールドに「auto_increment」属性を追加し、PostgresとOracleではシーケンスを使用します。

もし何百万もの行があるなら、あなたはあなたのユーザ名を使う方が良いかもしれないということは間違いありません。私は、テーブル間に浮動小数点型の浮動小数点型(浮動小数点型)を持つことを避けようとしています。絶対に必要でない限り、コードに従っている人のためにすべてを維持するのが難しくなります。

+0

ユーザー名を変更することができない場合は、追加の数値pkを使用する理由はありませんか? – user157195

+0

@ user157195:あなたの懸念を念頭において私の答えを更新しました。ここでは厳しくて速いルールはなく、数字のPKを使用することに決して束縛されません。後で変更したい場合は、どれくらい仕事をしなければならないかという問題です。 –

3

プライマリキーとして追加フィールドを追加することをお勧めします。

主な理由は、-imho-プライマリキーに「ビジネス」値を設定しないことです。主キーは単なる管理項目であり、データベースにとって重要であるため、整合性を保証することができます。
ブライアンが既に言及しているように、サロゲート主キーを追加することで、ユーザーが問題なくユーザー名を変更できるようにすることができます。

プライマリキーの値は決して変更しないでください。そうしないと、多数の外部キーがある場合、更新が非常に高価になる可能性があります。これらの変更はすべて、関連するテーブルにカスケードする必要があります。

次に、整数はたとえば4バイトですが、usename列ははるかに大きくなります。
これは、関連するテーブルでもっと多くのスペースを占有するだけでなく、インデックスが大きくなることを意味します。
インデックスを構成するバケットには「レコードポインタ」が少なくなります。つまり、バケットを増やすとインデックスが遅くなります。

+0

+1「ビジネス」価値に関するコメント、およびインデックスサイズへの洞察 – Rob

+0

はい、Frederikのコメントに+1を追加しました。私は、ほとんどの数値int列は現在8バイトにデフォルト設定されていると考えていますが、レクソグラフィッククラスタリングがないため、ユーザー名が8文字に制限されていてもより均一で効率的なbツリーインデックスが作成されます。 –