web-dev-qa-db-ja.com

主キー/外部キーの命名規則

開発グループでは、主キーと外部キーの命名規則に関する激しい議論があります。私たちのグループには、基本的に2つの考え方があります。

1:

Primary Table (Employee)   
Primary Key is called ID

Foreign table (Event)  
Foreign key is called EmployeeID

または

2:

Primary Table (Employee)  
Primary Key is called EmployeeID

Foreign table (Event)  
Foreign key is called EmployeeID

どの列でもテーブルの名前を複製しないことを好みます(したがって、上記のオプション1を好みます)。概念的には、プロパティ名にオブジェクトの名前を使用しない他の言語の多くの推奨プラクティスと一致しています。外部キーにEmployeeID(またはEmployee_IDの方が優れている場合があります)は、IDテーブルのEmployee列であることを読者に伝えます。

他の一部のユーザーは、列名がデータベース全体で同じになるように、主キーにテーブル名の接頭辞を付けるオプション2を好んでいます。その点はわかりましたが、主キーと外部キーを視覚的に区別できなくなりました。

また、列名にテーブル名を含めることは冗長だと思います。テーブルをエンティティと見なし、列をそのエンティティのプロパティまたは属性と見なす場合、EmployeeのID属性と見なすためです。従業員のEmployeeID属性ではありません。私は同僚にPersonAgeまたはPersonGenderが何であるかを尋ねません。私は彼に彼の年齢が何であるか尋ねます。

私が言ったように、それは激しい議論であり、私たちはそれについてどんどん進んでいきます。私はいくつかの新しい視点を得ることに興味があります。

89
Jeremy

本当に問題ではありません。選択肢1と選択肢2の間に実際の違いがあるシステムに遭遇したことはありません。

ジェフ・アトウッドは、このトピックについてしばらく前に素晴らしい記事を書いていました。基本的に人々は、彼らが間違っていると証明できないトピックを最も激しく議論し、議論します。または、別の角度から、フィリバスタースタイルの持久力に基づく最後の人が立てた議論によってのみ獲得できるトピック。

いずれかを選択して、実際にコードに影響を与える問題に焦点を当てるよう指示します。

編集:楽しみたい場合は、再帰的なテーブル参照に対してメソッドが優れている理由を詳細に指定してもらいます。

48
Russell Steen

2つの列の名前が両方のテーブルで同じ場合(慣例#2)、SQLのUSING構文を使用して、入力と定型的なノイズを節約できます。

SELECT name, address, amount
  FROM employees JOIN payroll USING (employee_id)

慣習#2を支持するもう1つの議論は、それが リレーショナルモデル の設計方法であるということです。

各列の重要性は、対応するドメインの名前でラベルを付けることによって部分的に伝えられます。

69
Steven Huwig

私はそれがあなたのアプリケーションがどのように組み立てられるかによって決まると思います。 ORMを使用するか、オブジェクトを表すためにテーブルを設計する場合、オプション1が適している場合があります。

データベースを独自のレイヤーとしてコーディングするのが好きです。すべてを制御し、アプリはストアドプロシージャを呼び出すだけです。特に多くのテーブルが結合され、多くの列が返される場合は、完全な列名を持つ結果セットがあると便利です。このタイプのアプリケーションでは、オプション2が好きです。結合で列名が一致するのを見るのが本当に好きです。一致しない古いシステムで作業してきましたが、それは悪夢でしたが、

12
KM.

いずれの規約もすべての場合に機能するわけではありません。常識を使用...

たとえば、自己参照テーブルの場合、同じテーブルのPKを自己参照するFK列が複数ある場合、2つのFK列に同じ名前を付けることはできないため、両方の「標準」に違反することになります。 、EmployeeId PK、SupervisorId FK、MentorId Fk、PartnerId FKなどのEmployeeTable.

3
Charles Bretana

それらを選択することはほとんどないことに同意します。私にとって、どちらの標準についてもはるかに重要なのは「標準」の部分です。

人々が「自分のことをする」ことを始めたら、彼らは地獄に縛られるべきです。私見では :)

3
MatBailie

次のことを考慮しましたか?

Primary Table (Employee)   
Primary Key is PK_Employee

Foreign table (Event)  
Foreign key is called FK_Employee
3
Wouter

私は慣習#2が好きです-このトピックを調査し、自分自身を投稿する前にこの質問を見つけると、次の問題にぶつかりました。

