19

Web アプリケーションで使用する小さな SQL データベースを設計しています。

特定のテーブルに、2 つの行が同じ値を持つことを許可されない Name フィールドがあるとします。ただし、ユーザーはいつでも [名前] フィールドを変更できます。

このテーブルの主キーは、他のテーブルで外部キーとして使用されます。そのため、Name フィールドが主キーとして使用された場合、すべての変更を他のテーブルに伝達する必要があります。一方、一意性要件は自動的に処理されます。

私の本能は、データベースによって自動的に入力される主キーとして機能する整数フィールドを追加することです。このフィールドを持つことに意味はありますか、それとも時間の無駄でしょうか?

4

11 に答える 11

25

あなたが言及した理由だけで、生成されたPKを自分で使用します。また、整数によるインデックス付けと比較は、文字列による比較よりも高速です。名前フィールドを主キーにせずに一意のインデックスを配置することもできます。

于 2008-10-03T13:10:29.700 に答える
12

あなたが説明しているものは、代理キーと呼ばれます。長い答えについては、ウィキペディアの記事を参照してください。

于 2008-10-03T13:23:28.300 に答える
6

整数列を検索して結合する方が高速ですが (多くの人が指摘しているように)、最初から結合しない方がさらに高速です。自然キーを格納することで、多くの場合、結合の必要がなくなります。

小規模なデータベースの場合、外部キー参照への CASCADE 更新は、非常に頻繁に変更されない限り、パフォーマンスに大きな影響を与えません。

そうは言っても、この場合はおそらく代理キーとして整数または GUID を使用する必要があります。設計によって更新可能な主キーは最良のアイデアではありません。また、アプリケーションに名前が一意であるという非常に説得力のあるビジネス上の理由がない限り、必然的に競合が発生します。

于 2008-10-03T13:33:33.367 に答える
2

はい - 経験則として、常に、すべてのテーブルに対して。

変更可能なフィールドを主キーとして使用するべきではありません。ほとんどの場合、他の目的を持つフィールドを主キーとして使用することは望ましくありません。

これは、db スキーマの基本的なグッド プラクティスです。

于 2008-10-03T13:17:24.223 に答える
2

整数の主キーを持つことは、パフォーマンスの見通しから常に良いことです。整数の主キーを使用すると、すべての関係がより効率的になります。たとえば、JOIN は非常に高速になります ( SQL Server )。

また、データベースの将来の変更も可能にします。多くの場合、一意の名前の列があるだけで、名前がまったく一意ではないことが後でわかります。

現時点では、列Nameにもインデックスを付けることで、列の一意性を強制できます。

于 2008-10-03T13:17:51.057 に答える
2

主キーには自動生成された ID フィールドを使用します。テキストよりも整数 ID に基づくテーブルと結合する方が簡単です。また、フィールドNameが頻繁に更新される場合、それが主キーである場合、そのフィールドのインデックスを頻繁に更新するために、データベースにストレスがかかります。

フィールドが常に一意である場合でも、データベース内で一意としてマークする必要があります。ただし、2 つの同じ名前が存在する可能性がある (現在ではないかもしれませんが、将来的には可能性があります) ため、お勧めしません。

ID を使用するもう 1 つの利点は、データベースでレポートが必要な場合です。特定の名前のセットが必要なレポートがある場合、名前が変更された場合でも、レポートの ID フィルターは一貫したままになります。

于 2008-10-03T13:22:04.607 に答える
1

名前の列が変更される場合は、主キーの候補としては適切ではありません。主キーは、テーブルの一意の行を定義する必要があります。変更できるのであれば、実際にはそうしていません。システムの詳細を知らなければ言うことはできませんが、これは代理キーにとって良い時期かもしれません。

また、すべての主キーに自動インクリメント整数を使用するという神話を払拭することを期待して、これを追加します。それらを使用することは必ずしもパフォーマンスの向上ではありません。実際、それは正反対であることがよくあります。自動インクリメント列がある場合、これは、システム内のすべてのINSERTに、新しい値を生成するための追加のオーバーヘッドがあることを意味します。

