Dlaczego nazywanie kolumny „Id” klucza podstawowego tabeli jest uważane za złą praktykę? [Zamknięte]


209

Mój nauczyciel t-sql powiedział nam, że nazywanie naszej kolumny PK „Id” jest uważane za złą praktykę bez dalszych wyjaśnień.

Dlaczego nazywanie tabeli PK kolumny „Id” jest uważane za złą praktykę?


27
Cóż, tak naprawdę nie jest to opis, a Id oznacza „tożsamość”, która jest bardzo oczywista. To moja opinia.
Jean-Philippe Leclerc

49
Jestem pewien, że istnieje wiele sklepów, które używają Id jako nazwy PK. Osobiście używam TableId jako mojej konwencji nazewnictwa, ale nie powiedziałbym nikomu, że JEDEN PRAWDZIWY SPOSÓB. Wygląda na to, że nauczycielka stara się przedstawić swoją opinię jako powszechnie akceptowaną najlepszą praktykę.

22
Zdecydowanie rodzaj złej praktyki, która nie jest taka zła. Chodzi o to, aby być konsekwentnym. Jeśli używasz identyfikatora, używaj go wszędzie lub nie używaj go.
deadalnix

57
Masz stolik ... nazywa się Ludzie, ma kolumnę o nazwie Id. Jak myślisz, co to jest Id? Samochód? Łódź? ... nie, to People People, to wszystko. Nie sądzę, żeby to była zła praktyka i nie trzeba nazywać kolumny PK niczym innym niż Id.
Jim

38
Więc nauczyciel wchodzi przed klasę i mówi ci, że to zła praktyka bez jednego powodu? To gorsza praktyka dla nauczyciela.
JeffO,

Odpowiedzi:


247

Mam zamiar wyjść i powiedzieć: to nie jest naprawdę zła praktyka (a nawet jeśli tak, to wcale nie jest taka zła).

Można argumentować (jak zauważył Chad ), że może maskować błędy, jak w poniższym zapytaniu:

SELECT * 
    FROM cars car
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

ale można to łatwo złagodzić, nie używając małych aliasów dla nazw tabel:

SELECT * 
    FROM cars
    JOIN manufacturer
        ON manufacturer.Id = cars.ManufacturerId
    JOIN models
        ON models.Id = cars.ModelId
    JOIN colors
        ON manufacturer.Id = cars.ColorId

Praktyka ZAWSZE przy użyciu trzyliterowych skrótów wydaje mi się o wiele gorsza niż używanie nazwy kolumny id. (Przypadek: kto właściwie skróciłby nazwę tabeli carsskrótem car? Jakiemu celowi to służy?)

Chodzi o to: bądź konsekwentny. Jeśli Twoja firma używa Id i często popełniasz powyższy błąd, nabądź zwyczaju używania pełnych nazw tabel. Jeśli Twoja firma zbanuje kolumnę Id, pospiesz się i zastosuj dowolną konwencję nazewnictwa.

Skoncentruj się na uczeniu się rzeczy, które W rzeczywistości są złymi praktykami (takimi jak wiele zagnieżdżonych skorelowanych zapytań cząstkowych), zamiast zastanawiać się nad takimi problemami. Problem nazwania kolumn „ID” jest bliższy kwestii gustu niż złej praktyce.


UWAGA DLA REDAKTORÓW: Błąd w tym zapytaniu jest celowy i służy do podkreślenia. Proszę przeczytać pełną odpowiedź przed edycją.


1
@Chad, było to odniesienie do faktu, że w tym konkretnym zapytaniu użyłeś 3 liter aliasów do nazw tabel, nawet jeśli nie miało to sensu ( cars-> car. Dzięki Bogu - uratowałeś mi palce). Nie czytaj zbyt głęboko w to.
riwalk

3
gorsze od moich pseudonimów było mieszanie mnogości carsi manufacturer. Jeden jest w liczbie mnogiej, a drugi nie. Jeśli ludzie chcą wybierać w db, jest to zła praktyka, którą należy wybrać.
CaffGeek

3
Myślę, że to zła praktyka. Oczywiście, jeśli chodzi o złą praktykę, nie jest to straszne .. ale tak łatwo jest tego uniknąć, dlaczego by tego nie zrobić? Zgadzam się, na wstępie, czy na tym należy się skupić? Prawdopodobnie nie ....
user606723,

2
@ user606723, tak naprawdę uważam, że w przypadku klasy wprowadzającej warto o tym wspomnieć. Nauczanie najlepszych praktyk powinno być fundamentalne. Dopiero gdy masz doświadczenie, zrozumiesz konsekwencje i kompromisy, a kiedy powinieneś odstąpić od najlepszych praktyk.
CaffGeek

