Benennungsschema für Fremdschlüssel


152

Ich arbeite gerade zum ersten Mal mit Fremdschlüsseln und frage mich, ob es ein Standard-Namensschema für sie gibt.

Angesichts dieser Tabellen:

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

Wenn Aufgaben Notizen enthalten, gehören Aufgaben den Benutzern und Benutzer verfassen Notizen.

Wie würden die drei Fremdschlüssel in dieser Situation benannt? Oder spielt es überhaupt eine Rolle ?

Update : Bei dieser Frage geht es um Fremdschlüsselnamen, nicht um Feldnamen!


6
Hinweis für Leser: Viele der unten aufgeführten Best Practices funktionieren in Oracle aufgrund der Beschränkung auf 30 Zeichen nicht. Ein Tabellenname oder Spaltenname kann bereits fast 30 Zeichen enthalten. Daher erfordert eine Konvention, bei der beide zu einem einzigen Namen kombiniert werden, einen Kürzungsstandard oder andere Tricks.
Charles Burns

Antworten:


179

Die Standardkonvention in SQL Server lautet:

FK_ForeignKeyTable_PrimaryKeyTable

So wäre beispielsweise der Schlüssel zwischen Notizen und Aufgaben:

FK_note_task

Und der Schlüssel zwischen Aufgaben und Benutzern wäre:

FK_task_user

Auf diese Weise erhalten Sie auf einen Blick einen Überblick darüber, welche Tabellen am Schlüssel beteiligt sind. So können Sie leicht erkennen, von welchen Tabellen eine bestimmte (die erste benannte) (die zweite benannte) abhängt. In diesem Szenario wäre der vollständige Schlüsselsatz:

FK_task_user
FK_note_task
FK_note_user

So können Sie sehen, dass Aufgaben von Benutzern abhängen und Notizen sowohl von Aufgaben als auch von Benutzern abhängen.


1
Wenn der Fremdschlüssel auf einen Kandidatenschlüssel in der zweiten Tabelle und nicht auf einen Primärschlüssel verweist, würden Sie wahrscheinlich ein drittes Segment für den Namen verwenden, um dies zu qualifizieren. Es ist eine ungewöhnliche Situation, in der man sich normalerweise nicht von Grund auf neu entwickelt, daher habe ich dies nicht in die Antwort aufgenommen.
Greg Beech

4
Sie geben den aktuellen Tabellennamen in den Schlüssel ein, um ihn eindeutig zu halten. FK-Namen befinden sich in SQL Server im globalen Namespace, sodass Sie nicht zwei FKs mit dem Namen FK_PrimaryKeyTable an zwei verschiedene Fremdschlüsseltabellen anhängen können. Die Regeln können für andere Datenbankserver unterschiedlich sein.
Greg Beech

Okay ... Ich habe unterschiedliche Namespaces für jede Tabelle in Oracle, daher benötige ich keine Selbstreferenz.
Steve Moyer

29
Dies scheint die übliche Verwendung zu sein, aber was tun Menschen, wenn zwei Fremdschlüssel auf dieselbe Tabelle verweisen? dh messageTisch hat ein from_user_idund to_user_idbeide würden werden fk_message_user. Es scheint mir fk_tablename_columnnameaus diesem Grund besser zu sein, (fk_message_from_user_id in meinem Beispiel) zu verwenden und dann zu versuchen, Ihre Spaltennamen über die Zieltabelle klar zu halten (dh to_user_id bezieht sich eindeutig auf die Benutzertabelle)
Code Commander

Was ist, wenn beide Tabellen selbst Unterstriche haben, zum Beispiel. Benutzerrolle und Benutzeradressen? fk_user_addresses_user_role ist das nicht verwirrend?
Govi S

38

Ich benutze zwei Unterstriche als Trennzeichen, dh

fk__ForeignKeyTable__PrimaryKeyTable 

Dies liegt daran, dass Tabellennamen gelegentlich selbst Unterstriche enthalten. Dies folgt im Allgemeinen der Namenskonvention für Einschränkungen, da die Namen von Datenelementen häufig Unterstriche enthalten, z

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
Dies ist absolut die beste Antwort.
Frederik Krautwald