多数の列を持つテーブルから*を選択し、同様に多数の列を持つ2番目のテーブルに結合しています。両方のテーブルには主キーとして「id」列があります。つまり、これら2つの値を結果で一意にするために、すべての列を(私が知る限り)具体的に選択する必要があります。

SELECT table1.id AS parent_id, table2.id AS child_id

慣習#2を使用すると、同じ名前の列が結果に残ることになりますが、今ではwhich id(必要な親または子)を指定でき、Steven Huwigが示唆したように、USINGステートメントは、物事をさらに簡素化します。

2
JYelton

私が作業している場所で使用している規則は、複数形(つまり「従業員」)でテーブルに名前を付け、テーブル名と列名の間にアンダースコアを使用することを除いて、Aにかなり近いです。この方法の利点は、列を参照するには、アクセス方法に応じて「employees _ id」または「employees.id」のいずれかになることです。列の取得元のテーブルを指定する必要がある場合、「employees.employees _ id」は間違いなく冗長です。

2
Jarett Millard

あるテーブルではPKとしてserIdを使用し、別のテーブルではFKとしてserIdを常に使用しています。 'serIdPKおよびserIdFKを名前から区別して使用することを真剣に考えています。テーブルを見るときにPKとFKをすばやく特定するのに役立ちます。また、PHP/SQLを使用してデータにアクセスすると理解しやすくなるため、コードがクリアされるようです。特に誰かが私のコードを見るとき。

2
Ross

データベースクエリだけでなく、アプリケーションコードを見ている場合、いくつかのことが明らかです。

  1. 通常、テーブル定義は1つのオブジェクトを記述するクラスに直接マップされるため、単数形でなければなりません。オブジェクトのコレクションを記述するために、複数形の使用がそれがコレクションであることだけでなく、どのようなコレクションであるかを明確に示すため、通常、単数名に「Array」または「List」または「Collection」を追加しますそうです。そのビューでは、テーブル名はコレクションの名前ではなく、コレクションであるオブジェクトのタイプの名前として表示されます。アプリケーションコードを記述しないDBAは、この点を見逃す可能性があります。

  2. 私が扱うデータは、多くの場合、非キー識別のために「ID」を使用します。キー「ID」と非キー「ID」の間の混乱を排除するために、主キー名に、テーブル名または略称を接頭辞として付けた「キー」(つまり、そうですね)を使用しますテーブル名。この接頭辞(およびこれは主キーのみに予約されています)によりキー名が一意になります。これは、データベース列名と同じ変数名を使用し、ほとんどのクラスには親があり、親キー。これは、それが「Key」だけである予約キーワードではないことを確認するためにも必要です。キー変数名の一貫性を維持し、自然な結合を行うプログラムを提供するために、外部キーは、それらが主キーであるテーブルで使用されているのと同じ名前を持っています。私は、自然結合を使用してこの方法でより良く機能するプログラムに何度も遭遇しました。この最後の点で、私が使用した自己参照テーブルの問題を認めます。この場合、外部キーの命名規則に例外を設けます。たとえば、EmployeeKeyテーブルの外部キーとしてManagerKeyを使用して、そのテーブルの別のレコードを指すようにします。

2
Bruce Patin

慣習#2を使用します。現在、私はレガシーデータモデルを使用しています。特定のテーブルの意味がわからない場合です。冗長であることの害はどこにありますか?

1
OMG Ponies

外部キーの命名方法はどうですか

role_id

ここで、roleは、参照されるエンティティが手元のテーブルに対して相対的な役割です。これにより、同じテーブルに対する再帰的な参照と複数のfksの問題が解決されます。

多くの場合、参照されるテーブル名と同じになります。この場合、提案の1つと同じになります。

いずれにせよ、havinの長い議論は悪い考えです

1
Jens Schauder

「「order.employee_id = employee.idの従業員INNER JOIN注文」のどこに追加の資格が必要ですか?」.

私が話した資格はすでにあるので、追加の資格は必要ありません。

「ビジネスユーザーが注文IDまたは従業員IDを参照する理由は、コンテキストを提供するためですが、dabaseレベルでは、テーブルを参照しているため既にコンテキストがあります」。

祈って、列に「ID」という名前が付いている場合、「テーブルを参照する」ことは、ID列へのこの参照を私が話している方法で正確に修飾しない限り、どのように正確に行われますか?

0
Erwin Smout