5
@Chad, Zgadzam się nie zgadzać. Próba nauczenia studentów „najlepszych praktyk” bez umożliwienia im zrozumienia, dlaczego są to najlepsze praktyki, jest daremnym wysiłkiem. A ponieważ nie możesz opisać wszystkiego, przeglądając ten punkt słowami „po prostu nie powinieneś tego robić, zrozumiesz, dlaczego później” jest rozsądnym wyborem z punktu widzenia profesora. Ciekawi studenci mogą pisać tutaj lub, mam nadzieję, znaleźć odpowiedź na to pytanie. (Lub zapytaj po zajęciach)
user606723,

123

Ponieważ gdy masz tabelę z kluczem obcym, nie możesz nazwać tego klucza obcego „Id”. Masz nazwę tabeli to TableId

I wtedy wygląda twoje dołączenie

SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId

I idealnie, twój stan powinien mieć taką samą nazwę pola po obu stronach

SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId

Więc choć wydaje się zbędne nazywanie Id jako ManufacturerId, zmniejsza prawdopodobieństwo wystąpienia błędów w twoich warunkach łączenia, gdy błędy stają się oczywiste.

Wydaje się to proste, ale kiedy dołączysz do kilku stolików, bardziej prawdopodobne jest, że popełnisz błąd, znajdź ten poniżej ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

Podczas prawidłowego nazewnictwa błąd wystaje ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    JOIN models mod
        ON mod.ModelId = car.ModelId
    JOIN colors col
        ON mfg.ManufacturerId = car.ColorId

Innym powodem nazwania ich Id jest „zły” jest to, że kiedy pytasz o informacje z kilku tabel, musisz zmienić nazwę kolumn Id, abyś mógł je rozróżnić.

SELECT   manufacturer.Id as 'ManufacturerId'
        ,cars.Id as 'CarId'
        --etc
    FROM cars 
    JOIN manufacturer
        ON manufacturer.Id = cars.Id

Przy dokładnych nazwach jest to mniejszy problem


174
Nie jestem pewien, czy to wystarczająco dobre wytłumaczenie. Nie ma nic złego w mówieniu SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId. Używałem idod lat i nigdy nie znalazłem, co opisałeś, prawdziwego problemu.
riwalk

61
Powiedziałbym, że złą praktyką jest alias tabel o nazwie takiej jak mfg lub mod. Manufacturers.id = cars.man Manufacturer_id jest bardzo czytelny i błąd również wystaje.
deadalnix

5
@Chad> Mam już problemy z głupimi nazwami zmiennych. Wiele razy. Dla przypomnienia, tutaj chciałbym powiedzieć deweloperowi, który robi to w moim zespole, „mfg nie oznacza producenta, oznacza to, że jesteś leniwy, aby wpisać producenta”.
deadalnix 17.10.11

9
@ Stargazer712: Wykonanie SELECT * z 2 tabel daje 2 kolumny ID. ID jest teraz dwuznaczne: czy odwołujesz się do porządku porządkowego czy imienia? SELECT * również nie jest dobrą praktyką. Słabe argumenty. Kruchy kod. Czad ma rację: kodowanie obronne w zasadzie
gbn

6
@ gbn, znowu, wszelka dwuznaczność zniknie, jeśli po prostu to zrobisz SELECT manufacturer.id FROM .... Każda wynikająca z tego trudność idmoże być pokonana bardzo łatwo, dzięki czemu jest to po prostu kwestia gustu.
riwalk

66

Biblioteka ActiveRecord Ruby i GORM Groovy'ego domyślnie używają „id” dla klucza zastępczego. Podoba mi się ta praktyka. Powielanie nazwy tabeli w nazwie każdej kolumny jest zbędne, żmudne w pisaniu i bardziej żmudne w czytaniu.


30
+1 za „i bardziej nużące czytanie”. - konwencje nazewnictwa nie powinny być traktowane jako pomoc dla niedbałego kodu, powinny przede wszystkim poprawiać czytelność.
ocodo

12
ID jest o wiele bardziej nużące do czytania
HLGEM,

5
@HLGEM: Zawsze można zakwalifikować nazwę kolumny nazwą tabeli.
kevin cline,

2
Zgodziłbym się, z wyjątkiem bardziej nużących do czytania. Właściwie wolę czytać bardziej opisowe nazwy kolumn i poświęcać mniej czasu na zastanawianie się, do czego właściwie służy ta kolumna.
Devin Dixon,

2
+1, nienawidzę widzieć tabel z kolumnami takimi jak Posts.postID, Posts.postName, gdzie po prostu użycie post.id i post.name jest znacznie ładniejsze.
Doug

40

Wspólne lub kluczowe nazwy kolumn, takie jak „Nazwa” lub „Id”, powinny być poprzedzone nazwą tabeli.

Usuwa niejednoznaczność, jest łatwiejszy do wyszukiwania, oznacza o wiele mniej aliasów kolumn, gdy potrzebne są obie wartości „Id”.

Rzadziej używana kolumna kontroli lub inna niż klucz (powiedzmy LastUpdatedDateTime) nie ma znaczenia


