web-dev-qa-db-ja.com

SQLデータベースの主キーとしての文字列

私は、データベースとそれらがどのように機能するかの背後にある理論にあまり詳しくありません。整数よりも主キーに文字列を使用することは、パフォーマンスの観点から(挿入/更新/クエリ)遅くなりますか?

159
mainstringargs

技術的には可能ですが、文字列が主キーとして理にかなっている場合は、おそらくそれを使用する必要があります。これはすべて、作成するテーブルのサイズと、主キーとなる文字列の長さに依存します(長い文字列==比較が難しくなります)。数百万行のテーブルに必ずしも文字列を使用するとは限りませんが、小さなテーブルで文字列を使用することで得られるパフォーマンスの低下は、整数を持つことで発生する可能性のある頭痛に非常に小さくなります。 「データに関連するものを意味するものではありません。

169
kemiller2002

文字列を主キーとして使用する場合の別の問題は、インデックスが常に順番に並べられるため、順序の途中にある新しいキーが作成されると、インデックスを再配列する必要があることです... autoを使用する場合整数の場合、新しいキーはインデックスの最後に追加されます。

66
Jeff Martin

シーケンスの途中で挿入が発生するクラスター化インデックスを持つテーブルへの挿入では、インデックスは書き換えられません。データを構成するページが書き換えられることはありません。ページに行が移動するスペースがある場合、そのページに配置されます。単一ページは、ページ内の適切な場所に行を配置するように再フォーマットされます。ページがいっぱいになると、ページ分割が発生し、ページの行の半分が1つのページに、残りの半分が他のページに移動します。その後、ページは、クラスター化インデックスを持つテーブルデータを構成するページのリンクリストに再リンクされます。せいぜい2ページのデータベースを書くことになります。

19
Mark Thompson

文字列は結合では遅くなり、実際には非常にまれにしか(実際にそうである場合でも)一意ではありません。唯一の利点は、名前を取得するためだけにプライマリテーブルに結合する場合、結合の数を減らすことができることです。ただし、文字列もしばしば変更される可能性があるため、会社名が変更されたり、人が結婚したときに関連するすべてのレコードを修正する必要があるという問題が発生します。これはパフォーマンスに大きな影響を与える可能性があり、何らかの形で関連する必要があるすべてのテーブルが関連していない場合(これは思っているよりも頻繁に発生します)、データの不一致も発生する可能性があります。レコードの存続期間を通じて決して変化しない整数は、データの整合性の観点およびパフォーマンスの観点からはるかに安全な選択です。通常、自然キーはデータのメンテナンスにはあまり適していません。

また、両方の長所は、多くの場合、PKとして自動インクリメントキー(または特殊なケースではGUID)を使用してから、自然キーに一意のインデックスを付けることです。より高速な結合を取得します;重複レコードを取得せず、会社名が変更されたために100万件の子レコードを更新する必要はありません。

12
HLGEM

一意である限り、主キーとして何を使用してもかまいません。データの複製を計画していない限り、速度や適切なデータベース設計が必要な場合はintを使用し、GUIDを使用します。

これがアクセスデータベースまたはいくつかの小さなアプリである場合、誰が本当に気にしますか。私たちのほとんどの開発者が古いintまたはguidを前面に平手打ちする理由は、プロジェクトが私たちを成長させる方法を持っているからであり、あなたは自分で成長するオプションを残したいのだと思います。

6
Al Katawazi

変数が多すぎます。テーブルのサイズ、インデックス、文字列キードメインの性質によって異なります...

一般的に、整数はより速くなります。しかし、その違いは気にするのに十分な大きさでしょうか?言うのが難しい。

また、文字列を選択する動機は何ですか?数値の自動インクリメントキーは、多くの場合easierにもなります。セマンティクスですか?便利ですか?複製/切断の懸念?ここであなたの答えはあなたのオプションを制限する可能性があります。これは、忘れている3番目の「ハイブリッド」オプションであるGuidsも思い浮かびます。

5
Joel Coehoorn

データが記述し、データの意図された用途にうまく適合するという主題に同意するシンプルで健全な設計を得るまで、パフォーマンスを心配しないでください。その後、パフォーマンスの問題が発生した場合、システムを微調整することで対処できます。

この場合、ほとんどの場合、文字列を自然な主キーとして使用することをお勧めします(信頼できる場合)。文字列が合理的に短い限り、文字列であるかどうか心配する必要はありません、最大約25文字と言います。パフォーマンスの面で大きな代価を払うことはありません。

データ入力担当者または自動データソースは、想定される自然キーの値を常に提供しますか、それとも省略されますか?入力データが時々間違っていますか?ある場合、エラーはどのように検出および修正されますか?

クエリを指定するプログラマーやインタラクティブユーザーは、自然なキーを使用して必要なものを取得できますか?

