web-dev-qa-db-ja.com

「varchar」を主キーとして使用しますか?悪いアイデア?または大丈夫?

「varchar」を主キーとして使用するのは本当に悪いことですか?

(ユーザードキュメントを保存します。はい、20億以上のドキュメントを保存できます)

15
001

それは完全にデータに依存します。 VARCHAR主キーを使用する可能性のある完全に正当なケースはたくさんありますが、誰かが将来のある時点で問題の列を更新したいと思う可能性が最も低い場合でも、使用しないでくださいキーとしてそれ。

17
ninesided

他のテーブルに結合する場合、varchar、特に幅の広いvarcharはintよりも遅くなる可能性があります。

さらに、子レコードが多数あり、varcharが変更される可能性がある場合、カスケード更新により、すべてのユーザーがブロックされ、遅延が発生する可能性があります。車のVIN番号のようなvarcharは、変更されることはめったにありません。名前が変わるようなvarcharは、起こるのを待っている悪夢になる可能性があります。 PKは、可能な限り安定している必要があります。

次に、考えられる多くのvarchar Pksは実際には一意ではなく、一意であるように見えることもありますが(電話番号など)、再利用でき(番号を放棄し、電話会社が再割り当てします)、子レコードが間違った場所に添付される可能性があります。したがって、使用する前に、本当に一意の不変の値があることを確認してください。

代理キーを使用することにした場合は、varcharフィールドに一意のインデックスを作成してください。これにより、結合が高速になり、何かが変更された場合に更新するレコードが少なくなるという利点が得られますが、必要な一意性は維持されます。

子テーブルがなく、おそらくそうなることはない場合、これのほとんどは意味がなく、整数pkを追加することは時間とスペースの無駄です。

7
HLGEM

ここでのパーティーには少し遅れていることに気づきましたが、以前の回答について少し詳しく説明しておくと役に立ちます。

VARCHAR()を主キーとして使用することは常に悪いことではありませんが、ほとんど常にです。これまでのところ、より適切な固定サイズの主キーフィールドを思い付くことができなかった時期はありませんでした。

VARCHARは、整数(INT)または短い固定長char(CHAR)フィールドよりも多くの処理を必要とします。

データベースエンジンは、各レコードのこのフィールドに格納されているデータの「実際の」長さを示す追加のバイトを格納することに加えて、各レコードの前のフィールドの開始バイトと終了バイトの位置(メモリ内)を計算するために追加の作業を行う必要があります。読んだ。

外部キーも、参照される親テーブルの主キーと同じデータ型を使用する必要があるため、出力のためにテーブルを結合するときにさらに複合を処理します。

データ量が少ない場合、この追加の処理は目立たない可能性がありますが、データベースが大きくなるにつれて、劣化が見られるようになります。

キーとしてGUIDを使用しているため、列の長さが固定されていることが事前にわかっています。これは、固定長のCHAR(36)フィールドを使用するのに適したタイミングです。これにより、処理のオーバーヘッドがはるかに少なくなります。

2
James Marks

多くの場合、intまたはbigintの方が優れていると思います。

  1. intは、より少ないCPU命令と比較できます(クエリに参加...)
  2. intシーケンスは、デフォルトで順序付けられます->バランスの取れたインデックスツリー->クラスター化インデックスとしてPKを使用する場合、再編成はありません
  3. インデックスに必要なスペースは潜在的に少なくなります
1
edze

IDを使用します(50個だけを表示したい場合などに便利です...)。ファイル名を使用してvarcharに制約UNIQUEを設定するよりも(私はそれがあなたが保存しているものだと思います)。

これはトリックを行い、速度を上げます。

0
JNDPNT