57
Jeśli to zrobisz, nienawidzę cię za zmuszanie mnie do dodatkowego pisania !!!! Tabela ma na imię Osoba. Jak myślisz, jaki będzie identyfikator? Samochód? nie, to osoba.
Jim

16
@ jim, nie wiem o tobie, ale wpisanie 6 dodatkowych znaków zajmuje mi około pół sekundy. Biorąc pod uwagę, że rzadko wybieram jedną tabelę, a zatem otrzymam dwie kolumny o nazwie „Id” i w każdym razie będę musiał podać nazwę tabeli / aliasu, nie ma oszczędności w ilości wpisywanych znaków.
CaffGeek

21
@Chad Uważam, że jest to zbyteczne. jeśli wykonuję połączenie, c.id = m.manufacturerid, jest ze mną w porządku. Kolumny te są zazwyczaj „mapowane” na klasy, a posiadanie klasy z Person.PersonId sprawia, że ​​chcę wymiotować ... Tak, jestem w pełni świadomy, że mam problemy.
Jim

20
Ja też się z tym nie zgadzam. Dlaczego warto zatrzymać się w namei id? Dlaczego każda kolumna nie ma prefiksu z nazwą tabeli? Wydaje się, że wybranie tych dwóch nazw w celu wprowadzenia prefiksu wydaje się arbitralne. Koncepcyjnie, musisz mieć tabelę, aby mimo to mieć kontekst kolumny. Dlaczego nie użyć tej nazwy tabeli do wyjaśnienia zapytania: Person.Name, Animal.Name, Part.Name, ...
Thomas

11
@Bill Leeper, DRY nie zawsze jest odpowiednie w tworzeniu baz danych. W bazach danych ważna jest wydajność i zmuszenie bazy do wykonania dodatkowej pracy w celu spełnienia zasad DRY DRY (takich jak używanie funkcji skalarnych lub widoków wywołujących widoki lub zapytania zwracające zbyt wiele kolumn lub użycie kursora w celu dodania 1000000 rekordów w celu użycia istniejącego proc) jest często przeciwwskazane. Nie myśl, że tylko dlatego, że coś jest dobre w świecie zorientowanym obiektowo, jest odpowiednie w projektowaniu baz danych. Twoja opinia była nieodpowiednia. Używanie identyfikatora jest znanym antipatternem SQL.
HLGEM,

31

Ten wątek jest martwy, ale chciałbym dodać, że IMO nie stosując Idjest złą praktyką. IdKolumna specjalnym; jest to klucz podstawowy. Każda tabela może mieć dowolną liczbę kluczy obcych, ale może mieć tylko jeden klucz, który jest podstawowy. W bazie danych, w której są wywoływane wszystkie klucze podstawowe Id, jak tylko spojrzysz na tabelę, wiesz dokładnie, która kolumna jest kluczem podstawowym.

Uwierz mi, od miesięcy spędzam cały dzień codziennie pracując w wielu dużych bazach danych (Salesforce), a najlepsze, co mogę powiedzieć o schematach, to to, że każda tabela ma podstawowy klucz o nazwie Id. Zapewniam cię, że nigdy nie mylę się przy łączeniu klucza podstawowego z kluczem obcym, ponieważ wywoływana jest PK Id. Inną rzeczą, o której ludzie nie wspominali, jest to, że tabele mogą mieć długie głupie nazwy, takie jak Table_ThatDoesGood_stuff__c; ta nazwa jest wystarczająco zła, ponieważ architekt miał kaca rano, gdy wymyślił tę tabelę, ale teraz mówisz mi, że złą praktyką jest nie wywoływanie klucza podstawowego Table_ThatDoesGood_stuff__cId (pamiętając, że nazwy kolumn SQL nie rozróżniają wielkich i małych liter).

Szczerze mówiąc, problemy z większością osób uczących programowania komputerowego polegają na tym, że od lat nie napisały linii kodu produkcyjnego i nie mają pojęcia, co właściwie robi działający inżynier oprogramowania. Poczekaj, aż zaczniesz pracować, a następnie zdecyduj, co uważasz za dobry pomysł, czy nie.


2
Dzieje się tak tylko wtedy, gdy żaden z kluczy podstawowych nie jest kluczem złożonym, co niestety zdarza się zbyt często. Naprawdę należy używać kluczy zastępczych tylko w szczególnych okolicznościach.
nicodemus13

6
Używając takiego identyfikatora, kończysz się sytuacją, w której programiści dodają identyfikator klucza podstawowego do każdej tabeli, którą tworzą. Jedną z podstaw relacyjnych baz danych jest używanie znaczących i agregujących kluczy podstawowych, a używanie identyfikatora nie pomaga.
Pieter B,

