Schema di denominazione della chiave esterna


153

Ho appena iniziato a lavorare con le chiavi esterne per la prima volta e mi chiedo se esiste uno schema di denominazione standard da utilizzare per loro?

Date queste tabelle:

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

Laddove le attività hanno note, le attività sono di proprietà degli utenti e le note degli autori degli utenti.

Come si chiamerebbero le tre chiavi esterne in questa situazione? Oppure, in alternativa, lo fa anche importa a tutti ?

Aggiornamento : questa domanda riguarda i nomi delle chiavi esterne, non i nomi dei campi!


6
Nota per i lettori: molte delle migliori pratiche elencate di seguito non funzionano in Oracle a causa del limite di 30 caratteri. Un nome di tabella o di colonna potrebbe essere già vicino a 30 caratteri, quindi una convenzione che combina i due in un singolo nome richiede uno standard di troncamento o altri trucchi.
Charles Burns,

Risposte:


180

La convenzione standard in SQL Server è:

FK_ForeignKeyTable_PrimaryKeyTable

Quindi, ad esempio, la chiave tra note e attività sarebbe:

FK_note_task

E la chiave tra attività e utenti sarebbe:

FK_task_user

Questo ti dà una visione 'a colpo d'occhio' di quali tabelle sono coinvolte nella chiave, quindi rende facile vedere da quali tabelle una particolare (la prima con nome) dipende (la seconda con nome). In questo scenario il set completo di chiavi sarebbe:

FK_task_user
FK_note_task
FK_note_user

Quindi puoi vedere che le attività dipendono dagli utenti e le note dipendono sia dalle attività che dagli utenti.


1
Se la chiave esterna punta a una chiave candidata nella seconda tabella anziché a una chiave primaria, probabilmente qualificheresti utilizzando un terzo segmento per il nome. È una situazione insolita in cui trovarsi, e non una in cui si dovrebbe progettare da zero, quindi non ho incluso questo nella risposta.
Greg Beech,

4
Includere il nome della tabella corrente nella chiave per mantenerlo distinto. I nomi FK si trovano nello spazio dei nomi globale in SQL Server, quindi non è possibile avere due FK denominati FK_PrimaryKeyTable collegati a due diverse tabelle di chiavi esterne. Le regole possono essere diverse per altri server di database.
Greg Beech,

Okay ... Ho spazi dei nomi diversi per ogni tabella in Oracle, quindi non ho bisogno del riferimento personale.
Steve Moyer,

29
Questo sembra essere l'uso comune ma cosa fanno le persone quando ci sono due chiavi esterne che puntano alla stessa tabella. cioè la messagetabella ha un from_user_ide to_user_identrambi diventerebbero fk_message_user. Mi sembra meglio usare fk_tablename_columnname(fk_message_from_user_id nel mio esempio) per questo motivo e quindi provare a mantenere chiari i nomi delle colonne sulla tabella di destinazione (ovvero to_user_id si riferisce chiaramente alla tabella degli utenti)
Codice comandante

cosa succede se entrambi la tabella stessa ha dei caratteri di sottolineatura per es. user_role e user_addresses? fk_user_addresses_user_role non è confuso?
Govi S

38

Uso due caratteri di sottolineatura come delimitatore, ad es

fk__ForeignKeyTable__PrimaryKeyTable 

Questo perché i nomi delle tabelle conterranno occasionalmente caratteri di sottolineatura stessi. Ciò segue la convenzione di denominazione per i vincoli in genere perché i nomi degli elementi di dati conterranno frequentemente caratteri di sottolineatura, ad es

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
Questa è assolutamente la risposta migliore.
Frederik Krautwald,

1
Ho appena creato Derby DB con una convenzione di denominazione molto specifica e questa qui è la più leggibile e tracciabile. Grazie
Anddo,

17

Che ne dici FK_TABLENAME_COLUMNNAME?

K eep I t S Imple S tupid quando possibile.


20
Perché quando hai un enorme db con molte chiavi e tabelle e ricevi un errore durante un aggiornamento dello schema nel tuo software, è piuttosto difficile trovare dove viene definita la chiave esterna senza fare una ricerca in uno script di creazione del database.
Giovanni

1
@JohnC se i nomi delle colonne FK hanno l'altro nome della tabella nel nome della colonna, non dovrebbe essere molto facile dirlo? Ti dice le due tabelle e il nome della colonna su cui è definito. Esempio: FK_Animals_OwnerIDtabella degli animali e dei proprietari, definita nella colonna OwnerID
David Sherret,

10

Una nota di Microsoft relativa a SQL Server:

Un vincolo FOREIGN KEY non deve essere collegato solo a un vincolo PRIMARY KEY in un'altra tabella; può anche essere definito per fare riferimento alle colonne di un vincolo UNIQUE in un'altra tabella.

quindi, userò i termini che descrivono la dipendenza anziché i termini convenzionali di relazione primaria / estera.

Quando si fa riferimento al PRIMARY KEY della tabella indipendente (padre) dalle colonne con nomi simili nella tabella dipendente (figlio) , ometto i nomi di colonna:

FK_ChildTable_ParentTable

Quando si fa riferimento ad altre colonne, oppure i nomi delle colonne variano tra le due tabelle, o solo per essere espliciti:

FK_ChildTable_childColumn_ParentTable_parentColumn