1
Ich habe gerade Derby DB mit einer sehr spezifischen Namenskonvention erstellt, und diese hier ist am besten lesbar und nachvollziehbar. Vielen Dank
Anddo

17

Wie wäre es FK_TABLENAME_COLUMNNAME?

K eep I t S imple S tupid wann immer möglich.


20
Denn wenn Sie eine riesige Datenbank mit vielen Schlüsseln und Tabellen haben und während eines Schema-Updates in Ihrer Software eine Fehlermeldung erhalten, ist es ziemlich schwierig zu finden, wo der Fremdschlüssel überhaupt definiert ist, ohne ein Datenbank-Erstellungsskript zu durchsuchen.
JohnC

1
@JohnC Wenn die FK-Spaltennamen den anderen Tabellennamen im Spaltennamen haben, sollte es dann nicht sehr einfach zu sagen sein? Es zeigt Ihnen die beiden Tabellen und den Spaltennamen, für den es definiert ist. Beispiel: FK_Animals_OwnerID- Tabelle mit Tieren und Besitzern, definiert in der Spalte OwnerID
David Sherret

10

Ein Hinweis von Microsoft zu SQL Server:

Eine FOREIGN KEY-Einschränkung muss nicht nur mit einer PRIMARY KEY-Einschränkung in einer anderen Tabelle verknüpft sein. Es kann auch definiert werden, um auf die Spalten einer UNIQUE-Einschränkung in einer anderen Tabelle zu verweisen.

Daher verwende ich Begriffe, die die Abhängigkeit beschreiben, anstelle der herkömmlichen Begriffe für primäre / fremde Beziehungen.

Wenn ich auf den PRIMARY KEY der unabhängigen (übergeordneten) Tabelle durch die ähnlich benannten Spalten in der abhängigen (untergeordneten) Tabelle verweise, lasse ich die Spaltennamen weg:

FK_ChildTable_ParentTable

Wenn Sie auf andere Spalten verweisen oder die Spaltennamen zwischen den beiden Tabellen variieren oder nur um explizit zu sein:

FK_ChildTable_childColumn_ParentTable_parentColumn

9

Normalerweise lasse ich einfach meine PK mit dem Namen id und verkette dann meinen Tabellennamen und den Namen der Schlüsselspalte, wenn ich FKs in anderen Tabellen benenne. Ich kümmere mich nie um Kamelhüllen, da einige Datenbanken die Groß- und Kleinschreibung verwerfen und trotzdem einfach alle Groß- oder Kleinbuchstaben zurückgeben. In jedem Fall würde meine Version Ihrer Tabellen folgendermaßen aussehen:

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

Beachten Sie, dass ich meine Tabellen auch im Singular benenne, da eine Zeile eines der Objekte darstellt, die ich beibehalten habe. Viele dieser Konventionen sind persönliche Vorlieben. Ich würde vorschlagen, dass es wichtiger ist, eine Konvention zu wählen und sie immer zu verwenden, als die Konvention eines anderen zu übernehmen.


heh - das ist genau der Stil, den ich tatsächlich benutze (aber mit camelCase) - Ich dachte, ich würde den Namen eine zusätzliche Beschreibung hinzufügen, um ihre Verknüpfungen zu veranschaulichen.
Nickf

Zumindest können wir die Schemata des anderen lesen;) ... was peinlich ist, ist, dass wir nach ein paar Jahren Abwesenheit nicht in der Lage sind, Ihre eigenen zu lesen. Wir verwenden ERWin, um unsere Schemata grafisch darzustellen, aber es ist oft praktisch, eine Textversion und eine Konvention zu haben, mit der Sie Tabellen und Felder leicht finden können.
Steve Moyer

5

Dies ist wahrscheinlich übertrieben, aber es funktioniert für mich. Es hilft mir sehr, wenn ich mich besonders mit VLDBs beschäftige. Ich benutze folgendes:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

Wenn Sie aus irgendeinem Grund nicht auf einen Primärschlüssel verweisen, müssen Sie natürlich auf eine Spalte verweisen, die in einer eindeutigen Einschränkung enthalten ist. In diesem Fall:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

Kann es lange dauern, ja. Hat es mir geholfen, Informationen für Berichte klar zu halten, oder hat es mir einen schnellen Einblick gegeben, dass das potenzielle Problem während eines Produktalarms besteht? 100% würden gerne die Gedanken der Menschen über diese Namenskonvention erfahren.