Ta odpowiedź wygląda na to, że mówisz „wolę Id” z opiniotwórczymi argumentami. Argumentujesz, że możesz natychmiast zobaczyć, który klucz jest kluczem podstawowym, znajdując klucz o nazwie Id. Cóż, dokładnie tak samo jest z TableId . Gwarantuję ci, że nigdy się nie mylę, który klucz jest kluczem podstawowym. Po prostu szukam tego, który ma nazwę tabeli przed identyfikatorem. Nie tylko to, ale z jakim rodzajem pogańskich tabel pracujesz, gdy pierwsza kolumna nie jest kluczem podstawowym? Wydaje mi się, że wszystkie twoje argumenty w tej odpowiedzi opierają się wyłącznie na preferencjach i przypominają „tableId do mnie źle”.
dallin

@dallin wszystkie odpowiedzi są opiniowane, w przeciwnym razie ktoś po prostu link do oficjalnego standardu, a nie ma!
James

@James Wydaje mi się, że celem witryn StackExchange jest ograniczenie opinii. Dlatego pytania są zamykane jako zbyt opiniotwórcze. Owszem, myślę, że właśnie dlatego to pytanie zostało zamknięte - ponieważ wywołuje wyrażone opinie, ale uważam, że ta konkretna odpowiedź została nadmiernie wyrażona bez żadnych faktów lub argumentów opartych na faktach. Całą odpowiedź można streścić, mówiąc: „W moim zdaniem powinieneś używać Id, tylko dlatego, że to lubię ". To nie jest cenna odpowiedź.
dallin

24

Nie uważam tego za złą praktykę. Konsekwencja jest jak zwykle królem.

Myślę, że chodzi o kontekst. W kontekście samej tabeli „id” oznacza dokładnie to, czego oczekujesz, etykietę, która pomoże jednoznacznie zidentyfikować ją na tle innych, które w przeciwnym razie mogą (lub wyglądać) identycznie.

W kontekście dołączeń Twoim obowiązkiem jest zbudowanie złączeń w taki sposób, aby były czytelne dla Ciebie i Twojego zespołu. Tak jak możliwe jest utrudnienie wyglądania przy złym frazowaniu lub nazywaniu, tak samo możliwe jest zbudowanie sensownego zapytania z efektywnym wykorzystaniem aliasów, a nawet komentarzy.

W ten sam sposób, w jaki klasa Java o nazwie „Foo” nie ma swoich właściwości z prefiksem „Foo”, nie czuję się zobowiązana do poprzedzania identyfikatorów tabel nazwami tabel. W kontekście zwykle jest jasne, do jakiego identyfikatora się odnosi.


5
Tabele relacyjnych baz danych nie są klasami .
Adam Robinson

1
Są to jednak struktury danych i są analogiczne do klas PODO. Obowiązują te same problemy z nazewnictwem.
ocodo

4
@Slomojo: Nie, nie są one analogiczne do prostych obiektów. Projektowanie obiektowe i projektowanie baz danych nie są takie same i nawet nie są ze sobą powiązane. Chociaż mogą w niektórych przypadkach dać podobny (lub nawet taki sam) projekt, nie oznacza to, że są ze sobą powiązane. Na przykład relacje m: m są trywialne w klasach, ale niemożliwe jest, aby istniały między dwiema tabelami bez trzeciej tabeli asocjacyjnej.
Adam Robinson

1
Nie wiem, jak to się ma do strategii nazewnictwa. Moja analogia jest (wyraźnie?) Tylko w tym zakresie.
ocodo

2
Przepraszam, że moje domniemane znaczenie nie było bardzo jasne, powinienem był powiedzieć „ w tym sensie są one analogiczne do klas”. Tak czy inaczej, nie sądzę, aby zbyt pedantyczne podejście do tego było szczególnie konstruktywne. Pod względem nazewnictwa tabele i klasy mają wiele podobieństw. Najlepsze praktyki, które rozwijają się w ślepej uliczce, są uczciwą grą do rewizji lub przynajmniej są otwarte na dyskusję. Jest wiele pytań i odpowiedzi, które to skutecznie ilustrują, nie mam nic ważnego do dodania.
ocodo

24

Od data.stackexchange.com

Id w postach

BOOM, odpowiedź na pytanie.
Teraz powiedz swojemu nauczycielowi, że SO ćwiczy zły projekt bazy danych.


8
Domyślam na FKS, na podstawie nazw: PostTypeId -> PostTypes.Id; AcceptedAnswerId -> Answers.Id; OwnerUserId -> Users.Id. Dlaczego tak łatwą praktykę należy uważać za „złą”?
Sjoerd

3
Jak dokładnie to dowodzi najlepszych praktyk?
GBa

5
To, czy coś jest używane na stosie, czy nie, nie dowodzi, czy jest to dobra czy zła praktyka.
Pieter B,

2
Udowadnia to, że ta praktyka w żaden sposób nie zabrania skalowalności i przydatności aplikacji.
Cypher

1
W rzeczywistości praktyka SO nie jest doskonała. Użyłbym tego nazewnictwa: PostType -> PostType.Id; AcceptedAnswer -> Answer.Id; OwnerUser -> User.Id
alpav

