1

次のようなデータベースがあるとします。

Product with columns [ProductName] [Price] [Misc] [Etc]
Order with columns [OrderID] [ProductName] [Quantity] [Misc] [Etc] 

ProductName は Product の主キーで、何らかの文字列型で一意です。
OrderID は主キーで整数型であり、ProductName は外部キーです。

Product の主キーを整数型の新しい列に変更するとします[ProductID]

これにより、データベースのサイズが縮小され、これら 2 つのテーブルを結合するルックアップ (および同様の操作) が最適化されますか? それとも、これらの最適化は(ほとんど/一般/メイン) SQL データベースの実装によって自動的に実行されますか?

技術的には、(String) ProductName を の主キーとして使用するProductと、データベースは ProductName 列Orderを の行への単なるポインターとして実装し、整数を外部キーとして持つのと同じくらい迅速にProduct実行できる必要があります。これは標準ですか? JOINSQL の実装方法。

更新: この質問は、製品テーブルにシリアル番号が必要かどうかや、データベース内の製品名の変更をどのように処理するかではなく、SQL サーバーが外部キーを処理する方法に関するものです。

4

5 に答える 5

2

文字列の主キーは良くないので、INT に変更するとパフォーマンスが向上します。ほとんどのデータベースはルックアップと比較に主キー インデックスを使用するため、簡単な主キー (可能であれば 1 列) を選択します。主キー列は、結合 (結合列の共通の値に基づいて 2 つ以上のテーブルのデータを結合すること)、クエリの取得、およびクエリ結果セットのグループ化または並べ替えに使用します。インデックス エントリが短いほど、データベースはルックアップと比較を高速に実行できます。

ましてや、商品名が変わったらどうするの?製品名を外部キーとして含むすべての行を更新しますか?

もっとうまく言えなかったので、この回答をチェックしてください: varchar または int の主キーを持つテーブルを設計する必要があります。その回答から引用します:

VARCHAR(10) または (20) を使用すると、あまりにも多くのスペースが使用されます - 4 ではなく 10 または 20 バイトであり、多くの人が知らないことです - クラスタリング キー値は、すべてのインデックス エントリごとに繰り返されます。テーブルに単一の非クラスター化インデックスがあるため、多くのスペースを浪費する可能性があります (ディスクだけでなく、安価です)。SQL Server のメイン メモリでも)。また、可変であるため (4 文字の場合もあれば、20 文字の場合もあります)、SQL サーバーが適切なインデックス構造を適切に維持することは困難です。

于 2010-05-26T11:52:03.197 に答える
0

整数列は、結合で文字列よりも優れた機能を果たします

クラスター化された主キーとしての整数 autoinc 列は、挿入に適しています

于 2010-05-26T11:52:49.357 に答える
0

データベースのサイズを縮小するつもりはありませんが (おそらく製品名フィールドはそのままにしておきます)、ルックアップのパフォーマンスは間違いなく改善されるはずです。

于 2010-05-26T11:53:42.817 に答える
0

ほとんどの実装では、整数データ型は文字列 (CHARなどVARCHAR) よりもサイズが小さくなります。これにより、インデックスのサイズが小さくなります。

さらに、文字列の比較にはいくつかの問題があります。

  1. 一部のデータベース、つまりMySQLでは、文字列キーが圧縮されているため、検索の効率が低下する可能性があります。

  2. 自然言語識別子を使用する文字列B-Treesは、 integer よりも並行性のバランスが取れていない傾向がありますB-Trees。自然言語の単語はアルファベット全体に均等に分散されていないため、より多くの更新と挿入が同じブロックに送られ、ページ分割の数が増加し、最終的にインデックス サイズが増加します。これを回避するために、インデックスで句がOracleサポートされています。REVERSE

  3. 2 つの文字列を比較するときは、照合を考慮する必要があります。通常、これはそれほど重要ではありませんが、多少のオーバーヘッドが追加されます。

于 2010-05-26T11:54:26.187 に答える
0

主キーは一意で、行の作成時に存在し、可能な限り不変である必要があります。IMO、代理キーを使用するかどうかについての議論は、データの完全性の問題に次ぐものであるべきです。

たとえば、製品にシリアル番号が刻印されていて、データベースの行が入力された時点で存在していなければならず、保証されていた場合一意であるためには、IMO が適切な主キーになります。その理由は、この値が他のテーブルの外部キーとして使用され、製品のシリアル番号を取得するための追加のルックアップの費用を節約できるからです。何百万もの行に到達するまで、追加の記憶域スペースは重要ではありません。ただし、シリアル番号が他のメーカーによって刻印されているため、一意性が保証されていない場合 (「おそらく一意である」だけでは十分ではありません)、代理が適切です。実際、ほとんどの「製品」テーブルが代理キーを使用していない場合でも、入力時に使用可能であることが保証され、一意であることが保証され、比較的不変であることが保証されている値がないため、かなりの部分を使用できます。かぎ。

ただし、代理キーを使用する多くの開発者は、代理キーを持つすべてのテーブルに別のキー (つまり、一意の制約)含める必要があることを見落としています。したがって、製品の場合、整数の主キーを追加しても、製品名には一意の制約が必要です。製品名の一意の制約により、整数値が主キーである候補キーと呼ばれるものが作成されます。

代理キーは、舞台裏でグーになることを意図しています。整数キーは最高のパフォーマンスを発揮し、簡単に作成できますが、欠点が 1 つあります。それは、アプリケーション開発者がキーの値をユーザーに表示するのは簡単で、魅力的ですらあります。これはIMOの間違いです。ユーザーはキーの値を決して見る必要はありません。そうしないと、値の順序を変更する必要がある場合 (データベースのマージなど)、またはキーによって作成されたギャップで作成された値を使用する場合に、値自体に依存するようになり、問題が発生します。アイデンティティ値であり、値が連続していることに依存しています。ユーザーに値を表示しない限り、整数の PK を使用しても問題ありません。

于 2010-05-26T14:03:58.533 に答える