Was ist eine richtige Namenskonvention für MySQL-FKs?

Antworten:

141

In MySQL müssen Fremdschlüsseleinschränkungen nicht symbolisch benannt werden. Wenn kein Name angegeben wird, erstellt InnoDB automatisch einen eindeutigen Namen.

In jedem Fall ist dies die Konvention, die ich verwende:

fk_[referencing table name]_[referenced table name]_[referencing field name]

Beispiel:

CREATE TABLE users(
    user_id    int,
    name       varchar(100)
);

CREATE TABLE messages(
    message_id int,
    user_id    int
);

ALTER TABLE messages ADD CONSTRAINT fk_messages_users_user_id 
    FOREIGN KEY (user_id) REFERENCES users(user_id);

Ich versuche, bei referenzierenden und referenzierten Tabellen dieselben Feldnamen zu verwenden wie in user_id obigen Beispiel. Wenn dies nicht praktikabel ist, hänge ich auch den referenzierten Feldnamen an den Fremdschlüsselnamen an.

Diese Namenskonvention ermöglicht es mir, den symbolischen Namen nur anhand der Tabellendefinitionen zu "erraten", und garantiert außerdem eindeutige Namen.

Daniel Vassallo
quelle
13
Der Grund für das Erstellen eines symbolischen Namens liegt in der Referenzierung, wenn Sie die Einschränkung löschen möchten / müssen. Mit Oracle & SQL Server können Sie bestimmte Einschränkungen deaktivieren. Wenn Sie nicht fk im Namen haben, müssen Sie bestätigen, dass die Einschränkung eine Fremdschlüsseleinschränkung ist ...
OMG Ponies
11
Ich verwende gerne einen doppelten Unterstrich zwischen dem Namen der referenzierenden Tabelle und dem Namen der referenzierten Tabelle. Dies bietet Ihnen die doppelten Vorteile von alphabetischen Auflistungen, die alle FKs einer Tabelle zusammenhalten, und hilft Ihnen gleichzeitig, Namenskollisionen / -verwechslungen zu vermeiden, wenn mehrere Worttabellennamen vorhanden sind. Ich lasse auch den Feldteil des Namens weg, wenn er trivial ist (dh ein einzelnes int-Feld verweist auf die Identität PK einer anderen Tabelle).
Joel Brown
2
Was ist, wenn mehr als ein Fremdschlüssel vorhanden ist? Beispiel: member_id~> Link zum Tabellenelement, edited_id~> Fremdschlüssel für bearbeiteten Benutzer, auch Link zum Tabellenmitglied. Wie soll ich sie benennen?
TomSawyer
@ TomSawyer: Ich füge allen Fremdschlüsseln 'pk_' hinzu, gefolgt von der Tabelle, auf die verwiesen wird (z. B. 'Mitglieder'), gefolgt von der Verwendung / dem Sinn (z. B. 'Editor' oder 'Autor'). Ich habe also so etwas wie 'pk_members_author' oder 'pk_members_editor'.
Nrgyzer
28

Meine Wahl ist anders. Meiner Meinung nach sollte eine Tabelle ein idFeld haben, kein user_ideinziges, da die Tabelle nur aufgerufen userwird.

CREATE TABLE users(
   id    int,
   name       varchar(100)
);

CREATE TABLE messages(
   id int,
   user_id    int
);

user_idIn der messagesTabelle befindet sich ein fk-Feld, daher muss klargestellt werden, welche ID ( user_id) ist.

Eine vollständig selbsterklärende Namenskonvention könnte meiner Meinung nach sein:

fk_[referencing table name]_[referencing field name]_[referenced table name]_[referenced field name]

i.e.: `fk_messages_user_id_users_id`

Hinweis:

  • In einigen Fällen können Sie das zweite Element weglassen ([Name des Referenzfelds]).
  • Diese fk könnte eindeutig sein, denn wenn eine messages_userTabelle existiert, sollte der Name des referenzierenden Feldes user_id(und nicht nur id) und der fk-Name sein:

    fk_messages_user_user_id_users_id

Mit anderen Worten, eine Fremdschlüssel-Namenskonvention stellt sicher, dass Sie eindeutige Namen haben, wenn Sie auch eine Namenskonvention "Referenzieren / referenziertes Feld" verwenden (und Sie können natürlich Ihre eigene auswählen).

Lorenzo
quelle
4
Namen können über Code hinweg bestehen bleiben. Schließlich finden Sie $idirgendwo eine Variable, die keine Ahnung hat, zu welcher Tabelle sie gehört. Je älter Ihre Codebasis ist und je mehr Leute daran gearbeitet haben, desto wahrscheinlicher wird dies.
CJ Dennis
9

Wenn Sie nicht so oft auf fk verweisen, nachdem sie erstellt wurden, besteht eine Möglichkeit darin, sie einfach zu halten und MySQL die Benennung für Sie vornehmen zu lassen (wie Daniel Vassallo am Anfang seiner Antwort erwähnt ).

Während Sie mit dieser Methode die Einschränkungsnamen nicht eindeutig "erraten" können, können Sie den Fremdschlüssel-Einschränkungsnamen leicht finden, indem Sie eine Abfrage ausführen:

use information_schema;
select TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME from KEY_COLUMN_USAGE where REFERENCED_TABLE_SCHEMA = 'your_db_schema_name' ORDER BY TABLE_NAME;

Beispielsweise erhalten Sie möglicherweise Folgendes von der Abfrage:

+------------+-------------+-----------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+------------+-------------+-----------------+-----------------------+------------------------+
| note       | taskid      | note_ibfk_2     | task                  | id                     |
| note       | userid      | note_ibfk_1     | user                  | id                     |
| task       | userid      | task_ibfk_1     | user                  | id                     |
+------------+-------------+-----------------+-----------------------+------------------------+

Wenn Ihnen dieser zusätzliche Schritt nicht zu viel ist, sollten Sie in der Lage sein, das gesuchte fk leicht zu finden.

user12345
quelle
1
fk-[referencing_table]-[referencing_field]

Der Grund ist die Kombination von referencing_tableund referencing_fieldist in einer Datenbank eindeutig. Auf diese Weise ist der Name des Fremdschlüssels leicht zu lesen, zum Beispiel:

table `user`:
    id
    name
    role

table `article`:
    id
    content
    created_user_id /* --> user.id */
    reviewed_user_id /* --> user.id */

Wir haben also zwei Fremdschlüssel:

fk-article-created_user_id
fk-article-reviewed_user_id

Das Hinzufügen eines userTabellennamens zum Fremdschlüsselnamen ist redundant.

Văn Quyết
quelle
Was ist, wenn der Datenbankname lautet user_role? userund rolehaben viele Beziehungen und user_roleist die Tabelle, die alle Fremdschlüssel enthält. Sollte es sein fk_user_role_role?
Nguyễn Đức Tâm
@ NguyễnĐứcTâm fk-user_role-role
Văn Quyết