17

Utrudnia (i dezorientuje) wykonywanie naturalnego łączenia na stole, więc tak, to źle, jeśli nie bardzo źle.

Natural Join jest starożytnym artefaktem SQL Lore (tj. Algebry relacyjnej), którą mogłeś zobaczyć: perhaps być może w książce bazy danych. Mam na myśli to, że Natrual Join nie jest nowym, wymyślonym pomysłem SQL, chociaż wydawało się, że DBMS go wdrożyło w nieskończoność, dlatego nie jest to nowy wymarzony pomysł na wdrożenie go, może być nawet nierozsądne zignorowanie jego istnienie w dzisiejszych czasach.

Cóż, jeśli nazwiesz wszystkie identyfikatory klucza podstawowego, stracisz łatwość i prostotę naturalnego łączenia. select * from dudes natural join carstrzeba będzie napisać select * from dudes inner join cars where cars.dudeid = dudes.idlub select * from dudes inner join cars where dudes.carid = cars.id. Jeśli jesteś w stanie wykonać naturalne połączenie, możesz zignorować rzeczywistą relację, która, moim zdaniem, jest niesamowita.


O ile nie piszesz procedury składowanej, kiedy programista aplikacji po raz ostatni napisał w pełni sformatowany selektor SQL? Wszystkie współczesne języki zawierają jakąś funkcję ORM, która zarządza tą relacją za Ciebie. Nazwa kolumny jest o wiele ważniejsza niż możliwość ręcznego pisania czystego SQL.
Bill Leeper

4
@ Bill Robię to cały czas, wiele razy dziennie, bardziej zależy od twojej bazy kodu niż języka, który rozwijasz. W przypadku diagnostyki, jeśli chcesz nawiązać dobre i głębokie relacje, możesz połączyć te naturalne połączenia i całkowicie uniknąć wyszukiwania identyfikatorów pól. I, jak słynie św. Hieronim, „nieznajomość SQL jest ignorancją baz danych”.
Peter Turner

Oprócz faktu, że naturalne łączenia nie są powszechnie obsługiwane, IMO, naturalne łączenia są trudniejsze do odczytania. Czy istnieją dwie kolumny w relacji czy tylko jedna? O wiele lepiej jest być wyraźnym i unikać naturalnych połączeń.
Thomas

1
@Thomas, nie wstawiłbym także naturalnych sprzężeń w kodzie, ale dla celów diagnostycznych uznałem je za bardzo przydatne, gdy baza danych jest modelowana, aby faktycznie działały.
Peter Turner

16

Jest sytuacja, w której umieszczenie „ID” na każdym stole nie jest najlepszym pomysłem: USINGsłowo kluczowe, jeśli jest obsługiwane. Używamy go często w MySQL.

Na przykład, jeśli masz fooTablekolumnę fooTableIdi barTableklucz obcy fooTableId, twoje zapytania mogą być skonstruowane jako takie:

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)

Nie tylko oszczędza pisania, ale jest znacznie bardziej czytelny w porównaniu do alternatywy:

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)

To odpowiedź najbardziej mnie wyróżnia. Słowo USINGkluczowe jest obsługiwane przez bazę danych postgres / mysql / sqlite, co oznacza mniej pisania, które niektóre inne odpowiedzi wymieniają jako powód do użycia id, i ostatecznie, moim subiektywnym zdaniem, jest bardziej czytelne.
Michael Barton,

11

Dlaczego nie zapytać swojego nauczyciela?

Pomyśl o tym, gdy wszystkie kolumny PK nazwane są tabelami, IDużywanie ich jako kluczy obcych jest koszmarem.

Nazwy kolumn muszą mieć znaczenie semantyczne. IDjest ogólny.


8
zbyt ogólny na co? identyfikator stołu?
Jim

3
@Jim który stół? idSamo nic nie znaczy, zwłaszcza w kontekście klucza obcego do innej tabeli. Nie ma to nic classeswspólnego z dobrym podstawowym podstawowym projektem relacyjnej bazy danych.

10
Aby być nieco głupim, stół, do którego należy. table.idjest całkowicie akceptowalnym sposobem odwoływania się do idpola. Poprzedzanie nazwy pola nazwą tabeli jest zbędne.
ocodo

2
@ Slomoj nie jest bardziej typowe niż wpisywanie nazwy w kolumnie i bardziej precyzyjne, gdy aliasy nazw tabel do skrótów jedno lub dwuliterowych w połączeniach potworów.

6
O jakim koszmarze mówisz? Załóżmy, że masz samoreferencyjną strukturę pracowników z kolumną reprezentującą ich kierownika. Jak nazywacie klucz obcy? Nie możesz nazywać go „EmployeeId”, ponieważ jest to prawdopodobnie twój PK. Nazwa FK nie musi odpowiadać PK. Należy nazwać tym, co reprezentuje byt, w którym jest zawarty.
Thomas

7

Identyfikator jest zły z następujących powodów:

