Indirizzo email chiave unica o primaria?


11

Sono un principiante nei database. Ho letto in giro e ho scoperto che probabilmente non è una buona idea usare l'indirizzo e-mail come chiave primaria perché i confronti di stringhe sono più lenti che influiscono sulle prestazioni in join complessi e se un'e-mail cambia dovrei cambiare tutte le chiavi esterne che richiedono molto di sforzo.

Ma se la tabella dei miei utenti richiede che tutti gli utenti dispongano di un indirizzo e-mail e ciascuno di essi sia univoco, sarà sufficiente aggiungere un indice univoco nella colonna e-mail? Perché i campi univoci di afaik consentono valori null, mentre richiedo a tutti gli utenti di avere un indirizzo e-mail, non consentendo valori null. C'è qualcosa che mi manca qui? Oppure suppongo di rendere unica la colonna e-mail e di accertarmi durante la convalida dei dati sul server che l'utente inserisca un indirizzo e-mail in modo che ogni utente ne abbia uno?


3
Cosa succede quando un utente cambia il suo indirizzo e-mail, come ad esempio cambierà lavoro
user151019

1
I confronti delle stringhe non sono solo più lenti, le stringhe tendono anche ad essere più grandi di dire un numero intero e quindi puoi inserirne meno in una pagina in memoria, aumentando le tue letture logiche per le query.
Senza nome, il

Risposte:


7

Per prima cosa distinguiamo tra chiavi e indici, la chiave fa parte del modello logico ed è spesso implementata con un indice univoco. È tuttavia possibile creare un indice univoco senza creare una chiave, ma a cui non è possibile fare riferimento da una chiave esterna.

Una chiave candidata è qualcosa che identifica in modo univoco una riga in una tabella, in SQL una delle chiavi candidate viene normalmente utilizzata come chiave primaria (non ho mai veramente capito perché uno dei ck sia considerato "migliore" degli altri, ma questo è un altro storia), e il ck rimanente diventa vincoli unici.

Un vincolo univoco può essere utilizzato allo stesso modo di una chiave primaria. Prendere in considerazione:

create table A ( x ... not null
               , y ... not null
               , z ... not null
               ,     unique (x)
               ,     primary key (y,z) );

create table B ( x ...
               ,   ...
               ,     foreign key (x) references A (x) );

create table C ( y ...
               , z ...
               ,   ...
               ,     foreign key (y, z) references A (y, z) );  

B fa riferimento al vincolo univoco e C fa riferimento al vincolo della chiave primaria.

NOT NULL è ancora un altro tipo di vincolo. Nel tuo caso puoi applicarlo per e-mail senza dichiararlo unico.

L'aspetto successivo del tuo post riguarda la stabilità di una chiave, una chiave dovrebbe essere stabile (ma ciò non significa che non possa mai cambiare, non deve essere immutabile). Alcuni DBMS implementano ON UPDATE CASCADE che possono essere di aiuto per tale operazione, tuttavia se la chiave è distribuita attorno al modello sarà un problema aggiornarlo.

Nel tuo caso, sceglierei probabilmente un'altra chiave candidata come chiave primaria e dichiarerei che l'email NON è NULL e UNICA.


1
In SQL Server è possibile fare riferimento a un indice univoco come FK.
Martin Smith,

1
Non ho accesso a sql, quindi non posso verificare da solo, crea implicitamente un vincolo univoco quando crei un indice univoco?
Lennart,

1
No. Un vincolo univoco viene trattato in modo leggermente diverso e presenta alcuni metadati e restrizioni aggiuntive rispetto a un indice univoco, ma SQL Server consente di utilizzare entrambi in un FK.
Martin Smith,

1
È un po 'strano quindi, gli indici non sono nemmeno menzionati nello standard sql mentre le chiavi ne sono una parte centrale. Comunque, grazie per l'informazione.
Lennart,

Vale la pena notare che se ci sono molti record con chiave esterna nella tua e-mail, può richiedere un bel po 'di tempo per aggiornare tutti quei record quando l'aggiornamento procede in sequenza.
cimmanon,

6

Sì, avere un indice univoco nella colonna EmailAddress dovrebbe essere ok. L'unico problema sarebbe se qualcuno avesse rinunciato all'indirizzo e-mail dopo essersi registrato al tuo servizio ma non te lo avesse detto, quindi chiunque il proprietario dell'indirizzo e-mail provasse a registrarsi. Ma questo è un caso abbastanza raro.

Se un indice univoco consenta valori nulli che dipenderanno dalla piattaforma del database. Oracle lo fa, SQL Server consente un singolo valore NULL. È possibile risolvere questo problema facendo in modo che la colonna non consenta valori NULL, quindi costruendo l'indice univoco su di esso.


1
Questo non è vero su SQL Server. È possibile creare indici con whereclausole che, ad esempio, consentono di escludere NULLvalori dall'indice.
Kirk Woll,

1
L'affermazione SQL Server allows a single NULL valueè ancora vera. Non dice che non c'è modo di ottenere più NULLvalori. Penso che il risponditore stesse cercando di mantenere la risposta semplice e non spiegare ulteriori dettagli (come filtrati indicizzati).
Brandon,

1
Sì, avrei potuto analizzare l'intero coniglio di indici filtrati, ma una semplice domanda di solito ha bisogno di una risposta semplice. Senza una piattaforma e una versione di database mantengo le mie risposte generiche.
mrdenny,

2

Avere l'indice univoco su EmailAddress va bene.

Dato che hai già dichiarato che esiste una convalida nella tua domanda per avere l'indirizzo e-mail come campo obbligatorio, direi che l'altra convalida sarebbe dal database non accettare un utente senza un indirizzo e-mail e impedire anche l'inserimento duplicato e queste convalide verrà imposto con questo indice univoco.

Come indicato in un'altra risposta per SQL Server, è necessario creare una colonna che non consenta il valore null prima di creare indici univoci.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.