tło
Mam te tabele
+-------------------------+ +------------------------+
|Airport | |Country |
|-------------------------| |------------------------|
|airport_code string (PK) | |country_code string (PK)|
|address string | |name string |
|name string | +------------------------+
+-------------------------+
+-------------------------+
|Currency |
|-------------------------|
|currency_code string (PK)|
|name string |
+-------------------------+
kod_portu to kod lotniska IATA (International Air Transport Association) , który można zobaczyć na etykietach bagażowych podczas podróży samolotem.
country_code to standardowy kod kraju ISO 3166-1 A3 , który można zobaczyć na igrzyskach olimpijskich.
currency_code to standardowy 3-znakowy kod waluty IS0 417 , który można zobaczyć na międzynarodowych tablicach wymiany walut.
pytania
Czy te naturalne PK są wystarczająco dobre?
Czy stosowanie uznanych na świecie standardów, które są akceptowane przez całe branże, jest wystarczająco dobre dla PK?
Czy te tabele potrzebują surogatów bez względu na wszystko?
źródło
Myślę, że potrzeba jest bardzo mocnym słowem iw ścisłym tego słowa znaczeniu tabele prawdopodobnie nie potrzebują kluczy zastępczych .
Gdyby jednak była to moja baza danych, prawdopodobnie i tak dodałbym klucze zastępcze. Niekoniecznie chcę, aby mój projekt bazy danych zależał od grupy stron trzecich (IATA, ISO), niezależnie od tego, jak stabilne są ich standardy. Lub może wcale nie chcę polegać na określonym standardzie (czy istnieją inne standardy kodów walut? Nie wiem). Prawdopodobnie modelowałbym swoje tabele za pomocą kluczy zastępczych w następujący sposób:
Innymi słowy, chyba że te standardowe kody branżowe są z natury ważne dla mojej aplikacji, nie użyłbym ich jako PK moich tabel. To tylko etykiety. Większość moich innych tabel prawdopodobnie będzie miała klucze zastępcze, a ta konfiguracja zwiększy spójność mojego modelu danych. Koszt „dodania” kluczy zastępczych jest minimalny.
Aktualizacja na podstawie niektórych komentarzy:
Bez znajomości kontekstu przykładowych tabel nie można wiedzieć, jak ważne są na przykład kody IATA Airport dla aplikacji korzystającej z bazy danych. Oczywiście, jeśli kody IATA są centralnie ważne i są szeroko stosowane w całej aplikacji, może być prawidłowa decyzja, po odpowiedniej analizie, użyć kodów jako PK tabeli.
Jeśli jednak tabela jest tylko tabelą wyszukiwania używaną w kilku rogach aplikacji, względne znaczenie kodów IATA może nie uzasadniać tak znaczącego miejsca w infrastrukturze bazy danych. Jasne, być może będziesz musiał wykonać dodatkowe sprzężenie w kilku zapytaniach tu i tam, ale wysiłek ten może być trywialny w porównaniu do wysiłku, jaki trzeba by wykonać, aby upewnić się, że w pełni rozumiesz konsekwencje wprowadzenia kodów IATA pole klucza podstawowego. W niektórych przypadkach nie tylko mnie to nie obchodzi, ale nie chcę dbać o kody IATA. Poniższy komentarz Jamesa Snella jest doskonałym przykładem czegoś, czego nie chciałbym się martwić o wpływ na PK moich stołów.
Ważna jest również konsekwencja w projektowaniu. Jeśli masz bazę danych z dziesiątkami tabel, z których wszystkie mają konsekwentnie zaprojektowane klucze zastępcze, a następnie kilka tabel odnośników, które używają kodów innych firm jako PK, co wprowadza niespójność. Nie jest to wcale takie złe, ale wymaga dodatkowej uwagi w dokumentacji i takie, które mogą nie być uzasadnione. Są to tabele odnośników dla dobra, po prostu użycie klucza zastępczego dla spójności jest całkowicie w porządku.
Aktualizacja na podstawie dalszych badań:
Ok, ugryzła mnie ciekawość i postanowiłem przeprowadzić dla zabawy badania kodów lotniska IATA, zaczynając od linków podanych w pytaniu.
Jak się okazuje, kody IATA nie są tak uniwersalne i autorytatywne, jak się wydaje na pytanie. Według tej strony :
Ponadto kody IATA i kody ICAO różnią się od kodów identyfikacyjnych FAA , które są jeszcze innym sposobem identyfikacji lotnisk.
Moim celem przywołania tych informacji nie jest rozpoczęcie debaty na temat tego, które kody są lepsze, bardziej uniwersalne, bardziej autorytatywne lub bardziej wyczerpujące, ale aby dokładnie pokazać, dlaczego projektowanie struktury bazy danych wokół dowolnego identyfikatora innej firmy nie jest czymś, co wybrałbym , chyba że istniałby konkretny powód biznesowy .
W tym przypadku uważam, że moja baza danych byłaby lepiej zbudowana, bardziej stabilna i bardziej elastyczna, poprzez rezygnację z kodów IATA (lub dowolnego kodu potencjalnie zmiennego innej firmy) jako kandydata na klucz podstawowy i użycie klucza zastępczego. W ten sposób mogę pominąć wszelkie potencjalne pułapki, które mogą się pojawić z powodu wyboru klucza podstawowego.
źródło
select * from baggage where airport_code = 'LHR'
, co oznacza, że baza danych jest użyteczna tylko do rzucenia aplikacji, która jest bardzo wąska i zastrzeżona podejście, szczególnie gdy właściciel firmy jest tym, który zapłacił za bazę danych, a zatem jest jej właścicielem. Będziesz także musiał napisać kod, aby wykonywać przyziemne czynności, takie jak importowanie danych z jednej bazy danych do drugiej, aby uniknąć kolizji PK.Chociaż posiadanie kluczy zastępczych w polach jest w porządku i nie ma w tym nic złego, czymś do rozważenia może być sam rozmiar strony indeksu.
Ponieważ jest to relacyjna baza danych, będziesz wykonywać wiele połączeń, a posiadanie klucza zastępczego typu liczbowego może ułatwić bazę danych obsługę, tzn. Rozmiar strony indeksu będzie mniejszy, a zatem szybsze wyszukiwanie. Jeśli jest to mały projekt, nie będzie to miało znaczenia i poradzisz sobie bez żadnych problemów, jednak im większa aplikacja, tym bardziej będziesz chciał zmniejszyć wąskie gardła.
Posiadanie BIGINT, INT, SMALLINT, TINYINT lub innego typu danych typu liczb całkowitych może zaoszczędzić ci problemów na drodze.
Tylko moje 2 centy
AKTUALIZACJA:
Mały projekt - z którego korzysta kilka, a może nawet kilkadziesiąt osób. Projekt na małą skalę, projekt demonstracyjny, projekt na użytek osobisty, coś do dodania do portfolio, gdy prezentujesz swoje umiejętności bez doświadczenia i tym podobne.
Duży projekt - z którego korzystają tysiące, dziesiątki tysięcy, miliony użytkowników dziennie. Coś, co zbudowałbyś dla krajowej / międzynarodowej firmy z ogromną bazą użytkowników.
Zwykle zdarza się, że kilka wybranych rekordów jest często wybieranych, a serwer buforuje wyniki w celu szybkiego dostępu, ale co jakiś czas trzeba uzyskać dostęp do mniej używanego rekordu, w którym to momencie serwer musiałby zanurzyć się w indeksie strona. (w powyższym przykładzie z nazwami lotnisk ludzie często latają na krajowe linie lotnicze, np. Chichago -> Los Angeles, ale jak często ludzie latają z Bostonu -> Zimbabwe)
Jeśli używana jest funkcja VARCHAR, oznacza to, że odstępy nie są jednolite, chyba że dane są zawsze tej samej długości (w którym momencie wartość CHAR jest bardziej skuteczna). Powoduje to, że wyszukiwanie indeksu jest wolniejsze, a ponieważ serwer jest już zajęty obsługą tysięcy i tysięcy zapytań na sekundę, teraz musi tracić czas na przeglądanie niejednorodnego indeksu i robić to samo ponownie na sprzężeniach (co jest wolniejsze niż regularne selekcje w niezoptymalizowanej tabeli, weź DW jako przykład, gdzie jest jak najmniej połączeń, aby przyspieszyć pobieranie danych). Również jeśli używasz UTF, który może również zepsuć się z silnikiem bazy danych (widziałem niektóre przypadki).
Osobiście z własnego doświadczenia wynika, że odpowiednio zorganizowany indeks może zwiększyć szybkość łączenia o ~ 70%, a wykonanie połączenia w kolumnie liczb całkowitych może przyspieszyć łączenie nawet o około 25% (w zależności od danych) . Gdy główne tabele zaczną się powiększać i te tabele się na nich przydadzą, wolałbyś, aby typ danych całkowitych zajmował kolumnę, która ma kilka bajtów, zamiast pola VARCHAR / CHAR, które zajmowałoby więcej miejsca. Sprowadza się to do oszczędności miejsca na dysku, zwiększenia wydajności i ogólnej struktury relacyjnej bazy danych.
Ponadto, jak wspomniał James Snell:
Biorąc to pod uwagę, wolałbyś raczej zaktualizować 1 rekord, który jest powiązany z liczbą, zamiast aktualizować ten jeden rekord plus wszystkie rekordy w tabeli, do której dołączasz.
źródło
small project
ibigger
, zaktualizuj, aby wyjaśnić, dlaczego to ma znaczenie.Jeśli zastosujesz podejście „Cały czas używam kluczy zastępczych”, możesz ominąć tego rodzaju obawy. To może nie być dobre, ponieważ ważne jest, aby zastanowić się nad danymi, ale z pewnością oszczędza dużo czasu, energii i wysiłku. Jeśli ktoś miałby przyjąć tę regułę, wymienione przykłady z pewnością się kwalifikują, ponieważ wprowadzenie zmiany wymaga prawie „aktu kongresu”.
Zapytania ad hoc bazy danych z tymi naturalnymi kluczami są z pewnością pomocne. Równie dobrze może działać tworzenie widoków, które robią to samo, włączając tabele odnośników. Nowoczesne bazy danych wykonują znacznie lepszą pracę z tego typu rzeczami do tego stopnia, że prawdopodobnie nie ma to znaczenia.
Istnieją pewne przypadki specyficzne dla USA, w których standardy zostały drastycznie zmienione: kod pocztowy został rozszerzony z 5 - 9 cyfr, skróty stanowe do spójnych 2 liter i pozbył się okresu (pamiętasz, kiedy Illinois był chory?), I większość świat miał do czynienia z Y2K. Jeśli masz aplikację czasu rzeczywistego z rozproszonymi na całym świecie danymi zawierającymi miliardy rekordów, aktualizacje kaskadowe nie są najlepszym pomysłem, ale czy nie powinniśmy wszyscy pracować w miejscach, w których stoją takie wyzwania? Za pomocą tego zestawu danych możesz sam go przetestować i uzyskać bardziej trudną odpowiedź.
źródło