web-dev-qa-db-ja.com

主キーと一意の制約

現在、新しいデータベースを設計しています。学校では、各テーブルに主キーを配置することを常に学びました。

PKの代わりにユニーク制約(いくつかのdbのユニークインデックス)を使用する方が良いと言っている多くの記事/議論/ニュースグループの投稿を読みました。

あなたの視点は何ですか?

44
vIceBerg

これらの記事への参照を提供できますか?

試した方法と本当の方法を変更する理由はないと思います。結局のところ、主キーはリレーショナルデータベースの基本的な設計機能です。

同じ目的を果たすためにUNIQUEを使用することは、私にとって本当にハックに聞こえます。彼らの論理的根拠は何ですか?

編集:私の注意はこの古い答えに引き戻されました。おそらく、PK対UNIQUEに関してあなたが読んだ議論は、PKに一意性を強制することを唯一の目的として、何かをPKにしている人々を扱っていました。これに対する答えは、ISキーであれば、キーにし、そうでなければUNIQUEにします。

38
Chris Cudmore

主キーは、実際には 候補キー であり、NULLは許可されません。そのため、SQLの用語では、他の一意のキーと違いはありません。

ただし、非理論的なRDBMSの場合は、主キーが必要です。そうでないと主張したことは聞いたことがありません。その主キーが 代理キー である場合、alsoには natural key( s)

無視する重要な点は、候補(自然または代理)キーのallに一意の制約があることです。次に、 Foreign Key で参照するのが最も簡単なものを選択して、主キー*にします。

クラスター化インデックス *も必要です。このcouldは主キーまたは自然キーになりますが、どちらかである必要はありません。テーブルのクエリの使用に基づいてクラスター化インデックスを選択する必要があります。疑わしいときは、主キーは最初の悪い選択ではありません。

  • 技術的には外部キー関係の一意のキーを参照することだけが要求されますが、主キーを大きく優先する標準的な慣行を受け入れています。実際、一部のRDBMSで主キー参照のみが許可されていても驚かないでしょう。

  • 編集:Oracleの「クラスター化テーブル」および「クラスター化インデックス」という用語は、SQL Serverとは異なることが指摘されています。私がOracle-eseで話しているものと同等のものは、 Index Ordered Table であり、OLTPテーブルに推奨されます。 SO質問。大規模なOLAPデータウェアハウスを担当している場合は、データベースの設計と最適化に関する独自の意見があるはずです。

46
Mark Brackett

主キーは、特別な処理(インデックスの自動作成など)のために選ばれた候補キー(一意の制約)です。

私は、彼らに反論する人々が、ある鍵を別の鍵とは異なる扱い方をする理由を見出さないと期待しています。それは私が立つところです。

[編集]どうやら、私は50ポイントなしでは自分の答えにもコメントできないようです。

@chris:害はないと思います。 「主キー」は実際には単なる構文上の砂糖です。私は常にそれらを使用していますが、私は確かにそれらが必要だとは思わない。一意のkeyが必要です。はい、ただし必ずしも主キーではありません。

10
Dave

主キーのないテーブルが必要になるのは、非常にまれな非正規化です。主キーには、PKとしての性質によって自動的に一意の制約があります。

主キーに対するADDITIONの列の一意性を保証する場合、一意制約が使用されます。

常にPKを使用するというルールは適切です。

http://msdn.Microsoft.com/en-us/library/ms191166.aspx

9

always主キーが必要です。

しかし、あなたの質問は少し誤解を招きやすい言葉であり、実際には、主キーが常に自動生成された数値(代理キーとも呼ばれる)であるか、実際の意味のあるデータである一意のフィールド(自然とも呼ばれる)キー)、人々のSSN、書籍のISBNなど。

この質問は、DB分野における古くからの宗教戦争です。

私の考えでは、もしそれらが本当に一意であり、決して変わらないなら、自然キーが望ましいということです。ただし、特定の状況ではSSNのように一見安定しているものが変更される可能性があるため、注意が必要です。

5
JacquesB

テーブルが作業中にデータをステージングするための一時テーブルでない限り、常にテーブルに主キーを配置する必要があります。その理由は次のとおりです。

1-一意の制約はnullを許可できますが、主キーneverはnullを許可します。 null値を持つ列で結合を使用してクエリを実行すると、nullはnullと等しくないため、結果のデータセットからそれらの行を削除します。これは、大企業でも会計上の誤りを犯し、利益を修正し直す必要がある方法です。それらのクエリでは、一意のインデックスの列の一部にnull値が含まれていたため、合計に含めるべき特定の行が表示されませんでした。 Shouldaは主キーを使用しました。