Jeśli wykonujesz wiele zapytań dotyczących raportowania, zawsze musisz alias kolumn, jeśli chcesz zobaczyć oba. Staje się więc stratą czasu, kiedy można nazwać go poprawnie na początku. Te złożone zapytania są wystarczająco trudne (piszę zapytania, które mogą mieć setki wierszy) bez dodatkowego obciążenia związanego z wykonywaniem niepotrzebnej pracy.

Może to powodować błędy w kodzie. Jeśli korzystasz z bazy danych, która pozwala na korzystanie z naturalnego sprzężenia (nie sądzę, że powinieneś go kiedykolwiek używać, ale gdy funkcje są dostępne, ktoś będzie ich używał), połączysz się z niewłaściwą rzeczą, jeśli uzyskasz programistę, który go używa.

Jeśli kopiujesz sprzężenia, aby utworzyć złożone zapytanie, łatwo zapomnieć o zmianie aliasu na żądany i uzyskać niepoprawne połączenie. Jeśli każdy identyfikator jest nazwany na podstawie tabeli, w której się on znajduje, zwykle pojawia się błąd składniowy. Łatwiej jest również wykryć, czy złożone zapytanie dołączenia jest niepoprawne, jeśli nazwa pPK i nazwa FK są zgodne.


+1: Moim zdaniem są to ważne powody, podczas gdy inne przeciwne odpowiedzi w IDogóle mnie nie przekonują.
phoog,

Odp: „Jeśli kopiujesz złączenia, aby utworzyć złożone zapytanie” - więc problemem jest kopiowanie i wklejanie. Zatrzymaj kopiowanie i wklejanie, a zobaczysz, jak wygodne jest nazywanie car.id. Aby dołączyć do FK, użyj car.mfg = mfg.id, car.color = color.id, car.model = model.id - bardzo proste i pasuje do tego, co napisałeś w LINQ.
alpav

Spróbuj napisać coś z 30 złączeniami, a zobaczysz, dlaczego jest to antypattern.
HLGEM

Aliasing to pierwszy i najważniejszy powód - to taki ból głowy podczas robienia dużych, złożonych raportów. Naturalne połączenia to tylko słodka premia. To niesamowite, jak inne odpowiedzi po prostu ignorują te punkty. Myślę, że dodanie kilku przykładów uczyniłoby sprawę bardziej zrozumiałą i przeskoczyłbym tę odpowiedź wyżej, gdzie powinna być.
Lulu,

5

Istnieją odpowiedzi, które podchodzą do tego, co uważam za najważniejszy powód, dla którego nie używam „id” jako nazwy kolumny klucza podstawowego w tabeli: mianowicie spójność i zmniejszona dwuznaczność.

Jednak dla mnie kluczową zaletą jest programista konserwacji, w szczególności ten, który nie był zaangażowany w pierwotne opracowanie. Jeśli używałeś nazwy „PersonID” dla identyfikatora w tabeli Person i konsekwentnie używałeś tej nazwy jako klucza obcego, napisanie zapytania do schematu jest banalne, aby dowiedzieć się, które tabele mają PersonID bez konieczności wnioskowania o tym „PersonID” to nazwa używana, gdy jest to klucz obcy. Pamiętaj, że dobre lub złe relacje między kluczami obcymi nie zawsze są egzekwowane we wszystkich projektach.

Istnieje przypadek skrajny, w którym jedna tabela może wymagać dwóch kluczy obcych do tej samej tabeli, ale w takich przypadkach wstawiłbym oryginalną nazwę klucza jako nazwę sufiksu dla kolumny, więc dopasowanie wieloznaczne,% PersonID, może łatwo znaleźć te przypadki również.

Tak, wiele z tego można osiągnąć dzięki standardowi posiadania „id” i wiedzy, aby zawsze używać go jako „tableNameID”, ale to wymaga zarówno znajomości, że praktyka jest na miejscu, a zależnie od pierwotnych programistów, aby postępować zgodnie z intuicyjna standardowa praktyka.

Chociaż niektórzy zauważyli, że do napisania dłuższych nazw kolumn potrzebne są dodatkowe naciśnięcia klawiszy, ale przypuszczam, że napisanie kodu to tylko niewielka część aktywnego życia programu. Jeśli celem było zapisanie naciśnięć klawiszy programisty, nigdy nie należy pisać komentarzy.

Jako ktoś, kto spędził wiele lat na utrzymywaniu dużych projektów z setkami tabel, zdecydowanie wolałbym spójne nazwy dla klucza między tabelami.


Załóżmy, że Companiestabela ma 2 klucze obce do Personstabeli. Jeden reprezentuje prezesa firmy; drugi reprezentuje skarbnika spółki. Czy naprawdę nazwałbyś kolumny PersonID1i PersonID2? Nazwanie ich PresidentIDi byłoby znacznie bardziej opisowe TreasurerID. O wiele łatwiej mi to czytać inner join Person AS Presidents ON Company.PresidentID = Presidents.IDniżinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
phoog

