sql >> Database >  >> RDS >> Mysql

Primaire sleutel SQL-zelfstudie - Hoe een primaire sleutel in een database te definiëren

Elk geweldig verhaal begint met een identiteitscrisis. Luke, de grote Jedi Master, begint onzeker - "Wie ben ik?" - en hoe kan ik iemand belangrijk zijn? Yoda, degene met de Force, heeft hem nodig om hem te leren hoe hij zijn krachten kan gebruiken.

Laat mij vandaag je Yoda zijn.

We beginnen met het kiezen van een primaire sleutel, het bestrijden van een identiteitscrisis en eindigen met codevoorbeelden voor het maken van een primaire sleutel in een database.

Een primaire sleutel kiezen

Je denkt misschien dat Luke de enige is met een identiteitscrisis, maar dat is niet waar. Bij het maken van een database bevindt alles zich in een identiteitscrisis. En dat is precies waarom we primaire sleutels nodig hebben:ze lossen de crisis op. Ze vertellen ons hoe we iedereen kunnen vinden.

Stel, u bent de overheid en u wilt al uw burgers digitaal identificeren. Dus je maakt deze database met alles over hen:

First Name
Last Name
Passport Number

U kiest het paspoortnummer als de primaire sleutel - de identiteit voor iedereen. Je denkt dat dat alles is wat je nodig hebt, aangezien het paspoort het adres en al het andere heeft. U weet dat paspoortnummers uniek zijn, dus u voelt zich goed en implementeert dit systeem.

Dan, een paar jaar later, ontdek je een lelijke waarheid:het hele land kampt met een identiteitscrisis.

Wanneer iemands paspoort verloopt, krijgen ze een nieuwe. Hun identiteit verandert. Andere systemen blijven de oude paspoortnummers gebruiken, zodat ze nu naar spookmensen verwijzen.

Uniek is niet genoeg. De waarde mag niet veranderen gedurende de levensduur van de rij.

En dan zie je dat er mensen zijn die niet eens een paspoort hebben. U kunt ze niet in uw systeem invoeren, aangezien primaire sleutels niet NULL kunnen zijn . Hoe herken je iemand met een NULL sleutel?

Elke rij moet een identifier hebben. NULL's niet toegestaan.

De volgende iteratie betekent het vinden van een identifier die in de loop van de tijd niet verandert en die iedereen heeft. In India blijkt dit de Adhaar Card te zijn. In de VS, het burgerservicenummer.

Als je een database aan het maken bent, maak daar dan je primaire sleutels van.

Soms heb je zo'n sleutel niet. Denk aan een land dat nog geen burgerservicenummer heeft en dat van elke burger een digitaal dossier wil maken. Ze kunnen een nieuw SSN maken, of ze kunnen gewoon gebruikmaken van de kracht van databases en een surrogaatsleutel gebruiken.

Een surrogaatsleutel heeft geen equivalent in de echte wereld. Het is gewoon een getal in een database. Dus je hebt deze tabel in het nieuwe land:

userID
First Name
Last Name
Passport Number

Paspoortnummers zijn uniek. Wanneer u de identificatie van een gebruiker wilt krijgen, kunt u deze verkrijgen via het paspoortnummer.

De gebruikers-ID verandert nooit. Het paspoortnummer kan veranderen, maar het is altijd uniek, dus u krijgt altijd de juiste gebruiker. De gebruikers-ID is een surrogaat voor een niet-bestaand burgerservicenummer in dit land.

Leuk weetje:het paspoortnummer is hier ook een kandidaatsleutel. Het zou de primaire sleutel kunnen zijn, als het nooit is veranderd. Dit is een onderscheid in bedrijfslogica.

De belangrijkste conclusie is dit:Als u een primaire sleutel kiest, denk dan aan een identiteitscrisis . Is het mogelijk dat iemand in de toekomst zijn ID wijzigt? Kunnen we in een toestand komen waarin meerdere mensen dezelfde identificatie hebben?

Ik gebruik mensen als voorbeeld, omdat het identiteit duidelijker maakt - we weten dat iedereen een identiteit zou moeten hebben. Breng deze denkwijze over naar uw databases. Alles heeft een identiteit, en dat is precies waarom je primaire sleutels nodig hebt.