2-一意のインデックスが主キーに自動的に配置されるため、作成する必要はありません。

3-ほとんどのデータベースエンジンは、クラスター化インデックスを主キーに自動的に配置し、行がデータブロックに連続して格納されるため、クエリを高速化します。 (クエリを高速化する場合は、これを変更してクラスター化インデックスを別のインデックスに配置できます。)テーブルにクラスター化インデックスがない場合、行はデータブロックに連続して格納されず、クエリが作成されます。読み取り/書き込みヘッドがデータを取得するためにディスク全体を移動する必要があるため、遅くなります。

4-多くのフロントエンド開発環境では、テーブルを更新したり削除したりするために主キーが必要です。

3
Chris OC

主キーは、このテーブルからこの値を参照する他のテーブルへの関係を確立する状況で使用する必要があります。ただし、一意制約を適用することを考えているテーブルとデータの性質によっては、サロゲートキーを確立する必要なく、その特定のフィールドを自然なプライマリキーとして使用できる場合があります。もちろん、代理キーと自然キーはまったく別の議論です。 :)

このテーブルと他のテーブルの間に関係が確立されない場合、一意のキーを使用できます。たとえば、新しいユーザーレコードなどを挿入する前に比較される有効な電子メールアドレスのリストを含むテーブル。または、主キーを持つが絶対的に一意である必要があるテーブルに値がある場合、一意のキーを使用できます。たとえば、ユーザー名を持つユーザーテーブルがある場合。ユーザー名を主キーとして使用する必要はありませんが、ログイン目的で使用するためには、ユーザー名も一意である必要があります。

3
Noah Goodrich

ここで、論理構造と物理構造を区別し、理論と実践を区別する必要があります。

まず、理論的な観点から見ると、主キーがない場合、テーブルはありません。とても簡単です。したがって、あなたの質問は、テーブルに主キーを含めるべきかどうかではなく(もちろん必要です)、RDBMS内でどのようにラベル付けするかです。

物理レベルでは、ほとんどのRDBMSは一意キーとして主キー制約を実装します。選択したRDBMSがこれらの1つである場合、主キーとして列を指定することと、列に一意の制約を単純に設定することとの間には、おそらくあまり実用的な違いはありません。ただし、これらのオプションの1つは意図をキャプチャし、もう1つはキャプチャしません。したがって、決定は簡単です。

さらに、一部のRDBMSは、ダイアグラムや半自動化された外部キー制約のサポートなど、主キーが適切にラベル付けされている場合に追加機能を使用可能にします。

一般的なルールとして主キーの代わりに一意の制約を使用するように言っている人は誰でも、かなりのひどい正当な理由を提供すべきです。

2
Michael Dorfman

主キー

1。Null Null値は許可されません。このため、PRIMARY KEY = UNIQUE KEY + Not Null CONSTRAINTを参照します。 2。INDEXデフォルトでは、クラスター化インデックスを追加します。 。LIMITテーブルには、1つのPRIMARY KEY列のみを含めることができます。

一意のキー

1。Null Null値を許可します。ただし、Null値は1つだけです。 2。INDEXデフォルトでは、UNIQUE非クラスター化インデックスを追加します。 。LIMITテーブルには複数のUNIQUEキー列を含めることができます。

1
sushmita

私はこのテーマについて多くのことを書いてきました。もしあなたが私の何かを読んでいるなら、おそらく私がJet a.k.a. MS Accessを特に言及していることを明確にしてください。

Jetでは、テーブルは、メンテナンスされていないクラスター化インデックスを使用して、プライマリキーで物理的に順序付けられます(コンパクトにクラスター化されます)。テーブルにPKがなく、NOT NULL列のUNIQUE制約を使用して定義された候補キーがある場合、エンジンはクラスター化インデックス用に1つを選択します(テーブルにクラスター化インデックスがない場合は、おそらくテーブルではなくヒープと呼ばれます) !)エンジンは候補キーをどのように選択しますか? null許容列を含むものを選択できますか?私は本当に知りません。ポイントは、Jetでは、クラスター化インデックスをエンジンに明示的に指定する唯一の方法は、PRIMARY KEYを使用することであるということです。もちろん、JetのPKには他の用途もあります。 SQL DDLのFOREIGN KEY宣言から1つが省略された場合にキーとして使用されますが、これも明示的でない理由です。

