外部キーの命名体系


152

私は初めて外部キーでの作業を始めたばかりであり、それらに使用する標準の命名スキームがあるかどうか疑問に思っていますか?

これらのテーブルを考えると:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)

タスクにメモがある場合、タスクはユーザーが所有し、ユーザーはメモを作成します。

この場合、3つの外部キーはどのように命名されますか?または、代わりにそれはまったく重要ですか?

更新:この質問は、フィールド名ではなく、外部キー名に関するものです!


6
読者への注意:以下に挙げるベストプラクティスの多くは、30文字の名前制限のため、Oracleでは機能しません。テーブル名または列名はすでに30文字に近い可能性があるため、2つを1つの名前に結合する規則では、切り捨ての標準またはその他のトリックが必要です。
Charles Burns

回答:


179

SQL Serverの標準規則は次のとおりです。

FK_ForeignKeyTable_PrimaryKeyTable

したがって、たとえば、メモとタスクの間のキーは次のようになります。

FK_note_task

そして、タスクとユーザーの間の鍵は次のとおりです。

FK_task_user

これにより、どのテーブルがキーに関係しているかが一目でわかるので、特定のテーブル(最初に指定されたテーブル)がどのテーブルに依存しているか(2番目に指定されたテーブル)を簡単に確認できます。このシナリオでは、キーの完全なセットは次のようになります。

FK_task_user
FK_note_task
FK_note_user

したがって、タスクはユーザーに依存し、メモはタスクとユーザーの両方に依存することがわかります。


1
外部キーが主キーではなく2番目のテーブルの候補キーを指している場合、これを修飾するために名前に3番目のセグメントを使用することになります。これは珍しい状況であり、通常は最初から設計する状況ではないので、これを応答に含めませんでした。
グレッグビーチ、

4
キーを区別するために、現在のテーブル名をキーに含めます。FK名はSQL Serverのグローバル名前空間にあるため、FK_PrimaryKeyTableという名前の2つのFKを2つの異なる外部キーテーブルにアタッチすることはできません。ルールは、他のデータベースサーバーでは異なる場合があります。
グレッグビーチ、

わかりました... Oracleのテーブルごとに異なる名前空間があるので、自己参照は必要ありません。
スティーブモイヤー

29
これは一般的な使用方法のようですが、同じテーブルを指す2つの外部キーがある場合、人々はどうしますか。つまり、messageテーブルにはがありfrom_user_idto_user_id両方ともになりfk_message_userます。fk_tablename_columnnameこの理由から(この例ではfk_message_from_user_id)を使用してから、ターゲットテーブルについて列名を明確にしておく(つまり、to_user_idがユーザーテーブルを明確に参照している)ようにします
コードコマンダー

テーブルの両方にexのアンダースコアがある場合はどうなりますか?user_roleおよびuser_addresses?fk_user_addresses_user_role混乱しませんか?
Govi S

38

私は区切り文字として2つの下線文字を使用します

fk__ForeignKeyTable__PrimaryKeyTable 

これは、テーブル名にアンダースコア文字自体が含まれる場合があるためです。データ要素の名前には下線文字が頻繁に含まれるため、これは一般に制約の命名規則に従います。

CREATE TABLE NaturalPersons (
   ...
   person_death_date DATETIME, 
   person_death_reason VARCHAR(30) 
      CONSTRAINT person_death_reason__not_zero_length
         CHECK (DATALENGTH(person_death_reason) > 0), 
   CONSTRAINT person_death_date__person_death_reason__interaction
      CHECK ((person_death_date IS NULL AND person_death_reason IS NULL)
              OR (person_death_date IS NOT NULL AND person_death_reason IS NOT NULL))
        ...

3
これは絶対に最良の答えです。
Frederik Krautwald

1
非常に具体的な命名規則でDerby DBを作成したところ、これが最も読みやすく、追跡可能です。ありがとう
Anddo

17

いかがFK_TABLENAME_COLUMNNAMEですか?

K EEP I T S imple S tupid可能な限り。


20
多くのキーとテーブルを含む巨大なデータベースがあり、ソフトウェアのスキーマ更新中にエラーが発生した場合、データベース作成スクリプトの検索を行わずに外部キーが定義されている場所を見つけるのは非常に困難です。
JohnC 2012

1
@JohnC FK列名に列名に他のテーブル名がある場合、それは非常に簡単にわかりませんか?これは、2つのテーブルと、それが定義されている列名を示します。例:FK_Animals_OwnerID—OwnerID列で定義された動物と所有者のテーブル
David Sherret

10

SQL Serverに関するMicrosoftからのメモ:

FOREIGN KEY制約は、別のテーブルのPRIMARY KEY制約にのみリンクする必要はありません。別のテーブルのUNIQUE制約の列を参照するように定義することもできます。

そのため、従来のプライマリ/フォーリン関係の用語ではなく、依存関係を説明する用語を使用します。

独立(親)テーブルのPRIMARY KEYを、依存(子)テーブル内の同様に名前が付けられた列で参照する場合、列名を省略します。

FK_ChildTable_ParentTable

他の列を参照する場合、または列名が2つのテーブル間で異なる場合、または単に明示的にする場合:

FK_ChildTable_childColumn_ParentTable_parentColumn

9

私は通常、PKという名前のidをそのままにして、他のテーブルでFKに名前を付けるときに、テーブル名とキー列名を連結します。一部のデータベースは大文字と小文字の区別を破棄し、とにかくすべての大文字または小文字の名前を返すだけなので、キャメルケースを気にすることはありません。いずれにせよ、私のバージョンのテーブルは次のようになります。

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);