1
Nie. W twoim przykładzie prawdopodobnie miałbym tabelę CompanyOfficerlub, CompanyPersonktóra pozwala na relację wiele do wielu pomiędzy Companyoraz Personz dodatkowymi informacjami na temat charakteru relacji. Gdybym zaimplementował ją w Companytabeli, użyłbym nazw kolumn PresidentPersonIDi TreasurerPersonIDzachowałby część * PersonID nazwy, dodając dodatkowy deskryptor. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
Malachi

5

Praktyka używania Id jako pola klucza podstawowego prowadzi do praktyki, w której identyfikator jest dodawany do każdej tabeli. Wiele tabel ma już unikalne informacje, które jednoznacznie identyfikują rekord. Użyj tego jako klucza podstawowego, a nie pola identyfikatora dodawanego do każdej tabeli. To jedna z podstaw relacyjnych baz danych.

I właśnie dlatego używanie id jest złą praktyką: id często nie jest informacją, tylko automatycznym wzrostem.

rozważ następujące tabele:

PK id | Countryid   | Countryname
    1 |         840 | United States
    2 |         528 | the Netherlands

Co jest nie tak z tą tabelą, to to, że pozwala użytkownikowi dodać kolejną linię: Stany Zjednoczone, z Countrycode 840. Po prostu złamała integralność relacyjną. Oczywiście możesz wymusić unikalność na poszczególnych kolumnach lub możesz użyć klucza podstawowego, który jest już dostępny:

PK Countryid   | Countryname
           840 | United States
           528 | the Netherlands

W ten sposób wykorzystujesz informacje, które już posiadasz jako klucz podstawowy, który jest sercem projektowania relacyjnych baz danych.


1
Zrozumiesz, dlaczego ludzie dodają ogólną kolumnę klucza do każdej tabeli, gdy trzeba było migrować bazy danych między różnymi systemami lub mieć przyjemność łączenia baz danych ze sobą.
Cypher

1
Od czasu do czasu tak jest, ale z mojego doświadczenia wynika, że ​​dość fajny jest unikalny niezmienny klucz. Ale nawet w twoim przykładzie masz bezsensowny unikalny numer identyfikujący kraje, tylko jeden, który jest przydzielany przez ISO, a nie przez twoją bazę danych.
CodesInChaos

A teraz, gdy zmienia się nazwa kraju, musisz ją zaktualizować w całej bazie danych, aby to naprawić. Gdybyś po prostu użył klucza zastępczego (jak ... „id”), aktualizacja byłaby trywialna. Naturalne klucze są świetne - gdy są całkowicie niezmienne i nigdy się nie zmieniają. W rzeczywistości jest bardzo niewiele przypadków, w których jest to prawdą.
Gerrat

@Gerrat: W przypadku zmiany nazwy kraju kod numeryczny ISO 3166-1 pozostaje niezmieniony, zmieniają się tylko kody alfa-2 i alfa-3 ISO 3166-1. Stało się tak na przykład w Birmie / Myanmarze. Podobnie, jeśli kraj zmienia terytorium, ale zachowuje swoją nazwę, kod numeryczny ISO 3166-1 ulega zmianie, ale kody ISO 3166-1 alfa-2 i alfa-3 pozostają. Stało się tak, gdy Sudan Południowy oddzielił się od Sudanu, a Erytrea oddzielił się od Etiopii. Kiedy Niemcy Wschodnie i Zachodnie ponownie się połączyły, zachowały kody alfa-2 i alfa-3 Niemiec Zachodnich, ale otrzymały nowy kod numeryczny. Kiedy kraje całkowicie się rozpadają lub przekształcają (pomyśl…
Jörg W Mittag

… Wynik wojen bałkańskich lat 90.), otrzymali zarówno nowe kody numeryczne, jak i kody alfa-2 i alfa-3.
Jörg W Mittag

4

Zawsze używam „id” jako podstawowej nazwy kolumny dla każdej tabeli po prostu dlatego, że jest to konwencja frameworków, których używam (Ruby on Rails, CakePHP), więc nie muszę go nadpisywać przez cały czas.

To nie będzie dla mnie uzasadnieniem akademickim.


2

Nie uważam, że jest to zła praktyka, jeśli jest właściwie stosowana. Często zdarza się, że pole ID automatycznie zwiększa się o nazwie „ID”, którego nigdy nie trzeba dotykać, i używa bardziej przyjaznego identyfikatora dla aplikacji. Pisanie kodu może być trochę kłopotliwe, from tableA a inner join tableB b on a.id = b.a_idale kod ten można schować.

Jako osobistą preferencję staram się poprzedzać identyfikator nazwą jednostki, ale nie widzę prawdziwego problemu z używaniem tylko Idwtedy, gdy jest obsługiwana w całości przez bazę danych.