自然なキーを信頼できない場合は、代理を発明します。サロゲートを発明する場合、整数を発明することもできます。次に、ユーザーコミュニティからサロゲートを隠すかどうかを心配する必要があります。代理キーを隠さなかった一部の開発者は、後悔するようになりました。

4
Walter Mitty

インデックスは多くの比較を意味します。

通常、文字列は整数よりも長く、照合規則を比較に適用できるため、通常、文字列の比較は整数の比較よりも計算負荷の高いタスクです。

ただし、場合によっては、string to numerical idテーブルとの余分な結合を作成するよりも、文字列を主キーとして使用する方が速い場合があります。

2
Quassnoi

はい。ただし、数百万行あると予想される場合を除き、文字列ベースのキーを使用するのは遅いため、通常は「時期尚早な最適化」です。結局、文字列は大きな数字として保存されますが、数字キーは通常小さな数字として保存されます。

ただし、注意が必要なのは、任意のキーにインデックスをクラスター化し、インデックス内で非連続の挿入を多数実行している場合です。書き込まれたすべての行により、インデックスが再書き込みされます。バッチ挿入を実行している場合、これによりプロセスが本当に遅くなる可能性があります。

2

PK列に整数を使用する2つの理由:

  1. 自動的にインクリメントされる整数フィールドにアイデンティティを設定できます。

  2. PKを作成すると、dbはデータをテーブルに保存する前に並べ替えるインデックス(クラスターまたは非クラスター)を作成します。 PKでIDを使用すると、オプティマイザーはレコードを保存する前にソート順を確認する必要がありません。これにより、大きなテーブルのパフォーマンスが向上します。

2
Jatinder Singh

パフォーマンスの観点から-はいstring(PK)は、整数(PK)を使用して達成されるパフォーマンスと比較すると、パフォーマンスが低下します(PK --->主キー)。

要件の観点から-これはあなたの質問の一部ではありませんが、まだ言及したいと思います。異なるテーブル間で巨大なデータを処理する場合、特定のテーブルに設定できる可能性のあるキーのセットを通常探します。これは主に、多くのテーブルがあり、ほとんどの場合、各テーブルまたは一部のテーブルが何らかのリレーション(外部​​キーの概念)を介して他のテーブルに関連付けられるためです。したがって、整数を主キーとして常に選択できるとは限らず、そのテーブルの主キーとして3、4、または5個の属性の組み合わせを選択します。また、これらのキーは、レコードを他のテーブルに関連付けるときに外部キーとして使用できます。これにより、必要に応じて異なるテーブルにレコードを関連付けることができます。

したがって、最適な使用のために-必要な場合にのみ、1または2文字列属性を持つ1または2整数の組み合わせを常に作成します。

1
Arijit

主キーとして文字列を使用する理由は何ですか?

私は主キーを自動インクリメント整数フィールドに設定し、文字列フィールドにインデックスを置きます。

その方法でテーブルを検索する場合、それらは比較的高速である必要があり、すべての結合と通常のルックアップは速度に影響しません。

インデックスを作成する文字列フィールドの量を制御することもできます。つまり、十分だと思う場合は、「最初の5文字のみをインデックス化する」と言うことができます。または、データが比較的似ている場合は、フィールド全体にインデックスを付けることができます。

1
John Bubriski

データベース内の文字列に関連する非常に大きな誤解がある可能性があります。ほとんどすべての人が、数値のデータベース表現は文字列よりもコンパクトであると考えています。彼らはdb-sの数字はメモリのように表現されると考えています。しかし、そうではありません。ほとんどの場合、数値表現は、他の表現よりもA文字列に近いです。

数値または文字列の使用速度は、タイプ自体よりもインデックス付けにより依存しています。

0
takacsot

デフォルトでは、ASPNetUserIdは128文字の文字列であり、パフォーマンスは問題ありません。

キーがテーブル内で一意であるを持っている場合、それはキーである必要があります。その理由は次のとおりです。

プライマリ文字列キー=正しいDB関係、1つの文字列キー(プライマリ)、および1つの文字列インデックス(プライマリ)。

もう1つのオプションは典型的なintキーですが、文字列が一意であるを持っている場合、おそらくnonのためにインデックスを追加する必要があります-クエリを停止して、その一意性を検証または確認します。

int identity key = Incorrect DB Relationships、1 int key(Primary)、1 int index(Primary)、おそらくユニークな文字列インデックスを使用し、同じ文字列を手動で検証する必要はありません多分SQLチェック)。

主キーの文字列に対してintを使用してパフォーマンスを向上させるには、文字列が一意であるを持っている場合、非常に奇妙な状況。私は常に文字列キーを使用することを好みました。経験則として、が必要になるまでデータベースを非正規化しないでください。

0
JPoole