行には永続化しているオブジェクトの1つを表すため、表には単数形でも名前を付けています。これらの規則の多くは個人的な好みです。他の人の慣習を採用することよりも、慣習を選択して常にそれを使用することが重要であることをお勧めします。


heh-これは私が実際に使用している正確なスタイルです(ただしcamelCaseで)-リンケージを説明するために、名前に少し余分な説明を追加すると思いました。
nickf 2008年

したがって、少なくともお互いのスキーマを読み取ることができます;)...恥ずかしいのは、数年の不在の後、自分のスキーマを読み取ることができないことです。私たちはスキーマをダイアグラム化するためにERWinを使用しますが、多くの場合、テキストバージョンがあり、テーブルやフィールドを簡単に見つけられるようにする規則があると便利です。
スティーブモイヤー

5

これはおそらくやり過ぎですが、私にとってはうまくいきます。特にVLDBを扱う場合に非常に役立ちます。私は以下を使用します:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

もちろん、何らかの理由で主キーを参照していない場合は、この場合、一意性制約に含まれている列を参照している必要があります。

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

長くていいですか?それはレポートの情報を明確に保つのに役立ちましたか、または潜在的な問題が本番アラート中に発生するという簡単なジャンプを得て、100%この命名規則に関する人々の考えを知りたいと思っています。


1

私の通常のアプローチは

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

または別の言葉で

FK_ChildColumnName_ParentTableName_ParentColumnName

このようにhistory_info tablecolumn actionBy and actionTofromのように同じテーブルを参照する2つの外部キーに名前を付けることができますusers_info tableのます

のようになります

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

ご了承ください:

私には常識のように見えるので、子テーブル名は含めませんでした。私は子のテーブルにいるので、簡単に子のテーブル名を推測できます。その合計文字数は26で、 Charles Burnsがここのコメント述べたオラクルの30文字の制限によく適合します。

読者への注記:以下にリストするベストプラクティスの多くは、30文字の名前制限のため、Oracleでは機能しません。テーブル名または列名はすでに30文字に近い可能性があるため、2つを1つの名前に結合する規則では、切り捨ての標準またはその他のトリックが必要です。–チャールズ・バーンズ


3番目のテーブルのFKがParentTableName_ParentColumnNameと同じテーブルを指すFK_Nameが重複している場合、1つは失敗します
Tony Dong

0

ここでの回答とコメントに基づいて、FKテーブル、FKフィールド、およびPKテーブル(FK_FKTbl_FKCol_PKTbl)を含む命名規則は、FK制約名の衝突を回避する必要があります。

だから、ここに与えられたテーブルについて:

fk_task_userid_user
fk_note_userid_user

したがって、タスクまたはメモを最後に変更した人を追跡する列を追加すると...

fk_task_modifiedby_user
fk_note_modifiedby_user

-2

FKをそれほど頻繁に参照せず、MySQL(およびInnoDB)を使用している場合は、MySQLにFKを指定させるだけです。

後で、クエリを実行して必要なFK名を見つけることができます


4
私は自分の反対票しか説明できません。ほぼすべてのデータベースシステムで、システムが制約に名前を付けることができます。FK__123ee456ffがどのような関係にあるかを解読しようとして、100テーブルデータベースを使用して、本番の問題をさかのぼってすばやく理解しようとすることを想像できますか?それは明白で、単純に恐ろしい習慣を付けます。このFKでインデックスを作成すると、どうなりますか?システムもその名前ですか?それで、インデックスIX_007e373f5963が98%断片化されている場合、その理由を理解するためにどこを見ればよいのかをどのようにして知るのでしょうか。すべきではない。
SSISPissesMeOff 2016

-3

最初のオクテットを「-」(ダッシュ)の代わりにFKと「_」(アンダースコア)に置き換えて、大文字のバージョン4 UUIDを使用してみてください。

例えば

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

根拠は次のとおりです

  • 厳密な生成アルゴリズム=> 統一名 ;
  • キーの長さが30文字未満ですであり、これはOracleの名前の長さ制限です(12cより前)。
  • エンティティ名が変更された場合、FKの名前を変更する必要はありませんベースのアプローチのように(DBがテーブル名変更演算子をサポートしている場合)。
  • 外部キー制約の名前を使用することはめったにありません。たとえば、DBツールは通常、制約が適用される対象を示します。「解読」のためにそれを使用するのを避けることができるので、不可解な外観を恐れる必要はありません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.