Schemat nazewnictwa kluczy obcych


152

Właśnie zaczynam pracę z kluczami obcymi po raz pierwszy i zastanawiam się, czy istnieje standardowy schemat nazewnictwa, którego mogę użyć?

Biorąc pod uwagę te tabele:

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

Tam, gdzie zadania mają notatki, zadania są własnością użytkowników, a użytkownicy - notatki autora.

Jak w tej sytuacji zostałyby nazwane trzy klucze obce? A może to w ogóle ma znaczenie ?

Aktualizacja : To pytanie dotyczy nazw kluczy obcych, a nie nazw pól!


6
Uwaga dla czytelników: wiele z najlepszych praktyk wymienionych poniżej nie działa w Oracle z powodu limitu 30 znaków. Nazwa tabeli lub nazwa kolumny może już mieć blisko 30 znaków, więc konwencja łączenia tych dwóch w jedną nazwę wymaga standardu obcinania lub innych sztuczek.
Charles Burns

Odpowiedzi:


179

Standardowa konwencja w SQL Server to:

FK_ForeignKeyTable_PrimaryKeyTable

Na przykład kluczem między notatkami a zadaniami byłoby:

FK_note_task

A kluczem między zadaniami a użytkownikami byłoby:

FK_task_user

Daje to „na pierwszy rzut oka” widok, które tabele są zaangażowane w klucz, dzięki czemu można łatwo sprawdzić, od których tabel zależy konkretna (pierwsza nazwana) (druga nazwana). W tym scenariuszu pełny zestaw kluczy wyglądałby następująco:

FK_task_user
FK_note_task
FK_note_user

Możesz więc zobaczyć, że zadania zależą od użytkowników, a notatki zależą zarówno od zadań, jak i od użytkowników.


1
Jeśli klucz obcy wskazuje na klucz kandydujący w drugiej tabeli, a nie na klucz podstawowy, prawdopodobnie użyłbyś trzeciego segmentu do nazwy, aby to zakwalifikować. To niezwykła sytuacja i nie taka, w której zwykle projektuje się od zera, więc nie uwzględniłem tego w odpowiedzi.
Greg Beech,

4
W kluczu umieszczasz nazwę bieżącej tabeli, aby była inna. Nazwy FK znajdują się w globalnej przestrzeni nazw w SQL Server, więc nie można mieć dwóch FK o nazwie FK_PrimaryKeyTable dołączonych do dwóch różnych tabel kluczy obcych. Reguły mogą być inne dla innych serwerów baz danych.
Greg Beech,

OK ... Mam różne przestrzenie nazw dla każdej tabeli w Oracle, więc nie potrzebuję odwołania do siebie.
Steve Moyer,

29
Wydaje się, że jest to powszechne zastosowanie, ale co ludzie robią, gdy istnieją dwa klucze obce wskazujące na tę samą tabelę. tzn. messagetabela ma from_user_idi to_user_idoba staną się fk_message_user. Wydaje mi się, że lepiej jest użyć fk_tablename_columnname(fk_message_from_user_id w moim przykładzie) z tego powodu, a następnie starać się, aby nazwy kolumn były jasne co do tabeli docelowej (tj. To_user_id wyraźnie odnosi się do tabeli użytkowników)
Code Commander,

co by było, gdyby zarówno sama tabela miała podkreślenia np. user_role i user_addresses? fk_user_addresses_user_role czy to nie jest mylące?
Govi S

38

Używam dwóch znaków podkreślenia jako separatora, tj

fk__ForeignKeyTable__PrimaryKeyTable 

Dzieje się tak, ponieważ nazwy tabel czasami zawierają same znaki podkreślenia. Jest to zgodne z konwencją nazewnictwa ograniczeń, ponieważ nazwy elementów danych często zawierają znaki podkreślenia, np

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
To jest absolutnie najlepsza odpowiedź.
Frederik Krautwald