9

Di solito lascio solo il mio ID nome PK e quindi concateno il nome della mia tabella e il nome della colonna chiave quando assegno gli FK in altre tabelle. Non mi preoccupo mai dell'involucro del cammello, perché alcuni database scartano la distinzione tra maiuscole e minuscole e restituiscono comunque tutti i nomi in maiuscolo o minuscolo. In ogni caso, ecco come sarebbe la mia versione dei tuoi tavoli:

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

Nota che desidero anche nominare le mie tabelle al singolare, perché una riga rappresenta uno degli oggetti che sto persistendo. Molte di queste convenzioni sono preferenze personali. Suggerirei che è più importante scegliere una convenzione e usarla sempre, piuttosto che adottare la convenzione di qualcun altro.


eh - questo è lo stile esatto che sto effettivamente usando (ma con camelCase) - Ho pensato di aggiungere un po 'di descrizione in più ai nomi allo scopo di illustrare i loro collegamenti.
nickf

Quindi almeno possiamo leggere gli schemi degli altri;) ... ciò che è imbarazzante non è riuscire a leggere i tuoi dopo un paio d'anni di assenza. Usiamo ERWin per disegnare i nostri schemi, ma spesso è conveniente avere una versione testuale e avere una convenzione per trovare facilmente tabelle e campi.
Steve Moyer,

5

Questo è probabilmente un over-kill, ma funziona per me. Mi aiuta molto quando ho a che fare soprattutto con i VLDB. Io uso il seguente:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

Naturalmente se per qualche motivo non si fa riferimento a una chiave primaria, si deve fare riferimento a una colonna contenuta in un vincolo univoco, in questo caso:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

Può essere lungo, sì. Ha aiutato a mantenere chiare le informazioni per i rapporti, o mi ha fatto fare un salto veloce sul fatto che il potenziale problema è durante un avvertimento al 100% che piacerebbe conoscere i pensieri delle persone su questa convenzione di denominazione.


1

Il mio solito approccio è

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

O in altri termini

FK_ChildColumnName_ParentTableName_ParentColumnName

In questo modo posso nominare due chiavi esterne che fanno riferimento allo stesso tavolo come un history_info tablecon column actionBy and actionToda users_infotavolo

Sarà come

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

Nota che:

Non ho incluso il nome della tabella del bambino perché mi sembra di buon senso, sono nella tabella del bambino in modo da poter facilmente assumere il nome della tabella del bambino. Il personaggio totale è 26 e si adatta bene al limite dell'oracolo di 30 caratteri che è stato dichiarato da Charles Burns su un commento qui

Nota per i lettori: molte delle migliori pratiche elencate di seguito non funzionano in Oracle a causa del limite di 30 caratteri. Un nome di tabella o di colonna potrebbe essere già vicino a 30 caratteri, quindi una convenzione che combina i due in un singolo nome richiede uno standard di troncamento o altri trucchi. - Charles Burns


La tua non avrà esito positivo se hai la terza tabella con il punto FK su ParentTableName_ParentColumnName stessa tabella per duplicato FK_Name
Tony Dong

0

In base alle risposte e ai commenti qui, una convenzione di denominazione che include la tabella FK, il campo FK e la tabella PK (FK_FKTbl_FKCol_PKTbl) dovrebbe evitare le collisioni del nome del vincolo FK.

Quindi, per le tabelle fornite qui:

fk_task_userid_user
fk_note_userid_user

Quindi, se aggiungi una colonna per tenere traccia dell'ultima modifica di un'attività o una nota ...

fk_task_modifiedby_user
fk_note_modifiedby_user

-2

Se non fai riferimento a questi FK così spesso e stai usando MySQL (e InnoDB), allora puoi semplicemente lasciare che MySQL nomini l'FK per te.

In un secondo momento è possibile trovare il nome FK necessario eseguendo una query .


4
Posso solo spiegare il mio voto negativo. Quasi ogni sistema di database consente al sistema di nominare i vincoli, puoi immaginare di tornare indietro e provare a capire rapidamente durante un problema di produzione anche con un database di 100 tabelle, cercando di decifrare a quale relazione si riferisce FK__123ee456ff? È chiaro e semplicemente messo una pratica ORRIBILE. Quando costruisci un indice su questo FK, allora cosa? anche i nomi di sistema? quindi quando l'indice IX_007e373f5963 è frammentato al 98% come saprai dove cercare per capire perché? Non dovrebbe essere fatto.
SSISPissesMeOff

-3

Prova a usare l'UUID versione 4 maiuscolo con il primo ottetto sostituito da FK e '_' (trattino basso) invece di '-' (trattino).

Per esempio

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

La logica è la seguente

  • Algoritmo di generazione rigorosa => nomi uniformi ;
  • La lunghezza della chiave è inferiore a 30 caratteri , ovvero la limitazione della lunghezza dei nomi in Oracle (prima del 12c);
  • Se il nome dell'entità cambia , non è necessario rinominare l'FK come nell'approccio basato sul nome dell'entità (se DB supporta l'operatore di rinomina tabella);
  • Raramente si usa il nome del vincolo di chiave esterna. Ad esempio, lo strumento DB di solito mostra a cosa si applica il vincolo. Non c'è bisogno di aver paura dell'aspetto criptico, perché puoi evitare di usarlo per la "decodifica".
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.