Jetの問題は、テーブルを作成するほとんどの人がクラスター化インデックスを認識していないか、またはクラスター化インデックスに関心がないことです。実際、ほとんどのユーザー(私は賭けます)は、すべてのテーブルに自動インクリメントの自動番号列を配置し、自然キーと候補キーに一意の制約を設定することなく、この列にのみPRIMARY KEYを定義します(自動インクリメント列は実際にはエンドユーザーに公開しないキーは、それ自体が別の議論です。ここではクラスター化インデックスの詳細については説明しませんが、IMOのみの自動インクリメントカラムが理想的な選択となることはほとんどありません。

SQLエンジンが何であれ、PRIMARY KEYの選択は任意であり、エンジン固有です。通常、エンジンはPKに特別な意味を適用するため、PKが何であるかを見つけて、それを有利に使用する必要があります。特にデータモデルで意味を持たない(自動)列を使用することを選択した場合、すべての候補キーをさらに考慮することを期待して、NOT NULL UNIQUE制約を使用することをお勧めします。しかし、私はむしろ、よく考えられたキーを1つ選択し、PRIMARY KEYを習慣から自動インクリメントカラムに置くのではなく、使用したいと思います。

すべてのテーブルにPKが必要ですか?そうでなければ、少なくともエンジンがPKを提供し、最悪の場合はデータの整合性がないというわずかな利点を逃してしまうことになるからです。

BTW Chris OCは、単純なPRIMARY KEY制約(大文字のSQLキーワード)を介して実装できないシーケンス化された主キー(小文字)を必要とするテンポラルテーブルについてここで良い点を示しています。

1
onedaywhen

pKの代わりにユニーク制約(別名dbのユニークインデックス)を使用した方が良いと言っている投稿

一意のインデックスとpk´sは同じものであるため、ここでの唯一のポイントは、同じ古い議論「自然対サロゲートキー」だと思います。

翻訳:

サロゲートキーの代わりに自然キーを使用する方が良いと言っている投稿

1

私は通常、PKと一意キーの両方を使用します。スキーマでPKを指定しなくても、常に内部的に生成されます。 SQL Server 2005とMySQL 5の両方に当てはまります。

しかし、SQLではPK列を使用しません。これは、誤った行の削除、PK値がAUTO INCREMENTに設定されている場合のPK値間のギャップの検出などの管理目的のためです。また、一連の列やchar配列ではなく、数値としてPKを使用することは理にかなっています。

1
yogman

主キーは、テーブルの単一レコードを一意に識別する1つ以上の列になります。一意制約は、テーブルの特定のデータ要素の単一インスタンスのみを許可するフィールドの制約です。

個人的には、GUIDまたは自動インクリメントBIGINTS(SQL SERVERのID挿入)を使用して、テーブル間の相互参照に使用される一意のキーを使用します。その後、他のデータを使用して、特定のレコードを選択します。

たとえば、従業員のリストがあり、舞台裏で使用するすべてのレコードにGUIDが添付されていますが、ユーザーが従業員を選択すると、彼らは次のフィールドのうち:LastName + FirstName + EmployeeNumber。

このシナリオでの私の主キーは、LastName + FirstName + EmployeeNumberですが、一意のキーは関連付けられたGUIDです。

1

LINQ-to-SQLの使用を計画している場合、更新の実行を計画する場合はテーブルに主キーが必要になり、非接続環境での作業(オブジェクトをWCFサービスに渡すなど)を計画する場合はtimestamp列が必要になります応用)。

.NETが好きなら、PKとFKがあなたの友達です。

0
Jarrett Meyer

私はこの問題を自分で考えていました。 uniqueを使用している場合、NFを傷つけます。これによると、すべての非pk属性はPKに依存する必要があります。この一意の制約の属性のペアは、PKの一部と見なされます。

この7年後に返信して申し訳ありませんが、新しいディスカッションを開始したくありませんでした。

0
Clevemayer

両方が必要な場合があります。本来、主キーは一意であり、null不可である必要があります。整数は、文字フィールドよりも高速な結合を作成し、特に複数フィールドの文字結合よりも作成されるため、これらは多くの場合代理キーです。ただし、これらは多くの場合自動生成されるため、IDを除くデータレコードの一意性は保証されません。テーブルに一意の自然キーがある場合は、重複のデータ入力を防ぐために一意のインデックスが必要です。これは基本的なデータ整合性要件です。

編集して追加:また、特にデータベースが人中心である場合、正規化されたテーブル構造の一意性を真に保証する自然なキーが現実世界のデータに含まれていないこともしばしばあります。名前、偶数の名前、住所、電話番号を組み合わせたもの(同じ医療行為で父と息子を考える)は必ずしも一意ではありません。

0
HLGEM