Qual è una convenzione di denominazione corretta per MySQL FK?


Risposte:


141

In MySQL, non è necessario dare un nome simbolico ai vincoli di chiave esterna. Se non viene fornito un nome, InnoDB crea automaticamente un nome univoco.

In ogni caso, questa è la convenzione che utilizzo:

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

Esempio:

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);

Cerco di restare con gli stessi nomi di campo nelle tabelle di riferimento e referenziate, come nell'esempio user_idsopra. Quando ciò non è pratico, aggiungo anche il nome del campo di riferimento al nome della chiave esterna.

Questa convenzione di denominazione mi permette di "indovinare" il nome simbolico semplicemente guardando le definizioni della tabella, e inoltre garantisce anche nomi univoci.


13
Il motivo per creare un nome simbolico è fare riferimento quando si desidera / è necessario eliminare il vincolo. Oracle e SQL Server consentono di disabilitare vincoli specifici. Se non hai fk nel nome, devi confermare che il vincolo è un vincolo di chiave esterna ...
OMG Ponies

11
Quello che mi piace fare è usare un doppio trattino basso tra il nome della tabella di riferimento e il nome della tabella di riferimento. Ciò offre i doppi vantaggi degli elenchi alfabetici che mantengono insieme tutti gli FK di una tabella e allo stesso tempo ti aiuta a evitare conflitti / confusione di nomi quando ci sono più nomi di tabelle di parole. Ometto anche la parte del campo del nome quando è banale (cioè un singolo campo int fa riferimento all'identità PK di un'altra tabella).
Joel Brown

2
Cosa succede se ci sono più di 1 chiave esterna? Esempio: member_id~> collegamento al membro della tabella, edited_id~> chiave esterna per l'utente modificato, collegamento anche al membro della tabella. Come dovrei chiamarli?
TomSawyer

@TomSawyer: aggiungo "pk_" a tutte le chiavi esterne, seguito dalla tabella referenziata (es. "Membri"), seguito dall'uso / senso (es. "Editor" o "autore"). Quindi ho qualcosa come "pk_members_author" o "pk_members_editor".
Nrgyzer

28

la mia scelta è diversa. secondo me, una tabella dovrebbe avere un idcampo, non user_iduno, perché la tabella si chiama solo user, quindi:

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

CREATE TABLE messages(
   id int,
   user_id    int
);

user_idin messagestable è un campo fk quindi deve chiarire quale id è ( user_id).

una convenzione di denominazione completamente autoesplicativa, a mio parere, potrebbe essere:

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

i.e.: `fk_messages_user_id_users_id`

Nota:

  • puoi, in alcuni casi, omettere il secondo elemento ([referencing field name])
  • questo fk potrebbe essere unico, perché se messages_useresiste una tabella, il nome del campo di riferimento dovrebbe essere user_id(e non solo id) e il nome fk dovrebbe essere:

    fk_messages_user_user_id_users_id

in altre parole, una convenzione di denominazione di chiavi esterne ti assicura di avere nomi univoci se usi anche una convenzione di denominazione di "campo di riferimento / riferimento" (e puoi sceglierne una tua, ovviamente).


4
I nomi hanno un modo per persistere nel codice. Alla fine, troverai una $idvariabile da qualche parte senza idea a quale tabella appartenga. Più vecchia è la tua base di codice e più persone ci hanno lavorato, più è probabile che ciò diventi.
CJ Dennis

9

Se non ti ritrovi a fare riferimento a fk così spesso dopo che sono stati creati, un'opzione è di mantenerlo semplice e lasciare che MySQL faccia il nome per te (come menziona Daniel Vassallo all'inizio della sua risposta ).

Sebbene non sarai in grado di "indovinare" in modo univoco i nomi dei vincoli con questo metodo, puoi facilmente trovare il nome del vincolo di chiave esterna eseguendo una query:

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;

Ad esempio potresti ricevere quanto segue dalla query:

+------------+-------------+-----------------+-----------------------+------------------------+
| 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                     |
+------------+-------------+-----------------+-----------------------+------------------------+

Se questo passaggio extra non è troppo per te, dovresti essere in grado di trovare facilmente l'fk che stai cercando.


1
fk-[referencing_table]-[referencing_field]

Il motivo è la combinazione di referencing_tableed referencing_fieldè unico in un database. In questo modo è facile leggere il nome della chiave esterna, ad esempio:

table `user`:
    id
    name
    role

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

Quindi abbiamo due chiavi esterne:

fk-article-created_user_id
fk-article-reviewed_user_id

L'aggiunta del usernome della tabella al nome della chiave esterna è ridondante.


E se il nome del database è user_role? usere rolehanno molte relazioni ed user_roleè la tabella che contiene tutta la chiave esterna. Dovrebbe essere fk_user_role_role?
Nguyễn Đức Tâm

@ NguyễnĐứcTâm fk-user_role-role
Văn Quyết
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.