Opmerking:soms is het mogelijk en wenselijk om meerdere kolommen samen als de primaire sleutel te gebruiken. Dit is een samengestelde sleutel.

Laten we nu proberen primaire sleutels te definiëren met echte codevoorbeelden. U moet hier twee dingen doen:eerst identificeert u de primaire sleutel. Vervolgens leert u de syntaxis om deze in een database te definiëren.

Een voorbeeld uit de echte wereld

Laten we zeggen dat u een scheepvaartstartup runt, net zoals Flexport. Je hebt pakketten die van de ene plaats naar de andere moeten, en schepen die ze vervoeren. Verder heb je klanten die deze pakketten bestellen.

Je denkt dat je één tafel nodig hebt voor de klanten, één voor de pakketten en één voor het transport, zodat je kunt zien welk pakket waar op dit moment is.

Bedenk welke kolommen u nodig heeft en wat de primaire sleutel moet zijn. Als je engineer bij Flexport was, is dit een echte vraag die je zou moeten oplossen. Niets wordt gegeven, alles wordt ontdekt in de echte wereld.

Met deze informatie zou ik deze tabellen als volgt ontwerpen:

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

We missen de primaire sleutels. Denk erover na voordat je verder leest.

Als pakket kies ik een surrogaat Pakket-ID. Ik had kunnen proberen om alle kenmerken van het pakket op te sommen:gewicht, volume, dichtheid, leeftijd. Ze zouden het pakket uniek identificeren, maar dit is in de praktijk erg moeilijk. Mensen geven er niet om, ze geven er alleen om dat het pakket van de ene plaats naar de andere gaat.

Het is dus logisch om een ​​willekeurig getal te maken en dat als ID te gebruiken. Dit is precies waarom je ziet dat FedEx, UPS en elke bezorgservice streepjescodes en ID's gebruiken. Dit zijn surrogaatsleutels die worden gegenereerd om pakketten te volgen.

Voor de klant kies ik een surrogaat Klanten ID. Ook hier had ik de mogelijkheid om bijvoorbeeld het burgerservicenummer van mijn klanten te kiezen. Maar klanten willen dit niet met mij delen, alleen maar om ze iets te kunnen sturen. We genereren dus intern een sleutel, vertellen onze klanten niets over deze sleutel en blijven ze Klantnr noemen. 345681.

Leuk verhaal:ik ken een paar bedrijven waar ze dit klantnr hebben onthuld, en de klanten stonden erop nummer 1 te krijgen. Het was behoorlijk hilarisch - de technici moesten hun front-endcode eigenlijk veranderen in:if (cust == 345681) print(1);

Voor vervoer kies ik een composiet Pakket-ID+Poort+tijd. Dit is wat interessanter. Ik had een surrogaat kunnen maken hier ook, en het zou net zo goed werken.

Maar hier ligt de magie van indexeren. De Primary Keys krijgen automatisch een index, wat betekent dat zoeken een stuk efficiënter is dan Primary Keys.

Wanneer u door deze database zoekt, zullen de meeste zoekopdrachten de vorm hebben van "waar is dit pakket?". Met andere woorden, gezien deze PackageID, vertel me de poort en tijd waarop het zich nu bevindt. Ik zou een extra index boven PackageID nodig hebben als ik deze niet als onderdeel van mijn primaire sleutel heb.

Klinkt dit goed? Laatste stap, laten we deze 3 tabellen in SQL definiëren. De syntaxis varieert enigszins met de database die u gebruikt.

Primaire sleutels definiëren in 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.

);

Primaire sleutels definiëren in 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.

);

Het is niet heel anders, toch? Als je eenmaal de basis onder de knie hebt, kun je het op bijna elke database toepassen met een snelle blik op de documentatie. De sleutel is weten waar je op moet letten!

Veel succes, jonge Padawan.

Genoten hiervan? Misschien ben je ook geïnteresseerd in Dingen die ik heb geleerd van een senior software-ingenieur



  1. Kan niet valideren, met novalidate-optie

  2. Hoe het mysql root-wachtwoord te wijzigen?

  3. Gebruik APP_NAME() om de toepassingsnaam van de huidige sessie in SQL Server op te halen

  4. SQL, querybuilders en ORM's vergelijken