Fiecare poveste grozavă începe cu o criză de identitate. Luke, marele Maestru Jedi, începe nesigur – “Cine sunt?” – și cum aș putea fi cineva important? Este nevoie de Yoda, cel cu Forța, pentru a-l învăța cum să-și valorifice puterile.

Astăzi, lasă-mă să fiu Yoda ta.

Vom începe cu cum să alegem o cheie primară, să luptăm împotriva unei crize de identitate și apoi să terminăm cu exemple de cod pentru crearea unei chei primare într-o bază de date.

Cum să alegeți o cheie primară

S-ar putea să credeți că Luke este singurul cu o criză de identitate, dar asta nu este adevărat. Când creați o bază de date, totul se află într-o criză de identitate. Și tocmai de aceea avem nevoie de chei primare: ele rezolvă criza. Ne spun cum să găsim pe toată lumea.

Imaginați-vă că sunteți guvernul și doriți să identificați fiecare dintre cetățenii dvs. în mod digital. Deci, creați această bază de date cu tot ceea ce privește:

First Name
Last Name
Passport Number

Alegeți numărul pașaportului ca cheie principală – identitatea pentru toată lumea. Vă gândiți că asta este tot ce aveți nevoie, deoarece pașaportul are adresa și toate celelalte. Știți că numerele pașapoartelor sunt unice, așa că vă simțiți bine și implementați acest sistem.

Apoi, câțiva ani mai târziu, afli un adevăr urât: întreaga țară se confruntă cu o criză de identitate.

Ori de câte ori pașaportul cuiva expiră, primește unul nou. Identitatea lor se schimbă. Alte sisteme folosesc în continuare numerele vechi ale pașaportului, așa că acum indică oamenii fantomă.

Unicitatea nu este suficientă. Valoarea nu trebuie să se schimbe pe toată durata de viață a rândului.

Și apoi, găsiți că există unii oameni care nici măcar nu au pașapoarte. Nu le puteți introduce în sistemul dvs., deoarece tastele primare nu pot fi NULL. Cum poți identifica pe cineva cu un NULL cheie?

Fiecare rând trebuie să aibă un identificator. NULL-urile nu sunt permise.

Următoarea iterație înseamnă găsirea unui identificator care nu se schimbă în timp și pe care îl are toată lumea. În India, aceasta se dovedește a fi Cardul Adhaar. În SUA, numărul de securitate socială.

Dacă creați o bază de date, faceți din acestea cheile dvs. principale.

Uneori, nu aveți o astfel de cheie. Luați în considerare o țară care nu are încă un număr de securitate socială și doresc să creeze o înregistrare digitală a fiecărui cetățean. Ar putea crea un nou SSN sau ar putea doar să profite de puterea bazelor de date și să folosească o cheie surogat.

O cheie surogat nu are echivalent în lumea reală. Este doar un număr dintr-o bază de date. Deci, aveți acest tabel în noua țară:

userID
First Name
Last Name
Passport Number

Numerele pașaportului sunt unice. Ori de câte ori doriți să obțineți identificatorul pentru un utilizator, îl puteți obține prin numărul pașaportului.

ID-ul utilizatorului nu se schimbă niciodată. Numărul pașaportului se poate schimba – dar este întotdeauna unic, astfel încât să obțineți întotdeauna utilizatorul potrivit. ID-ul utilizator este un surogat pentru un număr de securitate socială inexistent în această țară.

Fapt amuzant: numărul pașaportului aici este, de asemenea, o cheie de candidat. Ar fi putut fi cheia primară, dacă nu s-a schimbat niciodată. Aceasta este o distincție logică de afaceri.

Principala plată este următoarea: Ori de câte ori alegeți o cheie primară, gândiți-vă la o criză de identitate. Este posibil ca cineva să-și schimbe identificatorul în viitor? Putem ajunge într-un stat cu mai mulți oameni care au același identificator?