1

Mein üblicher Ansatz ist

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

Oder anders ausgedrückt

FK_ChildColumnName_ParentTableName_ParentColumnName

Auf diese Weise kann ich zwei Fremdschlüssel benennen, die auf dieselbe Tabelle verweisen wie eine history_info tablewith column actionBy and actionTofrom- users_infoTabelle

Es wird so sein

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

Beachten Sie, dass:

Ich habe den Namen der untergeordneten Tabelle nicht angegeben, da es mir vernünftig erscheint. Ich bin in der Tabelle des Kindes, sodass ich den Tabellennamen des Kindes leicht annehmen kann. Der Gesamtcharakter ist 26 und passt gut zu der 30-Zeichen-Grenze von Orakel, die Charles Burns in einem Kommentar hier angegeben hat

Hinweis für Leser: Viele der unten aufgeführten Best Practices funktionieren in Oracle aufgrund der Beschränkung auf 30 Zeichen nicht. Ein Tabellenname oder Spaltenname kann bereits fast 30 Zeichen enthalten. Daher erfordert eine Konvention, bei der beide zu einem einzigen Namen kombiniert werden, einen Kürzungsstandard oder andere Tricks. - Charles Burns


Ihre wird fehlschlagen, wenn Sie 3. Tabelle haben den FK-Punkt auf ParentTableName_ParentColumnName gleiche Tabelle durch Duplikat FK_Name
Tony Dong

0

Basierend auf den Antworten und Kommentaren hier sollte eine Namenskonvention, die die FK-Tabelle, das FK-Feld und die PK-Tabelle (FK_FKTbl_FKCol_PKTbl) enthält, Kollisionen von FK-Einschränkungsnamen vermeiden.

Also, für die angegebenen Tabellen hier:

fk_task_userid_user
fk_note_userid_user

Wenn Sie also eine Spalte hinzufügen, um zu verfolgen, wer zuletzt eine Aufgabe oder eine Notiz geändert hat ...

fk_task_modifiedby_user
fk_note_modifiedby_user

-2

Wenn Sie nicht so oft auf Ihre FKs verweisen und MySQL (und InnoDB) verwenden, können Sie MySQL einfach die FK für Sie benennen lassen.

Zu einem späteren Zeitpunkt können Sie den gewünschten FK-Namen finden, indem Sie eine Abfrage ausführen .


4
Ich kann nur meine Ablehnung erklären. Nahezu jedes Datenbanksystem ermöglicht es dem System, Einschränkungen zu benennen. Können Sie sich vorstellen, während eines Produktionsproblems mit einer Datenbank mit 100 Tabellen sogar schnell herauszufinden, welche Beziehung FK__123ee456ff hat? Es ist klar und einfach eine schreckliche Praxis. Wenn Sie einen Index für diese FK erstellen, was dann? Systemnamen das auch? Wenn der Index IX_007e373f5963 zu 98% fragmentiert ist, woher wissen Sie dann, wo Sie suchen müssen, um herauszufinden, warum? Es sollte einfach nicht gemacht werden.
SSISPissesMeOff

-3

Versuchen Sie, die UUID der Version 4 in Großbuchstaben zu verwenden, wobei das erste Oktett durch FK und '_' (Unterstrich) anstelle von '-' (Bindestrich) ersetzt wird.

Z.B

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

Begründung ist die folgende

  • Strenger Generierungsalgorithmus => einheitliche Namen ;
  • Die Schlüssellänge beträgt weniger als 30 Zeichen . Dies bedeutet eine Beschränkung der Namenslänge in Oracle (vor 12c).
  • Wenn sich Ihr Entitätsname ändert, müssen Sie Ihre FK nicht umbenennen wie bei einem auf Entitätsnamen basierenden Ansatz umbenennen (wenn DB den Operator zum Umbenennen von Tabellen unterstützt).
  • Man würde selten den Namen der Fremdschlüsseleinschränkung verwenden. Beispielsweise zeigt das DB-Tool normalerweise an, wofür die Einschränkung gilt. Sie müssen keine Angst vor einem kryptischen Aussehen haben, da Sie vermeiden können, es für die "Entschlüsselung" zu verwenden.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.