また、Markが指摘しているように、関連するテーブルのチェーンがある場合は、すべてのテーブルに代理IDがあり、あるテーブルから別のテーブルに移動するには、それらのテーブルをすべて結合してトラバースする必要があります。通常はそうではない自然な主キーを使用します。通常、6つのテーブルを整数で結合すると、2つのテーブルを文字列で結合するよりも遅くなります。

また、すべてのテーブルに自動インクリメントIDがあると、セットベースの操作を実行する機能が失われることがよくあります。親テーブルに1000行を挿入してから、子テーブルに5000行を挿入する代わりに、生成されたIDを取得して割り当てるために、親行をカーソルまたはその他のループに一度に1つずつ挿入する必要があります。関連する子供たちに。誰かがデータベース内のすべてのテーブルで自動インクリメントIDを使用することを主張したため、30秒のプロセスが20分のプロセスに変わるのを見てきました。

最後に(少なくともここにリストしている理由で-確かに他にもあります)、すべてのテーブルで自動インクリメントIDを使用すると、設計が不十分になります。設計者がテーブルの自然キーが何であるかを考える必要がなくなると、通常、誤った重複がデータに含まれることになります。一意のインデックスの問題を回避することはできますが、私の経験では、開発者と設計者はそのような余分な労力をかけず、新しいシステムを1年使用した後、データベースにデータがないためにデータが混乱していることに気付きます。自然キーによるデータの適切な制約。

確かに代理キーを使用する時間はありますが、すべてのテーブルでそれらを盲目的に使用することは、ほとんどの場合間違いです。

于 2008-10-03T14:07:32.080 に答える
1

あなたが理論数学者の希薄なサークルに住んでいる場合 (すべてのデータ値が既知で正しいため、C. Date が null のない国で行っているように)、主キーは以下から構築できます。参照している理想化されたプラトニック エンティティを識別するデータのコンポーネント (つまり、名前 + 誕生日 + 出生地 + 親の名前)。データベースのコンテキストは、物事を行うためのはるかに実用的な方法です。(そして、null 許容フィールドは、リレーショナル デザイン理論の人々にとって非常に便利です。)

于 2008-10-03T13:31:11.607 に答える
1

レコードの主キーは一意かつ永続的である必要があります。レコードが自然にこれらの両方を満たす単純なキーを持っている場合は、それを使用します。しかし、彼らはあまり頻繁に来ません。個人レコードの場合、個人の名前は一意でも永続的でもないため、自動インクリメントを使用する必要があります。

自然キーが機能する 1 つの場所はコード テーブルです。たとえば、ステータス値をその説明にマッピングするテーブルです。"Active" に 1 という主キー、"Delay" に 2 といった主キーを与えるのはあまり意味がありません。"遅延"、"DLY"; 「保留中」、「HLD」など。

また、比較が高速であるため、文字列よりも整数を使用する必要があると言う人もいます。本当ではありません。2 つの 4 バイト文字フィールドの比較には、2 つの 4 バイト整数フィールドの比較とまったく同じ時間がかかります。もちろん、文字列が長いほど時間がかかりますが、コードを短くしておけば、違いはありません。

于 2008-10-03T13:31:31.403 に答える
0

前述のすべてに加えて、UUID を PK として使用することを検討してください。複数のデータベースにまたがる一意のキーを作成できます。

データを他のデータベースとエクスポート/マージする必要がある場合、データは常に一意のままであり、関係を簡単に維持できます。

于 2016-03-01T10:48:27.170 に答える
0

主キーはすべての行で一意である必要があります。auto_increment Integer は非常に良いアイデアです。主キーの入力について他にアイデアがない場合は、これが最善の方法です。

于 2008-10-03T13:16:12.073 に答える