Folosesc oamenii ca exemplu, deoarece clarifică identitatea – știm că fiecare persoană ar trebui să aibă o identitate. Transferați această gândire în bazele de date. Totul are o identitate, tocmai de aceea ai nevoie de chei primare.

Notă: Uneori, este posibil și de dorit să utilizați mai multe coloane împreună ca cheie primară. Aceasta este o cheie compusă.

Acum, să încercăm să definim cheile principale cu exemple de coduri reale. Există două lucruri de făcut aici: mai întâi, veți identifica cheia primară. Apoi, veți învăța sintaxa pentru definirea acesteia într-o bază de date.

Un exemplu real

Să presupunem că rulați o pornire de expediere, la fel ca Flexport. Aveți pachete care trebuie să ajungă dintr-un loc în altul și nave care le transportă. Mai mult, aveți clienți care comandă aceste pachete.

Vă închipuiți că veți avea nevoie de o masă pentru clienți, una pentru pachete și una pentru transport, arătând care pachet este locul în acest moment.

Gândiți-vă la ce coloane veți avea nevoie și care ar trebui să fie cheia principală. Dacă ați fi inginer la Flexport, aceasta este o întrebare reală pe care ar trebui să o dați seama. Nimic nu este dat, totul este descoperit în lumea reală.

Având în vedere aceste informații, aș proiecta aceste tabele astfel:

Customers: first_name, last_name, email, address (for deliveries to their location)
Packages: weight, content
Transportation: <package_primary_key>, Port, time

Ne lipsesc cheile principale. Gândiți-vă la ele înainte de a citi mai departe.

Pentru pachet, voi alege un surogat ID pachet. Aș fi putut încerca să enumer toate atributele pachetului: greutate, volum, densitate, vârstă. Vor identifica în mod unic pachetul, dar acest lucru este foarte greu de realizat în practică. Oamenilor nu le pasă de acest lucru, ci doar de pachetul care ajunge dintr-un loc în altul.

Deci, este logic să creați un număr aleatoriu și să îl utilizați ca ID. Acesta este exact motivul pentru care vedeți FedEx, UPS și fiecare serviciu de livrare utilizează coduri de bare și ID-uri. Acestea sunt chei surogate generate pentru a urmări pachetele.

Pentru client, voi alege un surogat Număr de înregistrare client. Aici, din nou, am avut opțiunea de a alege, să zicem, numărul de securitate socială al clienților mei. Dar, clienții nu doresc să împărtășească acest lucru cu mine doar pentru a le putea livra ceva. Astfel, generăm o cheie pe plan intern, nu le spunem clienților despre această cheie și continuăm să le numim CustomerNo. 345681.

Poveste amuzantă: Știu câteva companii în care au expus acest CustomerNo, iar clienții au insistat să obțină numărul 1. if (cust == 345681) print(1);

Pentru Transport, voi alege un compozit PackageID + Port + timp. Este ceva mai interesant. Aș fi putut crea un surogat și aici și ar funcționa la fel de bine.

Dar aici se află magia indexării. Tastele primare primesc automat un index, ceea ce înseamnă căutarea este mult mai eficientă față de tastele primare.

Când căutați prin această bază de date, cele mai multe interogări vor avea forma „unde este acest pachet?”. Cu alte cuvinte, având în vedere acest PackageID, spuneți-mi portul și ora la care se află acum. Aș avea nevoie de un index suplimentar peste PackageID dacă nu îl am ca parte a cheii mele principale.

Sună bine? Pasul final, să definim aceste 3 tabele în SQL. Sintaxa variază ușor în funcție de baza de date pe care o utilizați.

Definirea cheilor primare în 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.

);

Definirea cheilor primare în 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.

);

Nu este foarte diferit, nu-i așa? Odată ce obțineți elementele de bază în jos, îl puteți aplica la aproape orice bază de date, doar cu o privire rapidă asupra documentației. Cheia este să știi ce să cauți!

Noroc, tânăr padawan.

Ti-a placut asta? S-ar putea sa-ti placa si Lucruri pe care le-am învățat de la un inginer software principal