Zastanawiałem się nad opiniami ludzi na temat nazewnictwa kolumn ID w tabelach bazy danych.
Jeśli mam tabelę o nazwie Faktury z kluczem podstawowym kolumny tożsamości, nazwałbym tę kolumnę InvoiceID, aby nie powodować konfliktów z innymi tabelami i jest oczywiste, co to jest.
Tam, gdzie jestem obecny, nazwali wszystkie kolumny ID.
Więc zrobiliby co następuje:
Select
i.ID
, il.ID
From
Invoices i
Left Join InvoiceLines il
on i.ID = il.InvoiceID
Teraz widzę tutaj kilka problemów:
1. Musiałbyś
aliasować kolumny na zaznaczeniu 2. ID = InvoiceID nie mieści się w moim mózgu
3. Jeśli nie aliasowałeś tabel i odnosiłeś się do InvoiceID to jest oczywiste, która tabela to jest włączone?
Jakie są opinie innych ludzi na ten temat?
sql
naming-conventions
Arry
źródło
źródło
Odpowiedzi:
ID to Antypattern SQL. Zobacz http://www.amazon.com/s/ref=nb_sb_ss_i_1_5?url=search-alias%3Dstripbooks&field-keywords=sql+antipatterns&sprefix=sql+a
Jeśli masz wiele tabel z identyfikatorem jako identyfikatorem, znacznie utrudniasz raportowanie. Zasłania to znaczenie i utrudnia odczytanie złożonych zapytań, a także wymaga używania aliasów w celu rozróżnienia samego raportu.
Ponadto, jeśli ktoś jest na tyle głupi, by użyć sprzężenia naturalnego w bazie danych, w której są one dostępne, dołączysz do niewłaściwych rekordów.
Jeśli chciałbyś użyć składni USING, na którą pozwalają niektóre bazy danych, nie możesz użyć ID.
Jeśli używasz ID, możesz łatwo skończyć z błędnym złączeniem, jeśli zdarzy ci się skopiować składnię złączenia (nie mów mi, że nikt tego nigdy nie robi!) I zapomnieć o zmianie aliasu w warunku złączenia.
Więc teraz masz
kiedy miałeś na myśli
Jeśli użyjesz tablenameID jako pola id, ten rodzaj przypadkowego błędu jest znacznie mniej prawdopodobny i znacznie łatwiejszy do znalezienia.
źródło
join table2 on table1.table1id = table2.table1id
. Twoje rozumowanie jest w porządku, z wyjątkiem tego, że jeśli używasz id, i tak nazwa tabeli jest przed identyfikatorem.join table2 on table1.id = table2.table1id
... co jest równie rozwlekłe i niepotrzebne, ani wymusza niejasne aliasy, aby zapobiec wspomnianej redundancji .. które moim zdaniem są zmorą rozwoju sql.Name
pole w tabeli, czy powinieneś zmienić je na,Table1Name
aby uniknąć tych samych problemów z tym polem? Czy z tego samego powodu należy poprzedzać wszystkie kolumny nazwą tabeli? To nie brzmi dobrze.Zawsze preferowałem ID zamiast TableName + ID dla kolumny id, a następnie TableName + ID dla klucza obcego. W ten sposób wszystkie tabele mają taką samą nazwę pola id i nie ma zbędnego opisu. Wydaje mi się to prostsze, ponieważ wszystkie tabele mają tę samą nazwę pola klucza podstawowego.
Jeśli chodzi o dołączanie do tabel i nie wiedząc, które pole Id należy do której tabeli, to moim zdaniem należy napisać zapytanie, aby obsłużyć tę sytuację. Tam, gdzie pracuję, zawsze poprzedzamy pola, których używamy w instrukcji, z aliasem tabeli / tabeli.
źródło
Ostatnio w moim towarzystwie toczyła się o to kłótnia kujonów. Pojawienie się LINQ sprawiło, że zbędna nazwa tabeli + wzorzec ID stała się jeszcze bardziej głupia w moich oczach. Myślę, że większość rozsądnych ludzi powie, że jeśli ręcznie piszesz swój kod SQL w taki sposób, że musisz określić nazwy tabel, aby rozróżnić FK, to nie tylko oszczędza się na pisaniu, ale dodaje jasności do twojego SQL, aby używać tylko identyfikator, dzięki któremu możesz wyraźnie zobaczyć, który jest PK, a który FK .
Na przykład
OD pracowników e LEWY DOŁĄCZ Klienci c ON e.ID = c
mówi mi nie tylko, że te dwa są połączone, ale który jest PK, a który jest FK . Podczas gdy w starym stylu jesteś zmuszony albo wyglądać, albo mieć nadzieję, że zostały dobrze nazwane.
źródło
Używamy
InvoiceID
, nieID
. Sprawia, że zapytania są bardziej czytelne - gdy widziszID
je sam, może to znaczyć cokolwiek, zwłaszcza jeśli utworzysz alias tabeli nai
.źródło
Zgadzam się z Kevenem i kilkoma innymi osobami tutaj, że PK dla tabeli powinno być po prostu Id, a klucze obce to OtherTable + Id.
Chciałbym jednak dodać jeden powód, który ostatnio nadał większą wagę temu argumentowi.
Na moim obecnym stanowisku używamy frameworka encji z wykorzystaniem generacji POCO. Używając standardowej konwencji nazewnictwa Id, PK pozwala na dziedziczenie podstawowej klasy poco z walidacją i taką dla tabel, które mają zestaw wspólnych nazw kolumn. Użycie nazwy Tablename + Id jako PK dla każdej z tych tabel niszczy możliwość użycia dla nich klasy bazowej.
Tylko trochę do myślenia.
źródło
Moje preferencje to również identyfikator klucza podstawowego i TableNameID dla klucza obcego. Lubię też mieć kolumnę „nazwa” w większości tabel, w których trzymam czytelny dla użytkownika identyfikator (tj. Nazwa :-)) wpisu. Taka konstrukcja zapewnia dużą elastyczność w samej aplikacji, w ten sam sposób mogę obsługiwać tabele masowe. To bardzo potężna rzecz. Zwykle oprogramowanie obiektowe jest budowane na bazie bazy danych, ale zestawu narzędzi obiektowych nie można zastosować, ponieważ sama baza danych na to nie pozwala. Posiadanie identyfikatora i nazwy kolumn nadal nie jest zbyt dobre, ale to krok.
Dlaczego nie mogę tego zrobić?
Moim zdaniem jest to bardzo czytelne i proste. Nazywanie zmiennych jako i i il jest ogólnie kiepskim wyborem.
źródło
To nie jest naprawdę ważne, prawdopodobnie napotkasz problemy z simalarami we wszystkich konwencjach nazewnictwa.
Jednak ważne jest, aby zachować spójność, aby nie trzeba było przeglądać definicji tabeli za każdym razem, gdy piszesz zapytanie.
źródło
Właśnie zacząłem pracować w miejscu, które używa tylko "ID" (w podstawowych tabelach, do których odwołuje się TableNameID w kluczach obcych) i już znalazłem DWA problemy produkcyjne bezpośrednio przez to spowodowane.
W jednym przypadku w zapytaniu użyto "... gdzie ID w (SELECT ID FROM OtherTable ..." zamiast "... where ID in (SELECT TransID FROM OtherTable ...").
Czy ktokolwiek może uczciwie powiedzieć, że nie byłoby to o wiele łatwiejsze do wykrycia, gdyby użyto pełnych, spójnych nazw, w których niewłaściwa instrukcja brzmiałaby „... gdzie TransID w (SELECT OtherTableID z OtherTable ...”? więc.
Drugi problem występuje podczas refaktoryzacji kodu. Jeśli używasz tabeli tymczasowej, podczas gdy poprzednio zapytanie wyszło z tabeli podstawowej, to stary kod czyta „... dbo.MyFunction (t.ID) ...” i jeśli nie zostanie to zmienione, ale teraz „t” odnosi się do temp zamiast tabeli podstawowej, nie pojawia się nawet błąd - po prostu błędne wyniki.
Jeśli celem jest generowanie niepotrzebnych błędów (może niektórym ludziom brakuje pracy?), To taka konwencja nazewnictwa jest świetna. W przeciwnym razie rozwiązaniem jest spójne nazewnictwo.
źródło
Dla uproszczenia większość ludzi nazywa kolumnę w identyfikatorze tabeli. Jeśli ma odniesienie do klucza obcego w innej tabeli, to bezpośrednio nazywają go InvoiceID (aby użyć twojego przykładu) w przypadku łączenia, i tak tworzysz alias tabeli, więc jawny Inv.ID jest nadal prostszy niż inv.
źródło
Ja osobiście wolę (jak stwierdzono powyżej), Table.ID na PK i tableid dla FK . Nawet (proszę, nie strzelaj do mnie) Microsoft Access to zaleca.
JEDNAK JEDNAK WIEM RÓWNIEŻ, że niektóre narzędzia generujące faworyzują TableID dla PK, ponieważ mają tendencję do łączenia wszystkich nazw kolumn, które zawierają 'ID' w słowie, W TYM ID !!!
Nawet projektant zapytań robi to na serwerze Microsoft SQL Server (a dla każdego utworzonego zapytania kończy się zgrywanie wszystkich niepotrzebnych nowo utworzonych relacji we wszystkich tabelach o identyfikatorze kolumny)
TAK, chociaż mój wewnętrzny OCD tego nienawidzi, używam konwencji TableID . Pamiętajmy, że nazywa się to BAZĄ DANYCH , ponieważ będzie ona, miejmy nadzieję, podstawą wielu, wielu aplikacji w przyszłości. Wszystkie technologie powinny korzystać z dobrze znormalizowanego schematu z jasnym opisem.
Jest rzeczą oczywistą, że NALEŻY rysować linię, gdy ludzie zaczynają używać TableName, TableDescription i tym podobnych. Moim zdaniem konwencje powinny postępować następująco:
Alias tabeli: pełna nazwa tabeli, wyróżniona. Dawny.
[Aktualizacja]
W tym wątku znajdują się również ważne posty dotyczące zduplikowanych kolumn ze względu na „rodzaj relacji” lub rolę. Na przykład, jeśli sklep ma EmployeeID , to mówi mi przysiad. Więc czasami robię coś takiego jak Store.EmployeeID_Manager . Jasne, że jest trochę większy, ale przynajmniej ludzie nie zwariują , próbując znaleźć identyfikator ManagerID lub to, co tam robi EmployeeID . Kiedy zapytanie jest GDZIE uprościłbym to jako: SELECT EmployeeID_Manager as ManagerID FROM Store
źródło
User.UserId
jest trochę dziwne w programowaniu.Wychodząc do tego z perspektywy formalnego słownika danych, nazwałbym element danych
invoice_ID
. Ogólnie rzecz biorąc, nazwa elementu danych będzie unikalna w słowniku danych i najlepiej będzie, jeśli będzie miała tę samą nazwę w całym tekście, chociaż czasami mogą być wymagane dodatkowe terminy kwalifikujące w zależności od kontekstu, np. Wymieniony element danychemployee_ID
może być użyty dwukrotnie w schemacie organizacyjnym, a zatem kwalifikowany jakosupervisor_employee_ID
isubordinate_employee_ID
odpowiednio.Oczywiście konwencje nazewnictwa są subiektywne i to kwestia stylu. Wytyczne ISO / IEC 11179 są dla mnie przydatnym punktem wyjścia.
W przypadku DBMS tabele traktuję jako kolekcje elementów (z wyjątkiem tych, które zawsze zawierają tylko jeden wiersz, np. Tabela cofig, tabela stałych itp.), Np. Tabela, w której mój
employee_ID
jest kluczem, zostanie nazwanaPersonnel
. WięcTableNameID
konwencja od razu mi nie wychodzi .Widziałem
TableName.ID=PK TableNameID=FK
styl używany w dużych modelach danych i muszę powiedzieć, że uważam go za nieco zagmatwany: zdecydowanie wolę, aby nazwa identyfikatora była taka sama przez cały czas, tj. Nie zmieniała nazwy w oparciu o tabelę, w której się on pojawia. wspomniany styl wydaje się być używany w sklepach, które dodająIDENTITY
kolumnę (autoinkrementacja) do każdej tabeli, unikając kluczy naturalnych i złożonych w kluczach obcych. Sklepy te zwykle nie mają formalnych słowników danych ani nie budują na podstawie modeli danych. Ponownie, jest to tylko kwestia stylu, której osobiście nie podpisuję. Więc ostatecznie to nie dla mnie.Mimo wszystko widzę przypadek, w którym czasami upuszczam kwalifikator z nazwy kolumny, gdy nazwa tabeli stanowi kontekst do zrobienia tego, np. Wymieniony element
employee_last_name
może stać się po prostulast_name
wPersonnel
tabeli. Powodem jest to, że domena to „nazwiska ludzi” i jest bardziej prawdopodobne, że zostanie utworzonaUNION
zlast_name
kolumnami z innych tabel, a nie będzie używana jako klucz obcy w innej tabeli, ale z drugiej strony ... Mogę po prostu zmienić zdanie, czasami nigdy nie wiadomo. O to chodzi: modelowanie danych to po części sztuka, po części nauka.źródło
Myślę, że jako „ID” możesz użyć wszystkiego, o ile jesteś konsekwentny. Dołączenie nazwy tabeli jest ważne. Sugerowałbym użycie narzędzia do modelowania, takiego jak Erwin, aby wymusić konwencje i standardy nazewnictwa, aby podczas pisania zapytań łatwo było zrozumieć relacje, które mogą istnieć między tabelami.
Przez pierwsze stwierdzenie mam na myśli to, że zamiast identyfikatora można użyć czegoś innego, jak „recno”. Więc ta tabela miałaby PK o wartości fact_recno i tak dalej.
Pozdrawiam, Ben
źródło
Mój głos dotyczy InvoiceID dla identyfikatora tabeli. Używam tej samej konwencji nazewnictwa, gdy jest używany jako klucz obcy, i używam inteligentnych nazw aliasów w zapytaniach.
Jasne, to dłużej niż w innych przykładach. Ale uśmiechnij się. To jest dla potomnych i pewnego dnia jakiś biedny młodszy programista będzie musiał zmienić twoje arcydzieło. W tym przykładzie nie ma dwuznaczności, a gdy do zapytania zostaną dodane dodatkowe tabele, będziesz wdzięczny za szczegółowość.
źródło
Jako nazwę kolumny w bazie danych użyłbym „InvoiceID”.
Jeśli skopiuję pola do nienazwanej struktury za pośrednictwem LINQ, mogę nazwać je tam „ID”, jeśli jest to jedyny identyfikator w strukturze.
Jeśli kolumna NIE będzie używana w kluczu obcym, tak że jest używana tylko do jednoznacznej identyfikacji wiersza do edycji lub usunięcia, nadam jej nazwę „PK”.
źródło
Jeśli nadasz każdemu kluczowi unikalną nazwę, np. „Invoices.invoice_id” zamiast „invoices.id”, możesz bez obaw używać operatorów „łączenie naturalne” i „using”. Na przykład
zamiast
SQL jest wystarczająco rozwlekły, nie czyniąc go bardziej szczegółowym.
źródło
To, co robię, aby zachować spójność dla siebie (gdy tabela ma klucz podstawowy z pojedynczą kolumną używany jako identyfikator), to nazwanie klucza podstawowego tabeli
Table_pk
. Wszędzie, gdzie mam klucz obcy wskazujący na klucz podstawowy tej tabeli, nazywam kolumnęPrimaryKeyTable_fk
. W ten sposób wiem, że jeśli mamCustomer_pk
w tabeli klientów aCustomer_fk
w tabeli zamówień, to wiem, że tabela zamówień odnosi się do wpisu w tabeli klientów.Dla mnie ma to sens zwłaszcza w przypadku złączeń, w których moim zdaniem jest łatwiejsze do odczytania.
źródło
FWIW, nasz nowy standard (który zmienia się, hm, mam na myśli „ewoluuje”, wraz z każdym nowym projektem) to:
pk_
prefiks oznacza klucz podstawowy_id
sufiks oznacza całkowity identyfikator z automatycznym zwiększaniemfk_
prefiks oznacza klucz obcy (przyrostek nie jest wymagany)_VW
przyrostek dla widokówis_
przedrostek dla wartości logicznychTak więc tabela o nazwie NAMES może mieć pola
pk_name_id, first_name, last_name, is_alive,
ifk_company
widok o nazwieLIVING_CUSTOMERS_VW
, zdefiniowany na przykład:Jednak jak powiedzieli inni, prawie każdy schemat będzie działał, o ile będzie spójny i nie zaciemni niepotrzebnie twoich znaczeń.
źródło
Zdecydowanie zgadzam się na umieszczenie nazwy tabeli w nazwie pola ID, dokładnie z podanych przez Ciebie powodów. Ogólnie jest to jedyne pole, w którym chciałbym podać nazwę tabeli.
źródło
Nienawidzę zwykłego identyfikatora. Zdecydowanie wolę zawsze używać parametru faktur_id lub jego wariantu. Zawsze wiem, która tabela jest autorytatywną tabelą dla identyfikatora, kiedy potrzebuję, ale to mnie wprawia w zakłopotanie
Najgorszy jest miks, o którym wspomniałeś, całkowicie zagmatwany. Musiałem pracować z bazą danych, w której prawie zawsze był to foo_id, z wyjątkiem jednego z najczęściej używanych identyfikatorów. To było totalne piekło.
źródło
Wolę DomainName || 'ID'. (tj. DomainName + ID)
Nazwa domeny jest często, ale nie zawsze, taka sama jak nazwa_tabeli.
Problem z samym ID polega na tym, że nie skaluje się w górę. Gdy masz około 200 tabel, z których każda ma pierwszą kolumnę o nazwie ID, dane zaczynają wyglądać podobnie. Jeśli zawsze kwalifikujesz się jako identyfikator z nazwą tabeli, to trochę pomaga, ale nie tak bardzo.
Nazwa domeny i identyfikator mogą służyć do nadawania nazw kluczom obcym, a także kluczom podstawowym. Kiedy klucze foriegn są nazywane według kolumny, do której się odnoszą, może to być pomoc mnemoniczna. Formalnie wiązanie nazwy klucza obcego z kluczem, do którego się on odwołuje, nie jest konieczne, ponieważ odwołanie zostanie ustanowione przez ograniczenie integralności referencyjnej. Ale jest to bardzo przydatne, jeśli chodzi o czytanie zapytań i aktualizacji.
Czasami DomainName || Nie można użyć „ID”, ponieważ w tej samej tabeli byłyby dwie kolumny o tej samej nazwie. Przykład: Employees.EmployeeID i Employees.SupervisorID. W takich przypadkach używam RoleName || „ID”, jak w przykładzie.
Wreszcie, jeśli to możliwe, używam klawiszy naturalnych, a nie syntetycznych. Są sytuacje, w których naturalne klucze są niedostępne lub niewiarygodne, ale jest wiele sytuacji, w których naturalny klucz jest właściwym wyborem. W takich przypadkach pozwoliłem naturalnemu kluczowi przybrać nazwę, którą miałby naturalnie. Ta nazwa często nie zawiera nawet liter „ID”. Przykład: OrderNo, gdzie No to skrót od „Number”.
źródło
Dla każdej tabeli wybieram skrót literowy (np. Employees => Emp)
W ten sposób klucz podstawowy z automatycznym numerowaniem numerycznym staje się nkEmp .
Jest krótki, unikalny w całej bazie danych i na pierwszy rzut oka znam dokładnie jego właściwości.
Zachowuję te same nazwy w SQL i we wszystkich językach, których używam (głównie C #, Javascript, VB6).
źródło
Zobacz konwencje nazewnictwa witryny Interakt, aby poznać dobrze przemyślany system nazewnictwa tabel i kolumn. Metoda używa przyrostka dla każdej tabeli (
_prd
dla tabeli produktów lub_ctg
dla tabeli kategorii) i dołącza go do każdej kolumny w danej tabeli. Zatem kolumna tożsamości dla tabeli produktów byłabyid_prd
i dlatego jest unikalna w bazie danych.Idą o krok dalej, aby pomóc w zrozumieniu kluczy obcych: klucz obcy w tabeli produktów odnoszący się do tabeli kategorii byłby
idctg_prd
taki, aby było oczywiste, do której tabeli należy (_prd
przyrostek) i do której tabeli się odnosi (kategoria) .Zaletą jest to, że nie ma niejednoznaczności w kolumnach tożsamości w różnych tabelach, a nazwy kolumn pozwalają na szybkie określenie, do których kolumn odnosi się zapytanie.
źródło
zobacz także Konwencja nazewnictwa klucza podstawowego / obcego
źródło
Możesz użyć następującej konwencji nazewnictwa. Ma swoje wady, ale rozwiązuje Twoje konkretne problemy.
inv
, Linie faktur -invl
inv_id
,invl_id
invl_inv_id
nazw.w ten sposób można powiedzieć
źródło