Mysql
 sql >> Database >  >> RDS >> Mysql

Esercitazione SQL sulla chiave primaria – Come definire una chiave primaria in un database

Ogni grande storia inizia con una crisi di identità. Luke, il grande Maestro Jedi, inizia incerto:"Chi sono io?" - e come potrei essere qualcuno di importante? Ci vuole Yoda, quello con la Forza, per insegnargli come sfruttare i suoi poteri.

Oggi, fammi essere il tuo Yoda.

Inizieremo con come scegliere una chiave primaria, combattere una crisi di identità e quindi finire con esempi di codice per creare una chiave primaria in un database.

Come scegliere una chiave primaria

Potresti pensare che Luke sia l'unico con una crisi di identità, ma non è vero. Quando si crea un database, tutto è in crisi di identità. Ed è proprio per questo che servono le chiavi primarie:risolvono la crisi. Ci dicono come trovare tutti.

Immagina di essere il governo e di voler identificare digitalmente ciascuno dei tuoi cittadini. Quindi, crei questo database con tutto ciò che li riguarda:

First Name
Last Name
Passport Number

Scegli il numero del passaporto come chiave primaria:l'identità per tutti. Pensi che sia tutto ciò di cui hai bisogno dal momento che il passaporto ha l'indirizzo e tutto il resto. Sai che i numeri di passaporto sono univoci, quindi ti senti bene e implementi questo sistema.

Poi, qualche anno dopo, si scopre una brutta verità:l'intero Paese sta affrontando una crisi di identità.

Ogni volta che il passaporto di qualcuno scade, ne riceve uno nuovo. La loro identità cambia. Altri sistemi continuano a utilizzare i vecchi numeri di passaporto, quindi ora puntano a persone fantasma.

L'unicità non basta. Il valore non deve cambiare per tutta la durata della riga.

E poi scopri che ci sono persone che non hanno nemmeno il passaporto. Non puoi inserirli nel tuo sistema, poiché le chiavi primarie non possono essere NULL . Come puoi identificare qualcuno con un NULL chiave?

Ogni riga deve avere un identificatore. NULL non consentiti.

L'iterazione successiva significa trovare un identificatore che non cambia nel tempo e che tutti hanno. In India si sta rivelando essere la carta di Adhaar. Negli USA, il numero di previdenza sociale.

Se stai creando un database, imposta quelle come chiavi primarie.

A volte, non hai alcuna chiave del genere. Considera un paese che non ha ancora un numero di previdenza sociale e desidera creare un record digitale di ogni cittadino. Potrebbero creare un nuovo SSN o semplicemente sfruttare la potenza dei database e utilizzare una chiave surrogata.

Una chiave surrogata non ha un equivalente nel mondo reale. È solo un numero all'interno di un database. Quindi, hai questa tabella nel nuovo paese:

userID
First Name
Last Name
Passport Number

I numeri di passaporto sono univoci. Ogni volta che vuoi ottenere l'identificatore di un utente, puoi ottenerlo tramite il numero di passaporto.

L'ID utente non cambia mai. Il numero del passaporto può cambiare, ma è sempre univoco, quindi ottieni sempre l'utente giusto. L'ID utente è un surrogato per un numero di previdenza sociale inesistente in questo paese.

Fatto divertente:il numero di passaporto qui è anche una chiave del candidato. Avrebbe potuto essere la chiave primaria, se non fosse mai cambiata. Questa è una distinzione di logica aziendale.

Il punto principale è questo:Ogni volta che scegli una chiave primaria, pensa a una crisi di identità . È possibile che qualcuno possa cambiare il proprio identificatore in futuro? Possiamo entrare in uno stato in cui più persone hanno lo stesso identificatore?

Uso le persone come esempio, perché rende più chiara l'identità:sappiamo che ogni persona dovrebbe avere un'identità. Trasferisci questo pensiero nei tuoi database. Tutto ha un'identità, ed è proprio per questo che hai bisogno delle chiavi primarie.

Nota:a volte è possibile e desiderabile utilizzare più colonne insieme come chiave primaria. Questa è una chiave composita.

Ora proviamo a definire le chiavi primarie con esempi di codice reale. Ci sono due cose da fare qui:in primo luogo, identificherai la chiave primaria. Quindi imparerai la sintassi per definirlo in un database.

Un esempio del mondo reale

Diciamo che gestisci una startup di spedizioni, proprio come Flexport. Hai pacchi che devono andare da un posto all'altro e navi che li trasportano. Inoltre, hai clienti che stanno ordinando questi pacchetti.

Pensi che avrai bisogno di una tabella per i clienti, una per i pacchi e una per il trasporto, che mostri quale pacco si trova in questo momento.

Pensa alle colonne di cui avrai bisogno e quale dovrebbe essere la chiave primaria. Se fossi un ingegnere di Flexport, questa è una vera domanda che dovresti capire. Niente è dato, tutto si scopre nel mondo reale.

Date queste informazioni, disegnerei queste tabelle in questo modo:

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

Ci mancano le chiavi primarie. Pensaci prima di continuare a leggere.

Per il pacchetto, sceglierò un surrogato PackageID. Avrei potuto provare ad elencare tutti gli attributi del pacco:peso, volume, densità, età. Identificherebbero in modo univoco il pacchetto, ma in pratica è molto difficile farlo. Le persone non si preoccupano di questo, si preoccupano solo del pacco che arriva da un posto all'altro.

Quindi, ha senso creare un numero casuale e usarlo come ID. Questo è esattamente il motivo per cui vedi FedEx, UPS e tutti i servizi di consegna utilizzano codici a barre e ID. Queste sono chiavi surrogate generate per tenere traccia dei pacchi.

Per il cliente, sceglierò un surrogato Identificativo del cliente. Anche in questo caso, avevo la possibilità di scegliere, diciamo, il numero di previdenza sociale dei miei clienti. Ma i clienti non vogliono condividerlo con me solo per poter spedire loro qualcosa. Pertanto, generiamo una chiave internamente, non informiamo i nostri clienti di questa chiave e continuiamo a chiamarli CustomerNo. 345681.

Storia divertente:conosco alcune aziende in cui hanno esposto questo CustomerNo, e i clienti hanno insistito per ottenere il numero 1. È stato piuttosto esilarante:gli ingegneri hanno effettivamente dovuto modificare il loro codice front-end in:if (cust == 345681) print(1);

Per i trasporti, sceglierò un composito PackageID+Porta+ora. Questo è un po' più interessante. Avrei potuto creare un surrogato anche qui, e funzionerebbe altrettanto bene.

Ma qui sta la magia dell'indicizzazione. Le chiavi primarie ottengono un indice automaticamente, il che significa che la ricerca è molto più efficiente rispetto alle chiavi primarie.

Durante la ricerca in questo database, la maggior parte delle query sarà nella forma "dov'è questo pacchetto?". In altre parole, dato questo PackageID, dimmi la porta e l'ora in cui si trova in questo momento. Avrei bisogno di un indice aggiuntivo su PackageID se non lo ho come parte della mia chiave primaria.

Questo suona bene? Passaggio finale, definiamo queste 3 tabelle in SQL. La sintassi varia leggermente con il database che stai utilizzando.

Definizione delle chiavi primarie 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.

);

Definizione delle chiavi primarie 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.

);

Non è molto diverso, vero? Una volta apprese le nozioni di base, puoi applicarle a quasi tutti i database con una rapida occhiata alla documentazione. La chiave è sapere cosa cercare!

Buona fortuna, giovane padawan.

Ti è piaciuto questo? Potrebbe piacerti anche Cose che ho imparato da un ingegnere software senior