データベーステーブルのID列の名前付けについて、人々の意見を知りたいと思いました。
ID列の主キーを持つInvoicesというテーブルがある場合、他のテーブルと競合しないようにInvoiceIDという列を呼び出します。
私が現在働いているところでは、彼らはすべてのID列をIDと呼んでいます。
したがって、彼らは次のことを行います。
Select
i.ID
, il.ID
From
Invoices i
Left Join InvoiceLines il
on i.ID = il.InvoiceID
さて、ここにいくつかの問題があります:
1。あなたは、選択の列をエイリアスする必要があります
2。 ID = InvoiceIDが私の脳に収まりません
3。テーブルのエイリアスを作成せず、InvoiceIDを参照した場合、それがどのテーブルにあるかは明らかですか?
トピックに関する他の人々の考えは何ですか?
IDはSQLアンチパターンです。 http://www.Amazon.com/s/ref=nb_sb_ss_i_1_5?url=search-alias%3Dstripbooks&field-keywords=sql+antipatterns&sprefix=sql+a を参照してください
IDがIDであるテーブルが多数ある場合、レポートをより困難にします。意味がわかりにくくなり、複雑なクエリを読みにくくしたり、エイリアスを使用してレポート自体を区別したりする必要があります。
さらに、誰かが利用可能なデータベースで自然な結合を使用するほど愚かな場合、間違ったレコードに結合します。
一部のデータベースで許可されているUSING構文を使用する場合、IDを使用することはできません。
IDを使用すると、結合構文をコピーした場合(誤って結合することはありません!)、結合条件のエイリアスの変更を忘れてしまうと、誤った結合に陥ってしまいます。
あなたは今持っています
select t1.field1, t2.field2, t3.field3
from table1 t1
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t1.id = t3.table2id
あなたが意味したとき
select t1.field1, t2.field2, t3.field3
from table1 t1
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t2.id = t3.table2id
IdフィールドとしてtablenameIDを使用すると、この種の偶発的な間違いは発生する可能性がはるかに低くなり、見つけやすくなります。
私は常に、ID列の場合はTableName + ID、次に外部キーの場合はTableName + IDよりもIDを好みました。この方法では、すべてのテーブルのidフィールドに同じ名前が付けられ、冗長な説明はありません。すべてのテーブルが同じプライマリキーフィールド名を持っているので、これは私には簡単に思えます。
テーブルを結合し、どのIdフィールドがどのテーブルに属しているかわからない限り、私の意見では、この状況を処理するクエリを作成する必要があります。私が働いている場所では、テーブル/テーブルのエイリアスを使用してステートメントで使用するフィールドを常に優先しています。
最近、私の会社でこのことについてオタクの戦いがありました。 LINQの出現により、冗長なtablename + IDパターンが私の目にはさらに明らかに愚かになりました。最も合理的な人々は、あなたが区別するためにテーブル名を指定する必要があるような方法でSQLを手書きしている場合、FKs入力の節約になるだけでなく、SQLにIDのみを使用すると、[〜#〜] pk [〜#〜]および[〜#〜] fk [〜#〜]です。
例えば。
FROM Employees e LEFT JOIN顧客c ON e.ID = c.EmployeeID
2つがリンクされているだけでなく、[〜#〜] pk [〜#〜]そして、これは[〜#〜] fk [〜#〜]です。古いスタイルでは、見た目も名前も付けられていることを期待せざるを得ません。
InvoiceID
ではなく、ID
を使用します。クエリを読みやすくします-ID
だけが表示されている場合、特にテーブルをi
にエイリアスしている場合は、何でも意味があります。
テーブルのPKは単純にIdで、外部キーはOtherTable + Idをリストする必要があるという点で、Kevenと他の少数の人々に同意します。
しかし、私は最近、この主張にもっと重きを置いた理由を一つ付け加えたいと思います。
私の現在の立場では、POCO生成を使用したエンティティフレームワークを採用しています。 Idの標準の命名規則を使用すると、PKは、一連の共通の列名を共有するテーブルに対して、検証などの基本pocoクラスの継承を許可します。これらの各テーブルのPKとしてTablename + Idを使用すると、これらのベースクラスを使用する機能が破壊されます。
ちょっと考えてみてください。
私の好みは、主キーのIDと外部キーのTableNameIDです。また、エントリのユーザーが読み取り可能な識別子(つまり、名前:-))を保持しているほとんどのテーブルに列「名前」があることも好きです。この構造は、アプリケーション自体に大きな柔軟性を提供し、同じ方法でテーブルをまとめて処理できます。これはvery強力なものです。通常、OOソフトウェアはデータベースの上に構築されますが、db =が許可していないため、OOツールセットは適用できません。名前はまだあまり良くありませんが、一歩です。
選択する
i.ID、il.ID Invoices i Left In InvoiceLines il on i.ID = il.InvoiceID
なぜこれができないのですか?
Select
Invoices.ID
, InvoiceLines.ID
From
Invoices
Left Join InvoiceLines
on Invoices.ID = InvoiceLines.InvoiceID
私の意見では、これは非常に読みやすく簡単です。変数にiおよびilの名前を付けることは、一般的に適切な選択ではありません。
それほど重要ではありません。すべての命名規則で同様の問題が発生する可能性があります。
ただし、クエリを記述するたびにテーブル定義を確認する必要がないように、一貫性を保つことが重要です。
「外部キーのTableNameIDによって参照されるコアテーブル」の「ID」のみを使用する場所で作業を開始したところ、それによって直接引き起こされる2つの運用上の問題を既に発見しています。
あるケースでは、クエリは「... where ID in(SELECT TransID FROM OtherTable ...」ではなく「... where ID in(SELECT ID FROM OtherTable ...)」を使用しました。
間違った文に「... where TransID in(SELECT OtherTableID from OtherTable ...」と表示される場所で、完全で一貫性のある名前が使用されていた場合、それを見つけるのはそれほど簡単ではなかったと正直に言うことができますか?そう。
他の問題は、コードをリファクタリングするときに発生します。以前はクエリがコアテーブルから外れていたのに対して一時テーブルを使用する場合、古いコードは「... dbo.MyFunction(t.ID)...」と表示され、それが変更されないが「t」がコアテーブルの代わりに一時テーブルを使用すると、エラーは発生しません。結果が誤っているだけです。
不要なエラーを生成することが目標である場合(おそらく、十分な作業がない人もいますか?)、この種の命名規則は素晴らしいです。それ以外の場合は、一貫性のある名前付けを行う方法です。
簡単にするために、ほとんどの人はテーブルIDの列に名前を付けます。別のテーブルに外部キー参照がある場合、結合の場合、明示的にInvoiceIDと呼びます(例を使用するため)、とにかくテーブルをエイリアスしているため、明示的なinv.IDはinv.InvoiceIDよりも簡単です
これを正式なデータディクショナリの観点から見てみると、データ要素にinvoice_ID
という名前を付けます。一般に、データ要素名はデータディクショナリ内で一意であり、理想的には全体にわたって同じ名前を持ちますが、コンテキストに基づいて追加の修飾用語が必要になる場合があります。 employee_ID
という名前のデータ要素は、組織図で2回使用できるため、それぞれsupervisor_employee_ID
およびsubordinate_employee_ID
として修飾されます。
明らかに、命名規則は主観的であり、スタイルの問題です。 ISO/IEC 11179のガイドラインが有用な出発点であると思います。
DBMSの場合、テーブルはエンティティのコレクションとして表示されます(cofigテーブル、定数のテーブルなど、1行のみを含むものを除く)。私のemployee_ID
がキーであるテーブルは、Personnel
という名前になります。すぐにTableNameID
の規則はうまくいきません。
大規模なデータモデルで使用されるTableName.ID=PK TableNameID=FK
スタイルを見て、やや紛らわしいと言わざるを得ません。識別子の名前は全体を通して同じであることが非常に好きです。注意すべき点は、前述のスタイルは、外部キーの自然キーと複合キーを避けながら、IDENTITY
(自動インクリメント)列をeveryテーブルに追加するショップで使用されているようです。これらのショップには、正式なデータ辞書がなく、データモデルから構築されない傾向があります。繰り返しますが、これは単にスタイルの問題であり、私が個人的に購読するものではありません。だから最終的に、それは私のためではありません。
とはいえ、テーブルの名前がそのためのコンテキストを提供するときに、列名から修飾子を削除することがある場合があります。 employee_last_name
という名前の要素は、Personnel
テーブルで単にlast_name
になる場合があります。ここでの理論的根拠は、ドメインが「人々の姓」であり、last_name
列でUNION
edされる可能性が高いことですfrom外部キーとして使用されるよりも他のテーブルin別のテーブルですが、もう一度...気が変わるかもしれません。データモデリングは芸術であり、科学であるということです。
I 個人的に(上記で述べたように)Table.IDが[〜#〜] pk [〜#〜]を好むTableID for [〜#〜] fk [〜#〜]でも(私を撃たないでください)Microsoft Accessはこれを推奨します。
ただし、Wordで'ID'を含むすべての列名をリンクする傾向があるため、一部の生成ツールがPKのTableIDを好むという事実も知っています。 IDを含む!!!
クエリデザイナでさえMicrosoft SQL Serverでこれを行います(作成するクエリごとに、列IDのすべてのテーブルで新しく作成された不要な関係をすべて取り除いてしまいます)
このように、私の内部OCDが嫌いなのと同じように、私はTableIDの慣習を採用しています。 Data [〜#〜] base [〜#〜]と呼ばれることを思い出してください。これは、多くの多くのアプリケーションのベースとなることを願っています。そして、すべてのテクノロジーは、明確に記述されたスキーマで十分に正規化されているという利点があります。
人々がTableNameやTableDescriptionなどを使い始めたときに線を引くのは言うまでもない。私の意見では、コンベンションは次のことを行うべきです。
テーブルエイリアス:単数形のフルテーブル名。例.
SELECT Employee.*, eMail.Address
FROM Employees AS Employee LEFT JOIN eMails as eMail on Employee.eMailID = eMail.eMailID -- I would sure like it to just have the eMail.ID here.... but oh well
[更新]
また、このスレッドには、「関係の種類」または役割による重複した列に関するいくつかの有効な投稿があります。たとえば、ストアにEmployeeIDがある場合、スクワットがわかります。ですから、私は時々Store.EmployeeID_Managerのようなことをします。確かにそれは少し大きくなりますが、人々はtable ManagerID、またはwhatEmployeeIDを見つけようとして夢中になりませんがそこで行っています。クエリがWHEREの場合、次のように単純化します。SELECT EmployeeID_Manager as ManagerID FROM Store
一貫している限り、「ID」には何でも使用できます。テーブル名を含めることは重要です。 Erwinなどのモデリングツールを使用して命名規則と標準を適用することをお勧めします。クエリを作成するときに、テーブル間に存在する関係を理解しやすくなります。
最初のステートメントが意味するのは、IDの代わりに 'recno'のような何かを使用できるということです。したがって、このテーブルのPKはinvoice_recnoなどになります。
乾杯、ベン
私の投票はテーブルIDのInvoiceIDに対するものです。また、外部キーとして使用する場合も同じ命名規則を使用し、クエリでインテリジェントなエイリアス名を使用します。
Select Invoice.InvoiceID, Lines.InvoiceLine, Customer.OrgName
From Invoices Invoice
Join InvoiceLines Lines on Lines.InvoiceID = Invoice.InvoiceID
Join Customers Customer on Customer.CustomerID = Invoice.CustomerID
もちろん、他のいくつかの例よりも長いです。しかし、笑顔。これは後世のためであり、いつか、貧しいジュニアコーダーがあなたの傑作を変えなければならないでしょう。この例ではあいまいさはなく、追加のテーブルがクエリに追加されるので、冗長性に感謝します。
一貫性を保つために(表にIDとして使用される単一列の主キーがある場合)、表の主キーにTable_pk
という名前を付けます。そのテーブルの主キーを指す外部キーがある場所では、PrimaryKeyTable_fk
列を呼び出します。そうすれば、CustomerテーブルにCustomer_pk
とOrderテーブルにCustomer_fk
があれば、OrderテーブルがCustomerテーブルのエントリを参照していることがわかります。
私にとって、これは特に読みやすいと思う結合に意味があります。
SELECT *
FROM Customer AS c
INNER JOIN Order AS c ON c.Customer_pk = o.Customer_fk
各キーに一意の名前を付けると、たとえば「invoices.id」の代わりに「invoices.invoice_id」を使用すると、「自然結合」および「使用」演算子を心配なく使用できます。例えば。
SELECT * FROM invoices NATURAL JOIN invoice_lines
SELECT * FROM invoices JOIN invoice_lines USING (invoice_id)
の代わりに
SELECT * from invoices JOIN invoice_lines
ON invoices.id = invoice_lines.invoice_id
SQLは、より冗長にすることなく十分に冗長です。
データベースの列名には、「InvoiceID」を使用します。
LINQを介してフィールドを名前のない構造体にコピーすると、構造内の唯一のIDであれば、そこに「ID」という名前を付けることができます。
列が外部キーで使用されないため、編集編集または削除のために行を一意に識別するためだけに使用される場合は、「PK」という名前を付けます。
FWIW、私たちの新しい標準(これは、すべての新しいプロジェクトで「進化」を意味します)は次のとおりです。
pk_
プレフィックスは主キーを意味します_id
接尾辞は整数の自動インクリメントIDを意味しますfk_
プレフィックスは外部キーを意味します(サフィックスは不要です)_VW
ビューの接尾辞is_
ブール値のプレフィックスしたがって、NAMESという名前のテーブルには、フィールドpk_name_id, first_name, last_name, is_alive,
およびfk_company
と、次のように定義されたLIVING_CUSTOMERS_VW
というビューがあります。
ファーストネーム、ラストネーム FROM CONTACT.NAMES WHERE(is_alive = 'True')
しかし、他の人が言ったように、一貫性があり、あなたの意味を不必要に難読化しない限り、ほぼすべてのスキームが機能します。
DomainNameが好きです|| 「ID」。 (つまり、DomainName + ID)
DomainNameは、常にではありませんが、多くの場合TableNameと同じです。
ID自体の問題は、IDが上方に拡大しないことです。それぞれがIDという名前の最初の列を持つ約200のテーブルを作成すると、データはすべて同じように見え始めます。常にテーブル名でIDを修飾する場合、それは少し役立ちますが、それほど多くはありません。
DomainNameとIDを使用して、外部キーとプライマリキーの名前を付けることができます。 foriegnキーが参照する列にちなんで名前が付けられている場合、ニーモニックの助けになることがあります。正式には、参照整合性の制約により参照が確立されるため、外部キーの名前を参照するキーに関連付ける必要はありません。しかし、クエリや更新の読み取りに関しては非常に便利です。
時々、DomainName || 「ID」は使用できません。同じテーブルに同じ名前の2つの列があるためです。例:Employees.EmployeeIDおよびEmployees.SupervisorID。そのような場合、RoleNameを使用します||例のように「ID」。
最後になりましたが、可能な場合は合成キーではなく自然キーを使用します。自然キーが利用できない、または信頼できない状況もありますが、自然キーが正しい選択である状況はたくさんあります。そのような場合、自然なキーに自然な名前を付けます。多くの場合、この名前には「ID」という文字さえありません。例:OrderNo。Noは「Number」の省略形です。
各テーブルに対して、ツリー文字の短縮形を選択します(例:Employees => Emp)
そのようにして、数値の自動番号主キーはnkEmpになります。
それは短く、データベース全体で一意であり、一目でそのプロパティを正確に知っています。
SQLと使用するすべての言語(主にC#、Javascript、VB6)で同じ名前を使用しています。
プライマリキー/外部キーの命名規則 も参照してください
考え抜かれたテーブルと列の命名システムについては、Interaktサイトの 命名規則 を参照してください。メソッドは、各テーブルの接尾辞(_prd
製品テーブルの場合、または_ctg
はカテゴリテーブルの場合)、特定のテーブルの各列に追加します。したがって、productsテーブルのID列はid_prd
であり、したがってデータベース内で一意です。
外部キーの理解を支援するためにさらに一歩進んでいます。カテゴリテーブルを参照する製品テーブルの外部キーはidctg_prd
これにより、どのテーブルに属するかが明確になります(_prd
接尾辞)およびそれが参照するテーブル(カテゴリ)。
利点は、さまざまなテーブルのID列にあいまいさがなく、クエリが参照している列が列名で一目でわかることです。
私は普通のID名が嫌いです。常にinvoice_idまたはそのバリアントを使用することを強くお勧めします。必要なときにどのテーブルがIDの信頼できるテーブルであるかを常に知っていますが、これは私を混乱させます
SELECT * from Invoice inv, InvoiceLine inv_l where
inv_l.InvoiceID = inv.ID
SELECT * from Invoice inv, InvoiceLine inv_l where
inv_l.ID = inv.InvoiceLineID
SELECT * from Invoice inv, InvoiceLine inv_l where
inv_l.ID = inv.InvoiceID
SELECT * from Invoice inv, InvoiceLine inv_l where
inv_l.InvoiceLineID = inv.ID
すべての最悪なのは、あなたが言及したミックスであり、完全に混乱します。最もよく使用されるIDの1つを除き、ほぼ常にfoo_idであるデータベースを使用する必要がありました。それは完全な地獄でした。
正確な理由から、IDフィールド名にテーブル名を含めることに間違いなく同意します。通常、これはテーブル名を含める唯一のフィールドです。