1
Właśnie stworzyłem Derby DB z bardzo specyficzną konwencją nazewnictwa, a ta tutaj jest najbardziej czytelna i identyfikowalna. Dziękuję
Anddo

17

A co powiesz FK_TABLENAME_COLUMNNAME?

K EEP I T S wyko S tupid miarę możliwości.


20
Ponieważ gdy masz ogromną bazę danych z wieloma kluczami i tabelami i otrzymujesz błąd podczas aktualizacji schematu w swoim oprogramowaniu, dość trudno jest znaleźć, gdzie jest zdefiniowany klucz obcy bez przeszukiwania bazy danych skryptu tworzenia.
JohnC,

1
@JohnC, jeśli nazwy kolumn FK mają inną nazwę tabeli w nazwie kolumny, czy nie powinno być łatwo to stwierdzić? Informuje o dwóch tabelach i nazwie kolumny, w której jest zdefiniowana. Np .: FK_Animals_OwnerID—Tabela Zwierzęta i Właściciele zdefiniowana w kolumnie ID właściciela
David Sherret

10

Uwaga od Microsoft dotycząca SQL Server:

Ograniczenie FOREIGN KEY nie musi być połączone tylko z ograniczeniem PRIMARY KEY w innej tabeli; można go również zdefiniować jako odniesienie do kolumn ograniczenia UNIQUE w innej tabeli.

dlatego użyję terminów opisujących zależność zamiast konwencjonalnych terminów relacji pierwotnych / obcych.

Odwołując się do KLUCZA PODSTAWOWEGO niezależnej (nadrzędnej) tabeli przez podobnie nazwane kolumny w tabeli zależnej (podrzędnej) , pomijam nazwy kolumn:

FK_ChildTable_ParentTable

W przypadku odwoływania się do innych kolumn lub nazwy kolumn różnią się między dwiema tabelami lub po prostu mają być wyraźne:

FK_ChildTable_childColumn_ParentTable_parentColumn

9

Zwykle po prostu zostawiam swój PK o nazwie id, a następnie łączę nazwę mojej tabeli i nazwę kolumny klucza podczas nadawania nazw FK w innych tabelach. Nigdy nie zawracam sobie głowy pisaniem wielbłądów, ponieważ niektóre bazy danych odrzucają rozróżnianie wielkości liter i po prostu zwracają wszystkie nazwy wielkich lub małych liter. W każdym razie oto jak wyglądałaby moja wersja twoich tabel:

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

Zwróć uwagę, że moje tabele również nazywam w liczbie pojedynczej, ponieważ wiersz reprezentuje jeden z obiektów, które utrwalam. Wiele z tych konwencji to osobiste preferencje. Sugerowałbym, że ważniejsze jest, aby wybrać konwencję i zawsze z niej korzystać, niż przyjąć konwencję kogoś innego.


heh - to jest dokładnie ten styl, którego aktualnie używam (ale z camelCase) - pomyślałem, że dodam trochę dodatkowego opisu do nazw w celu zilustrowania ich powiązań.
nickf

Więc przynajmniej możemy czytać nawzajem schematy;) ... co jest żenujące, to nieumiejętność czytania własnego po kilku latach nieobecności. Używamy ERWin do tworzenia diagramów naszych schematów, ale często wygodnie jest mieć wersję tekstową, a konwencja pozwala łatwo znaleźć tabele i pola.
Steve Moyer,

5

To prawdopodobnie przesada, ale w moim przypadku działa. Bardzo mi to pomaga, zwłaszcza gdy mam do czynienia z VLDB. Używam następujących:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

Oczywiście, jeśli z jakiegoś powodu nie odwołujesz się do klucza podstawowego, musisz odwołać się do kolumny zawartej w unikalnym ograniczeniu, w tym przypadku:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

Czy to może być długie, tak. Czy pomogło to w utrzymaniu jasnych informacji na potrzeby raportów, czy też pozwoliło mi szybko stwierdzić, że potencjalny problem występuje podczas ostrzeżenia o produkcie. 100% chciałoby poznać opinie ludzi na temat tej konwencji nazewnictwa.