Nigdy nie dołączysz do dwóch tabel przez każdy klucz podstawowy, zwłaszcza identyfikator automatycznego przyrostu. Powyższy przykład pochodzi z tabeli A wewnętrznej tabeli łączenia Bb na a.id = b.table_a_id.
Bill Leeper

Tak, o to mi chodziło. Prawie czas na lunch i potrzeba energii.
Wayne Molina

2

Identyfikator jest na tyle powszechny, że nie sądzę, że mógłby to kogoś pomylić. Zawsze będziesz chciał poznać stół. Umieszczanie nazw pól w kodzie produkcyjnym bez dołączania tabeli / aliasu jest złą praktyką. Jeśli martwisz się, że możesz szybko pisać zapytania ad hoc, jesteś sam.

Mam tylko nadzieję, że nikt nie tworzy bazy danych SQL, w której ID jest słowem zastrzeżonym.

CREATE TABLE CAR (ID);

Dba o nazwę pola, klucz podstawowy i przyrosty automatyczne o 1, zaczynając od 1 wszystko w jednym ładnym małym zestawie 2 znaków. Och, nazwałbym to CARS, ale jeśli chcemy zaoszczędzić na naciśnięciach klawiszy i kto naprawdę myśli, że stół o nazwie CAR będzie miał tylko jeden?


1
pokazuje to, dlaczego znajomość formalnej teorii relacyjnej jest ważna, nazwa tabeli reprezentuje to, co jest pojedynczy wiersz . Tabela Carprzedstawia miejsce, w Tablektórym każdy Rowreprezentuje pojedynczy Car. Wywołanie Carszmian semantycznych i pokazuje całkowity brak zrozumienia formalnych podstawowych zasad teorii relacyjnej. Szyny to doskonały przykład kogoś, kto wiedział wystarczająco dużo, aby być niebezpiecznym .

2

To pytanie było wielokrotnie powtarzane, ale pomyślałem, że ja też dodam swoją opinię.

  1. Używam identyfikatora, co oznacza, że ​​jest to identyfikator każdej tabeli, więc kiedy dołączam do tabeli i potrzebuję klucza podstawowego, automatycznie dołączam do klucza podstawowego.

  2. Pole id jest autoinkrementacją, bez znaku (co oznacza, że ​​nigdy nie muszę ustawiać jego wartości i nie może być ujemne)

  3. W przypadku kluczy obcych używam tablenameid (znowu kwestia stylu), ale kluczem podstawowym, do którego dołączam, jest pole identyfikatora tabeli, więc spójność oznacza, że ​​zawsze mogę łatwo sprawdzać zapytania

  4. id też jest krótki i słodki

  5. Dodatkowa konwencja - używaj małych liter dla wszystkich nazw tabel i kolumn, więc nie można znaleźć problemów z powodu wielkości liter


1

Inną rzeczą do rozważenia jest to, że jeśli nazwa klucza podstawowego różni się od nazwy klucza obcego, nie można używać niektórych narzędzi stron trzecich.

Na przykład nie można załadować schematu do narzędzia takiego jak Visio i uzyskać dokładne ERD.


Byłaby to jednak wina narzędzia zewnętrznego. Konwencje nazewnictwa kolumn nie zastępują rzeczywistych kluczy obcych, które narzędzie powinno introspekować.
Gerrat

1

Uważam, że ludzie tutaj zajmują się prawie każdym aspektem, ale chcę dodać, że „identyfikator” nie jest i nie powinien być odczytywany jako „identyfikator”, jest raczej „indeksem” i na pewno nie określa ani nie opisuje tożsamości wiersza. (Być może użyłem tutaj niewłaściwych sformułowań, popraw mnie, jeśli tak zrobiłem)

Mniej więcej tak ludzie czytają dane tabeli i jak piszą swój kod. Ja osobiście i najprawdopodobniej jest to najpopularniejszy sposób, w jaki częściej widzę, że koderzy piszą pełne referencje jako table.id, nawet jeśli nie muszą robić związków i / lub dołączać. Na przykład:

SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>

W ten sposób możesz przetłumaczyć go na angielski jako „Daj mi kolor i model tego samochodu, który ma numer”. a nie jako „Daj mi kolor i model tego samochodu, który jest określony jako numer”. Identyfikator nie reprezentuje samochodu w żaden sposób, jest to tylko indeks samochodu, numer seryjny, jeśli wolisz. Tak jak wtedy, gdy chcesz pobrać trzeci element z tablicy.

Podsumowując, chciałem dodać, że jest to tylko kwestia preferencji, a opisany sposób czytania SQL jest najbardziej popularny.

Są jednak przypadki, w których nie jest to używane, na przykład (o wiele rzadszy przykład), gdy identyfikator jest ciągiem, który naprawdę opisuje. Na przykład id = "RedFordMustang1970"lub coś podobnego. Naprawdę mam nadzieję, że mógłbym to wyjaśnić przynajmniej po to, aby uzyskać ten pomysł.

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.