Enhver stor historie starter med en identitetskrise. Luke, den store Jedi-mester, begynder usikker - "Hvem er jeg?" - og hvordan kunne jeg være nogen vigtig? Det kræver Yoda, ham med Kraften, at lære ham at udnytte sine kræfter.
I dag, lad mig være din Yoda.
Vi starter med, hvordan man vælger en primær nøgle, bekæmper en identitetskrise og afslutter med kodeeksempler til at oprette en primær nøgle i en database.
Sådan vælger du en primær nøgle
Du tror måske, at Luke er den eneste med en identitetskrise, men det er ikke sandt. Når man opretter en database, er alt i en identitetskrise. Og det er netop derfor, vi har brug for primære nøgler:de løser krisen. De fortæller os, hvordan vi finder alle.
Forestil dig, at du er regeringen, og du vil identificere hver enkelt af dine borgere digitalt. Så du opretter denne database med alt om dem:
First Name
Last Name
Passport Number
Du vælger pasnummeret som den primære nøgle - identiteten for alle. Du regner med, at det er alt, du behøver, da passet har adressen og alt muligt andet. Du ved, at pasnumre er unikke, så du har det godt og implementerer dette system.
Så, et par år senere, finder du ud af en grim sandhed:hele landet står over for en identitetskrise.
Når nogens pas udløber, får de et nyt. Deres identitet ændrer sig. Andre systemer bliver ved med at bruge de gamle pasnumre, så de peger nu på spøgelsesmennesker.
Unikitet er ikke nok. Værdien må ikke ændre sig i hele rækkens levetid.
Og så opdager du, at der er nogle mennesker, der ikke engang har pas. Du kan ikke indtaste dem i dit system, da primære nøgler ikke kan være NULL
. Hvordan kan du identificere nogen med en NULL
nøgle?
Hver række skal have en identifikator. NULL er ikke tilladt.
Den næste iteration betyder at finde en identifikator, der ikke ændrer sig over tid, og en som alle har. I Indien viser det sig at være Adhaar-kortet. I USA, Social Security Number.
Hvis du opretter en database, skal du gøre dem til dine primære nøgler.
Nogle gange har du ikke sådan en nøgle. Overvej et land, der endnu ikke har et CPR-nummer, og de ønsker at oprette en digital registrering af alle borgere. De kunne oprette et nyt SSN, eller de kunne bare udnytte kraften i databaser og bruge en surrogatnøgle.
En surrogatnøgle har ingen ækvivalent i den virkelige verden. Det er bare et tal inde i en database. Så du har denne tabel i det nye land:
userID
First Name
Last Name
Passport Number
Pasnumre er unikke. Når du ønsker at få identifikationen for en bruger, kan du få den via pasnummeret.
Bruger-ID'et ændres aldrig. Pasnummeret kan ændres – men det er altid unikt, så du altid får den rigtige bruger. Bruger-ID'et er en surrogat for et ikke-eksisterende CPR-nummer i dette land.
Sjovt faktum:Pasnummeret her er også en kandidatnøgle. Det kunne have været den primære nøgle, hvis den aldrig ændrede sig. Dette er en forretningslogisk skelnen.
Den vigtigste takeaway er dette:Når du vælger en primær nøgle, så tænk på en identitetskrise . Er det muligt, at nogen ændrer deres identifikator i fremtiden? Kan vi komme ind i en tilstand med flere personer, der har samme identifikator?
Jeg bruger mennesker som eksempel, fordi det gør identiteten mere tydelig – vi ved, at hver person formodes at have en identitet. Overfør denne tankegang til dine databaser. Alt har en identitet, og det er netop derfor, du har brug for primære nøgler.
Bemærk:Nogle gange er det muligt og ønskeligt at bruge flere kolonner sammen som den primære nøgle. Dette er en sammensat nøgle.
Lad os nu prøve at definere Primære nøgler med rigtige kodeeksempler. Der er to ting at gøre her:For det første skal du identificere den primære nøgle. Derefter lærer du syntaksen til at definere det i en database.
Et eksempel fra den virkelige verden
Lad os sige, at du kører en forsendelsesopstart, ligesom Flexport. Du har pakker, der skal fra et sted til et andet, og skibe, der transporterer dem. Derudover har du kunder, der bestiller disse pakker.
Du regner med, at du skal bruge et bord til kunderne, et til pakkerne og et til transport, der viser, hvilken pakke der er lige nu.
Tænk igennem, hvilke kolonner du skal bruge, og hvad der skal være den primære nøgle. Hvis du var ingeniør hos Flexport, er dette et reelt spørgsmål, du skulle finde ud af. Intet er givet, alt bliver opdaget i den virkelige verden.
Med disse oplysninger ville jeg designe disse tabeller sådan:
Customers: first_name, last_name, email, address (for deliveries to their location)
Packages: weight, content
Transportation: <package_primary_key>, Port, time
Vi mangler de primære nøgler. Tænk over dem, før du læser videre.
Til pakken vælger jeg en surrogat Pakke-ID. Jeg kunne have forsøgt at liste alle pakkens egenskaber:vægt, volumen, tæthed, alder. De ville entydigt identificere pakken, men det er meget svært at gøre i praksis. Folk er ligeglade med det her, de bekymrer sig bare om, at pakken kommer fra et sted til et andet.
Så det giver mening at oprette et tilfældigt tal og bruge det som ID. Det er præcis grunden til, at du ser FedEx, UPS og alle leveringstjenester bruge stregkoder og ID'er. Disse er surrogatnøgler, der er genereret for at spore pakker.
For kunden vælger jeg en surrogat Kunde ID. Her havde jeg igen mulighed for at vælge f.eks. mine kunders CPR-nummer. Men kunder ønsker ikke at dele dette med mig, bare så jeg kan sende dem noget. Derfor genererer vi en nøgle internt, fortæller ikke vores kunder om denne nøgle, og fortsætter med at kalde dem Kundenr. 345681.
Sjov historie:Jeg kender et par virksomheder, hvor de afslørede dette kundenummer, og kunderne insisterede på, at de fik nr. 1. Det var ret morsomt - ingeniørerne var faktisk nødt til at ændre deres frontend-kode til:if (cust == 345681) print(1);
Til transport vælger jeg en komposit Pakke-ID+Port+tid. Det her er lidt mere interessant. Jeg kunne have oprettet en surrogat også her, og det ville fungere lige så godt.
Men her ligger magien ved indeksering. De primære nøgler får automatisk et indeks, hvilket betyder, at søgning er meget mere effektiv i forhold til primære nøgler.
Når du søger gennem denne database, vil de fleste forespørgsler have formen "hvor er denne pakke?". Med andre ord, givet dette pakke-ID, fortæl mig den port og det tidspunkt, det er på lige nu. Jeg har brug for et ekstra indeks over PackageID, hvis jeg ikke har det som en del af min primære nøgle.
Lyder det her godt? Sidste trin, lad os definere disse 3 tabeller i SQL. Syntaksen varierer lidt med den database, du bruger.
Definering af primære nøgler i 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.
);
Definering af primære nøgler i 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.
);
Det er ikke meget anderledes, vel? Når du har fået det grundlæggende ned, kan du anvende det på næsten enhver database med blot et hurtigt kig på dokumentationen. Nøglen er at vide, hvad man skal kigge efter!
Held og lykke, unge padawan.
Nydt dette? Du kan måske også lide Ting, jeg har lært af en senior softwareingeniør