私はデータベースとそれらがどのように機能するかの背後にある理論にあまり精通していません。パフォーマンスの観点(挿入/更新/クエリ)から、整数よりも主キーに文字列を使用する方が遅いですか?
15 に答える
技術的にはそうですが、文字列が主キーであることが理にかなっている場合は、おそらくそれを使用する必要があります。これはすべて、作成するテーブルのサイズと主キーとなる文字列の長さによって異なります(文字列が長い==比較が難しくなります)。数百万行のテーブルに文字列を使用する必要はありませんが、小さいテーブルで文字列を使用することで得られるパフォーマンスの低下は、整数を使用しないことで発生する可能性のある頭痛の種になります。データに関して何も意味しません。
文字列を主キーとして使用する場合のもう1つの問題は、インデックスが常に順番に並べられるため、順序の途中にある新しいキーが作成されると、インデックスを並べ替える必要があることです...自動を使用する場合整数の場合、新しいキーはインデックスの最後に追加されます。
挿入がシーケンスの途中で発生するクラスター化インデックスを持つテーブルへの挿入では、インデックスが書き換えられることはありません。データを構成するページが書き換えられることはありません。ページに行が入るスペースがある場合は、そのページに配置されます。1 つのページが再フォーマットされ、行がページ内の適切な場所に配置されます。ページがいっぱいになると、ページ分割が発生し、ページの行の半分が一方のページに移動し、残りの半分が他方のページに移動します。次に、ページは、クラスター化インデックスを持つテーブル データを構成するページのリンク リストに再リンクされます。せいぜい、データベースの 2 ページを書き込むことになります。
文字列は結合が遅く、実際には、文字列が実際に一意になることはめったにありません(想定されている場合でも)。唯一の利点は、名前を取得するためだけにプライマリテーブルに結合している場合に、結合の数を減らすことができることです。ただし、文字列も変更されることが多いため、会社名が変更されたり、結婚したりしたときに、関連するすべてのレコードを修正する必要があるという問題が発生します。これはパフォーマンスに大きな打撃を与える可能性があり、何らかの形で関連しているはずのすべてのテーブルが関連していない場合(これは思ったよりも頻繁に発生します)、データの不一致も発生する可能性があります。レコードの存続期間を通じて変更されることのない整数は、データの整合性の観点からもパフォーマンスの観点からもはるかに安全な選択です。自然キーは通常、データの保守にはあまり適していません。
また、両方の長所は、自動インクリメントキー(または一部の特殊なケースではGUID)をPKとして使用し、自然キーに一意のインデックスを付けることです。より高速な結合が得られ、重複するレコードが得られず、会社名が変更されたために100万の子レコードを更新する必要がありません。
変数が多すぎます。これは、テーブルのサイズ、インデックス、文字列キードメインの性質によって異なります。
一般的に、整数の方が高速です。しかし、違いは気にするのに十分な大きさでしょうか?言うのが難しい。
また、弦を選ぶ動機は何ですか?多くの場合、数値の自動インクリメントキーも非常に簡単です。セマンティクスですか?快適?レプリケーション/切断の懸念?ここでのあなたの答えはあなたの選択肢を制限するかもしれません。これはまた、あなたが忘れている3番目の「ハイブリッド」オプションであるGuidsを思い起こさせます。
UNIQUEである限り、主キーとして何を使用してもかまいません。速度や優れたデータベース設計が必要な場合は、データの複製を計画していない限り、intを使用してから、GUIDを使用してください。
これがアクセスデータベースまたはいくつかの小さなアプリである場合、誰が本当に気にします。私たちの開発者のほとんどが古いintまたはguidを最前線で叩く理由は、プロジェクトには成長の方法があり、成長するオプションを自分に残したいからだと思います。
データが説明する主題に一致し、データの使用目的にうまく適合するシンプルで健全な設計が得られるまで、パフォーマンスについて心配する必要はありません。その後、パフォーマンスの問題が発生した場合は、システムを微調整して対処できます。
この場合、ほとんどの場合、文字列を自然な主キーとして使用することをお勧めします。ただし、それが信頼できる場合に限ります。文字列が適度に短い限り、たとえば最大 25 文字程度であれば、文字列であっても心配する必要はありません。パフォーマンスに関して大きな代償を払うことはありません。
データ入力担当者または自動データ ソースは、想定される自然キーに対して常に値を提供しますか?それとも省略される場合がありますか? 入力データが時々間違っていませんか?もしそうなら、エラーはどのように検出され、修正されますか?
クエリを指定するプログラマーや対話型ユーザーは、自然キーを使用して必要なものを取得できますか?
自然キーを信頼できない場合は、サロゲートを発明してください。サロゲートを発明するなら、整数を発明することもできます。次に、サロゲートをユーザー コミュニティから隠すかどうかを心配する必要があります。代理キーを隠蔽しなかった一部の開発者は、後悔するようになりました。
インデックスは、多くの比較を意味します。
通常、文字列は整数よりも長く、照合ルールが比較に適用される場合があるため、文字列の比較は通常、整数の比較よりも計算量の多いタスクです。
ただし、テーブルとの追加の結合を行うよりも、文字列を主キーとして使用する方が速い場合がありstring to numerical id
ます。
はい。ただし、数百万行になると予想される場合を除いて、文字列ベースのキーは低速であるため使用しないのは、通常、「時期尚早の最適化」です。結局のところ、文字列は大きな数字として保存されますが、数値キーは通常小さな数字として保存されます。
ただし、注意すべき点の1つは、任意のキーにクラスター化されたインデックスがあり、インデックス内で非シーケンシャルな多数の挿入を実行している場合です。行が書き込まれるたびに、インデックスが再書き込みされます。バッチ挿入を行う場合、これによりプロセスが非常に遅くなる可能性があります。
文字列を主キーとして使用する理由は何ですか?
主キーを自動インクリメント整数フィールドに設定し、文字列フィールドにインデックスを付けるだけです。
そうすれば、テーブルで検索を行う場合、それらは比較的高速であるはずであり、すべての結合と通常のルックアップはそれらの速度に影響されません。
インデックスを作成する文字列フィールドの量を制御することもできます。つまり、「最初の5文字だけをインデックスに登録する」と言えば、それで十分だと思います。または、データが比較的類似している可能性がある場合は、フィールド全体にインデックスを付けることができます。
パフォーマンスの観点から - はい、文字列 (PK) は、整数 (PK) を使用して達成されるパフォーマンスと比較すると、パフォーマンスが低下します。ここで、PK ---> プライマリ キーです。
要件の観点から - これはあなたの質問の一部ではありませんが、まだ言及したいと思います。異なるテーブル間で巨大なデータを処理する場合、通常、特定のテーブルに設定できる可能性のあるキーのセットを探します。これは主に、多くのテーブルがあり、ほとんどの場合、各テーブルまたは一部のテーブルが何らかの関係 (外部キーの概念) を介して他のテーブルに関連付けられるためです。したがって、常に整数を主キーとして選択できるわけではなく、そのテーブルの主キーとして 3 つ、4 つ、または 5 つの属性の組み合わせを使用します。これらのキーは、レコードを他のテーブルと関連付ける際に外部キーとして使用できます。これにより、必要に応じて異なるテーブル間でレコードを関連付けることができます。
したがって、最適な使用法のために - 常に 1 つまたは 2 つの整数と 1 つまたは 2 つの文字列属性の組み合わせを作成しますが、これも必要な場合に限られます。
データベース内の文字列に関連する非常に大きな誤解がある可能性があります。ほとんどの人は、数値のデータベース表現は文字列よりもコンパクトであると考えています。彼らは、db-sでは数値はメモリ内のように表されると考えています。しかし、それは真実ではありません。ほとんどの場合、数値表現は他の表現と同様に文字列に近いです。
数値または文字列を使用する速度は、タイプ自体よりもインデックスに依存します。