1

Moje zwykłe podejście jest takie

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

Lub innymi słowy

FK_ChildColumnName_ParentTableName_ParentColumnName

W ten sposób mogę nazwać dwa klucze obce, które odwołują się do tej samej tabeli, jak history_info tablez column actionBy and actionTofromusers_info table

To będzie jak

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

Zauważ, że:

Nie podałem nazwy stołu podrzędnego, ponieważ wydaje mi się to rozsądne, jestem w stole dziecka, więc mogę łatwo przyjąć nazwę stołu dziecka. Całkowity charakter to 26 i dobrze pasuje do 30-znakowego limitu wyroczni, który został określony przez Charlesa Burnsa w komentarzu tutaj

Uwaga dla czytelników: wiele z najlepszych praktyk wymienionych poniżej nie działa w Oracle ze względu na limit 30 znaków. Nazwa tabeli lub nazwa kolumny może już mieć blisko 30 znaków, więc konwencja łączenia tych dwóch w jedną nazwę wymaga standardu obcinania lub innych sztuczek. - Charles Burns


Twój jeden nie powiedzie się, jeśli masz trzeci stół, który ma punkt FK do ParentTableName_ParentColumnName, ta sama tabela przez duplikat FK_Name
Tony Dong

0

W oparciu o odpowiedzi i komentarze tutaj, konwencja nazewnictwa, która obejmuje tabelę FK, pole FK i tabelę PK (FK_FKTbl_FKCol_PKTbl), powinna unikać kolizji nazw ograniczeń FK.

Tak więc dla podanych tutaj tabel:

fk_task_userid_user
fk_note_userid_user

Jeśli więc dodasz kolumnę, aby śledzić, kto ostatnio modyfikował zadanie lub notatkę ...

fk_task_modifiedby_user
fk_note_modifiedby_user

-2

Jeśli nie odwołujesz się do swoich FK tak często i nie używasz MySQL (i InnoDB), możesz po prostu pozwolić MySQL nazwać FK za Ciebie.

Później możesz znaleźć potrzebną nazwę FK, uruchamiając zapytanie .


4
Mogę tylko wyjaśnić mój głos negatywny. Prawie każdy system bazy danych umożliwia systemowi nazywanie ograniczeń. Czy możesz sobie wyobrazić powrót i próbę szybkiego rozwiązania problemu podczas produkcji nawet w 100-tabelowej bazie danych, próbując rozszyfrować, do jakiej relacji odnosi się FK__123ee456ff? Jest to proste i po prostu przedstawia STRASZNĄ praktykę. Kiedy budujesz indeks na tym FK, co wtedy? nazwy systemów, które też? więc kiedy indeks IX_007e373f5963 jest w 98% pofragmentowany, skąd będziesz wiedzieć, gdzie szukać, aby dowiedzieć się, dlaczego? Po prostu nie powinno się tego robić.
SSISPissesMeOff

-3

Spróbuj użyć dużych liter UUID wersji 4 z pierwszym oktetem zastąpionym przez FK i „_” (podkreślenie) zamiast „-” (myślnik).

Na przykład

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

Uzasadnienie jest następujące

  • Algorytm ścisłej generacji => jednolite nazwy ;
  • Długość klucza jest mniejsza niż 30 znaków , co stanowi ograniczenie długości nazw w Oracle (przed 12c);
  • Jeśli nazwa jednostki ulegnie zmianie, nie musisz zmieniać nazwy swojego FK, jak w podejściu opartym na nazwie jednostki (jeśli DB obsługuje operatora zmiany nazwy tabeli);
  • Rzadko można by użyć nazwy ograniczenia klucza obcego. Np. Narzędzie DB zwykle pokazuje, czego dotyczy ograniczenie. Nie musisz bać się tajemniczego wyglądu, ponieważ możesz uniknąć używania go do „deszyfrowania”.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.