Każda wielka historia zaczyna się od kryzysu tożsamości. Luke, wielki mistrz Jedi, zaczyna być niepewny – „Kim jestem?” - a jak mógłbym być kimś ważnym? Dopiero Yoda, ten z Mocą, nauczy go, jak wykorzystać swoje moce.
Dzisiaj pozwól mi być twoim Yodą.
Zaczniemy od tego, jak wybrać klucz podstawowy, walczyć z kryzysem tożsamości, a następnie zakończyć z przykładami kodu do tworzenia klucza podstawowego w bazie danych.
Jak wybrać klucz podstawowy
Możesz myśleć, że tylko Luke ma kryzys tożsamości, ale to nieprawda. Podczas tworzenia bazy danych wszystko przeżywa kryzys tożsamości. I właśnie dlatego potrzebujemy kluczy podstawowych:one rozwiązują kryzys. Mówią nam, jak znaleźć wszystkich.
Wyobraź sobie, że jesteś rządem i chcesz cyfrowo zidentyfikować każdego ze swoich obywateli. Więc tworzysz tę bazę danych ze wszystkim, co ich dotyczy:
First Name
Last Name
Passport Number
Wybierasz numer paszportu jako klucz podstawowy - tożsamość dla każdego. Myślisz, że to wszystko, czego potrzebujesz, ponieważ paszport zawiera adres i wszystko inne. Wiesz, że numery paszportów są unikalne, więc czujesz się dobrze i wdrażasz ten system.
Kilka lat później dowiadujesz się brzydkiej prawdy:cały kraj stoi w obliczu kryzysu tożsamości.
Ilekroć czyjś paszport traci ważność, otrzymuje nowy. Zmienia się ich tożsamość. Inne systemy nadal używają starych numerów paszportów, więc teraz wskazują na ludzi-duchy.
Wyjątkowość nie wystarczy. Wartość nie może się zmieniać przez cały okres istnienia wiersza.
A potem okazuje się, że są ludzie, którzy nawet nie mają paszportów. Nie możesz wprowadzić ich do swojego systemu, ponieważ klucze podstawowe nie mogą być NULL
. Jak możesz zidentyfikować kogoś z NULL
? klucz?
Każdy wiersz musi mieć identyfikator. Wartości NULL są niedozwolone.
Następna iteracja oznacza znalezienie identyfikatora, który nie zmienia się w czasie i który każdy ma. W Indiach okazuje się, że jest to karta Adhaar. W USA numer ubezpieczenia społecznego.
Jeśli tworzysz bazę danych, uczyń je swoimi kluczami podstawowymi.
Czasami nie masz takiego klucza. Weźmy pod uwagę kraj, który nie ma jeszcze numeru ubezpieczenia społecznego i chce stworzyć cyfrowy rejestr każdego obywatela. Mogą stworzyć nowy numer SSN lub po prostu wykorzystać moc baz danych i użyć klucza zastępczego.
Klucz zastępczy nie ma odpowiednika w świecie rzeczywistym. To tylko liczba w bazie danych. Masz więc tę tabelę w nowym kraju:
userID
First Name
Last Name
Passport Number
Numery paszportów są unikalne. Ilekroć chcesz uzyskać identyfikator użytkownika, możesz go uzyskać za pomocą numeru paszportu.
Identyfikator użytkownika nigdy się nie zmienia. Numer paszportu może się zmienić, ale zawsze jest unikalny, więc zawsze znajdziesz właściwego użytkownika. Identyfikator użytkownika jest zamiennikiem dla nieistniejącego numeru ubezpieczenia społecznego w tym kraju.
Ciekawostka:Numer paszportu tutaj jest również kluczem kandydata. Mógłby to być Klucz Główny, gdyby się nigdy nie zmienił. To jest rozróżnienie logiki biznesowej.
Głównym wnioskiem jest to:Za każdym razem, gdy wybierasz klucz podstawowy, pomyśl o kryzysie tożsamości . Czy to możliwe, że w przyszłości ktoś może zmienić swój identyfikator? Czy możemy wejść w stan, w którym wiele osób ma ten sam identyfikator?
Jako przykład podaję ludzi, ponieważ dzięki temu tożsamość jest jaśniejsza - wiemy, że każda osoba powinna mieć tożsamość. Przenieś to myślenie do swoich baz danych. Wszystko ma tożsamość, dlatego właśnie potrzebujesz kluczy podstawowych.
Uwaga:Czasami jest możliwe i pożądane użycie wielu kolumn razem jako klucza podstawowego. To jest klucz złożony.
Teraz spróbujmy zdefiniować klucze podstawowe za pomocą prawdziwych przykładów kodu. Są tu dwie rzeczy do zrobienia:po pierwsze, zidentyfikujesz Klucz Główny. Następnie nauczysz się składni służącej do definiowania jej w bazie danych.
Przykład ze świata rzeczywistego
Załóżmy, że prowadzisz firmę wysyłkową, podobnie jak Flexport. Masz paczki, które muszą dostać się z miejsca na miejsce i statki, które je przewożą. Co więcej, masz klientów, którzy zamawiają te pakiety.
Sądzisz, że będziesz potrzebować jednego stołu dla klientów, jednego dla paczek i jednego dla transportu, pokazującego, która paczka jest teraz gdzie.
Zastanów się, jakich kolumn będziesz potrzebować i jaki powinien być klucz podstawowy. Gdybyś był inżynierem w firmie Flexport, to jest rzeczywiste pytanie, które musiałbyś rozwiązać. Nic nie jest dane, wszystko odkrywa się w prawdziwym świecie.
Biorąc pod uwagę te informacje, zaprojektowałbym te tabele w następujący sposób:
Customers: first_name, last_name, email, address (for deliveries to their location)
Packages: weight, content
Transportation: <package_primary_key>, Port, time
Brakuje kluczy podstawowych. Pomyśl o nich, zanim zaczniesz czytać dalej.
Jako pakiet wybiorę substytutkę IDPakietu. Mogłem spróbować wymienić wszystkie atrybuty opakowania:wagę, objętość, gęstość, wiek. Jednoznacznie identyfikowaliby opakowanie, ale w praktyce jest to bardzo trudne. Ludziom to nie zależy, po prostu dbają o to, żeby paczka dotarła z jednego miejsca do drugiego.
Dlatego sensowne jest utworzenie losowej liczby i użycie jej jako identyfikatora. Właśnie dlatego widzisz, że FedEx, UPS i każda firma kurierska używają kodów kreskowych i identyfikatorów. Są to klucze zastępcze generowane do śledzenia pakietów.
Dla klienta wybiorę substytutkę Identyfikator klienta. Tutaj znowu miałem możliwość wyboru, powiedzmy, numeru ubezpieczenia społecznego moich klientów. Ale klienci nie chcą się tym ze mną dzielić, tylko po to, żebym im coś wysłać. Dlatego generujemy klucz wewnętrznie, nie informujemy naszych klientów o tym kluczu i nadal nazywamy ich CustomerNo. 345681.
Zabawna historia:Znam kilka firm, które ujawniły ten numer klienta, a klienci nalegali, by otrzymali numer 1. To było całkiem zabawne — inżynierowie musieli zmienić swój kod front-endowy na:if (cust == 345681) print(1);
W przypadku transportu wybiorę kompozyt Identyfikator pakietu+port+czas. To jest trochę ciekawsze. Mogłem stworzyć zastępcę tutaj również i działałoby to równie dobrze.
Ale na tym polega magia indeksowania. Klucze podstawowe otrzymują indeks automatycznie, co oznacza, że wyszukiwanie jest o wiele bardziej wydajne niż klucze podstawowe.
Kiedy przeszukujesz tę bazę danych, większość zapytań będzie miała postać „gdzie jest ten pakiet?”. Innymi słowy, mając ten identyfikator pakietu, podaj mi port i godzinę, w której aktualnie się znajduje. Potrzebuję dodatkowego indeksu nad PackageID, jeśli nie mam go jako części mojego klucza podstawowego.
Czy to brzmi dobrze? Ostatni krok, zdefiniujmy te 3 tabele w SQL. Składnia różni się nieznacznie w zależności od używanej bazy danych.
Definiowanie kluczy podstawowych w MySQL
CREATE TABLE customers
( customerID INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
last_name VARCHAR(30) NOT NULL,
first_name VARCHAR(25) NOT NULL,
email VARCHAR(50) NOT NULL,
address VARCHAR(300)
);
CREATE TABLE packages
( packageID INT(15) NOT NULL AUTO_INCREMENT,
weight DECIMAL (10, 2) NOT NULL,
content VARCHAR(50),
CONSTRAINT packages_pk PRIMARY KEY (packageID) # An alternative way to above,
# when you want to name the constraint as well.
);
CREATE TABLE transportation
( package INT(15) NOT NULL,
port INT(15) NOT NULL,
time DATE NOT NULL,
PRIMARY KEY (package, port, time),
FOREIGN KEY package
REFERENCES packages(packageID)
ON DELETE RESTRICT # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.
);
Definiowanie kluczy podstawowych w PostgreSQL
CREATE TABLE customers
( customerID SERIAL NOT NULL PRIMARY KEY, # In PostgreSQL SERIAL is same as AUTO_INCREMENT - it adds 1 to every new row.
last_name VARCHAR(30) NOT NULL,
first_name VARCHAR(25) NOT NULL,
address TEXT,
email VARCHAR(50) NOT NULL
);
CREATE TABLE packages
( packageID SERIAL NOT NULL,
weight NUMERIC NOT NULL,
content TEXT,
CONSTRAINT packages_pk PRIMARY KEY (packageID) # In PostgreSQL, this alternative way works too.
);
CREATE TABLE transportation
( package INTEGER NOT NULL,
port INT(15) NOT NULL,
time DATE NOT NULL,
PRIMARY KEY (package, port, time),
FOREIGN KEY package
REFERENCES packages(packageID)
ON DELETE RESTRICT # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.
);
To nie jest bardzo różne, prawda? Po zapoznaniu się z podstawami możesz zastosować je do prawie każdej bazy danych, po prostu rzucając okiem na dokumentację. Kluczem jest wiedzieć, czego szukać!
Powodzenia, młody padawan.
Podobało Ci się to? Możesz również polubić rzeczy, których nauczyłem się od starszego inżyniera oprogramowania