27

作成者が結合テーブルに主キーを置くのは良くないと言ったスクリーンキャストを見ていましたが、その理由は説明していませんでした。

この例の結合テーブルには、Rails移行で定義された2つの列があり、作成者は各列にインデックスを追加しましたが、主キーは追加しませんでした。

この例で主キーを使用するのはなぜ良くないのですか?

create_table :categories_posts, :id => false do |t|
  t.column :category_id, :integer, :null => false
  t.column :post_id, :integer, :null => false
end
add_index :categories_posts, :category_id
add_index :categories_posts, :post_id

編集:Cletusに述べたように、結合テーブルの場合でも、主キーとしての自動番号フィールドの潜在的な有用性を理解できます。ただし、上記の例では、作成者は「createtable」ステートメントで構文「:id=>false」を使用して自動番号フィールドを作成することを明示的に回避しています。通常、Railsは、このような移行で作成されたテーブルに自動番号IDフィールドを自動的に追加し、これが主キーになります。しかし、この結合テーブルについては、作成者は特にそれを防ぎました。なぜ彼がこのアプローチに従うことにしたのかわかりませんでした。

4

8 に答える 8

56

いくつかのメモ:

  1. category_idとpost_idの組み合わせはそれ自体が一意であるため、追加のID列は冗長で無駄になります。
  2. スクリーンキャストでは、「主キーを持っているのは良くない」というフレーズは正しくありません。あなたはまだ主キーを持っています-それは2つの列で構成されています(例えば、CREATE TABLE foo(cid、pid、PRIMARY KEY(cid、pid))。奇妙ですが、関係理論では、それは非常に正確で自然です。スクリーンキャストの作成者は、「主キーとして「ID」と呼ばれる暗黙の整数属性を持つのは良くない」と言ったほうがよいでしょう。
  3. とにかくcategory_idとpost_idの組み合わせに一意のインデックスを配置して、重複する行が挿入されないようにするため、余分な列を用意するのは冗長です。
  4. 最後に、一般的な命名法はそれを「複合キー」と呼ぶことですが、これも冗長です。関係理論における「キー」という用語は、実際には行を一意に識別する0個以上の属性のセットであるため、主キーはcategory_id、post_idであると言っても問題ありません。
  5. 主キー宣言の最初にMOSTSELECTIVE列を配置します。b(+ / *)ツリーの構築に関する説明は、この回答の範囲外です(下位レベルの説明については、 http ://www.akadia.com/services/ora_index_selectivity.htmlを参照してください)が、あなたの場合は、post_idはテーブルに表示される頻度が低くなり、インデックスがより便利になるため、おそらくpost_id、category_idに配置することをお勧めします。もちろん、テーブルは非常に小さく、インデックスは基本的にデータ行になるため、これはそれほど重要ではありません。テーブルが広い場合は、より広い場合になります。
于 2009-05-19T01:54:09.970 に答える
3

DBAは、この場合の主キーは実際には2つのFK列の組み合わせであると通知します。Rails / ActiveRecordは複合PKではうまく機能しないため(少なくともデフォルトでは)、それが理由である可能性があります。

于 2009-05-19T01:05:43.717 に答える
3

外部キーの組み合わせは、主キー(複合主キーと呼ばれる)にすることができます。個人的には、その代わりに技術的な主キー(自動番号フィールド、シーケンスなど)を使用することを好みます。なんで?そうですね、レコードを識別するのがはるかに簡単になります。これは、レコードを削除する場合に行う必要がある場合があります。

考えてみてください。すべてのリンクのWebページを表示する場合は、レコードを識別するための主キーを使用すると、はるかに簡単になります。

于 2009-05-19T01:11:31.210 に答える
3

基本的には必要ないからです。2つの外部キーフィールドの組み合わせにより、任意の行が適切に一意に識別されます。

しかし、それは単にそれが良いアイデアではない理由を示しています....しかし、なぜそれは悪いアイデアになるのでしょうか?

ID列を追加するとオーバーヘッドが増えることを考慮してください。テーブルは50%多くのディスクスペースを占有します。さらに悪いのは、インデックスの状況です。IDフィールドでは、IDカウントと2番目のインデックスを維持する必要があります。ディスク容量が3倍になり、すべての挿入で実行する必要のある作業が3倍になります。唯一の利点は、DELETEコマンドのWHERE句がわずかに短いことです。

一方、複合キーフィールドがテーブル全体である場合、インデックスはテーブルにすることができます。

于 2009-05-19T01:40:54.240 に答える
3

テーブル、ピリオドに主キーを持たないことは悪い考えです(DBMSがリレーショナルDBMSまたはSQLDBMSの場合)。主キーは、データベースの整合性の重要な部分です。

データベースが不正確で間違った答えを頻繁に提供することを気にしないのであれば、それなしで済ますことができると思います...しかし、ほとんどの人はDBMSからの正確な答えを望んでおり、そのような人にとっては主キーが重要です。

于 2009-05-19T01:42:04.517 に答える
2

次のコメントにコメントしたかった:「ゼロ以上と言うのは正しくない」。

このコメントが追加されたテキストには「ゼロ以上」というテキストが含まれていないことを指摘したかったので、コメントしたいコメントの作成者は、他の誰かが言われていないことを批判していました。

また、「ゼロ以上」と言うのは正しくないと言うのは正しくないということもコメントしたいと思います。まだその理論の詳細を研究することをわざわざしている少数の人々の間で今日一般的に知られている関係理論は、実際には属性のない鍵の可能性を必要とします。

しかし、「コメント」ボタンを押すと、システムは、コメントには50(またはそのようなもの)のレピュテーションスコアが必要であると応答しました。

科学は民主主義ではないこと、そして科学では、たまたま多数派である人や「十分な評判」を持っている人によって真実が決定されないことを世界がどのように忘れているかを示す悲しい例です。

于 2009-05-19T17:43:30.690 に答える
2

最も選択的な列を最初に配置することは、INDEX宣言にのみ関連する必要があります。KEY宣言では、それは重要ではありません(正しく指摘されているように、KEYはSETであり、セット内では順序は重要ではありません-セット{a1、a2}は{a2と同じセットであるため) 、a1})。

DBMS製品が、KEY宣言内の属性の順序に違いをもたらすようなものである場合、そのDBMS製品は、データベースの論理設計(KEY宣言を行う部分)との物理設計を適切に区別しないという罪を犯します。データベース(INDEX宣言を行う部分)。

于 2009-05-19T10:34:29.157 に答える
1

単一のPKを持つことの長所

  • 単一の値で行を一意に識別します
  • 必要に応じて他の場所から関係を簡単に参照できるようにします
  • 一部のツールでは、単一の整数値pkが必要です。

単一のPKを持つことの短所

  • より多くのディスクスペースを使用します
  • 1つではなく3つのインデックスが必要
  • 一意の制約がないと、同じ関係に対して複数の行が作成される可能性があります

ノート

  • 重複を避けたい場合は、一意の制約を定義する必要があります
  • 私の意見では、テーブルが巨大になる場合は単一のpkを使用しないでください。そうしないと、利便性のためにディスク容量をトレードオフします。はい、それは無駄ですが、実際のアプリケーションではディスク上の数MBを気にします。
于 2009-05-19T01:57:22.770 に答える