Dirección de correo electrónico clave única o primaria?


11

Soy un novato en bases de datos. Leí y descubrí que probablemente no sea una buena idea usar la dirección de correo electrónico como clave principal porque las comparaciones de cadenas son más lentas, lo que afecta el rendimiento en combinaciones complejas y si un correo electrónico cambia, tendría que cambiar todas las claves externas, lo que requiere mucho de esfuerzo

Pero si mi tabla de usuarios requiere que cada usuario tenga una dirección de correo electrónico y cada una de esas direcciones de correo electrónico debe ser única, ¿será suficiente agregar un índice único en la columna de correo electrónico? Porque los campos únicos de afaik permiten valores nulos, mientras que requiero que cada usuario tenga una dirección de correo electrónico, no permitiendo valores nulos. ¿Hay algo que me falta aquí? ¿O se supone que debo hacer que la columna de correo electrónico sea única y asegurarme durante la validación de datos en el servidor de que el usuario ingrese una dirección de correo electrónico para que cada usuario tenga una?


3
¿Qué ocurre cuando un usuario cambia su dirección de correo electrónico - ya que, por ejemplo, cambiar de trabajo
user151019

1
Las comparaciones de cadenas no solo son más lentas, las cadenas también tienden a ser más grandes que, digamos, un número entero, y por lo tanto, puede caber menos en una página en la memoria, elevando sus lecturas lógicas para consultas.
Sin nombre

Respuestas:


7

Primero distingamos entre claves e índices, la clave es parte del modelo lógico y a menudo se implementa con un índice único. Sin embargo, puede crear un índice único sin crear una clave, pero eso no puede ser referenciado por una clave externa.

Una clave candidata es algo que identifica de forma exclusiva una fila en una tabla, en SQL una de las claves candidatas se usa normalmente como clave primaria (nunca entendí realmente por qué una de las ck se considera "mejor" que las otras, pero esa es otra historia), y el ck restante se convierte en restricciones únicas.

Una restricción única se puede utilizar de la misma manera que una clave primaria. Considerar:

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 hace referencia a la restricción única y C hace referencia a la restricción de clave principal.

NOT NULL es otro tipo de restricción. En su caso, puede aplicar esto para el correo electrónico sin declararlo único.

El siguiente aspecto de su publicación se refiere a la estabilidad de una clave, una clave debe ser estable (pero eso no significa que nunca pueda cambiar, no tiene que ser inmutable). Algunos DBMS implementan ON UPDATE CASCADE que pueden ser de ayuda para dicha operación, aunque si la clave se distribuye alrededor de su modelo, será una molestia actualizarla.

En su caso, probablemente elegiría otra clave candidata como clave principal y declararía que el correo electrónico NO ES NULO ni ÚNICO.


1
En SQL Server puede hacer referencia a un índice único como un FK.
Martin Smith

1
No tengo acceso a sql, así que no puedo verificarlo por mí mismo, ¿crea implícitamente una restricción única cuando crea un índice único?
Lennart

1
No. Una restricción única se trata de manera ligeramente diferente y tiene algunos metadatos adicionales y restricciones adicionales en comparación con un índice único, pero SQL Server permite que cualquiera de los dos se use en un FK.
Martin Smith

1
Eso es un poco extraño, los índices ni siquiera se mencionan en el estándar sql, mientras que las claves son una parte central de él. De todos modos, gracias por la información.
Lennart

Vale la pena señalar que si hay muchos registros con clave externa para su correo electrónico, puede llevar bastante tiempo actualizar todos esos registros cuando la actualización caiga en cascada.
cimmanon

6

Sí, tener un índice único en la columna EmailAddress debería estar bien. El único problema sería si alguien renunciara a la dirección de correo electrónico después de suscribirse a su servicio pero no se lo dijera, entonces quien sea el propietario de la dirección de correo electrónico intente registrarse. Pero ese es un caso marginal bastante raro.

En cuanto a si un índice único permite valores nulos que dependerán de su plataforma de base de datos. Oracle lo hace, SQL Server permite un único valor NULL. Puede resolver esto haciendo que la columna no permita valores NULL, luego construyendo el índice único en él.


1
Eso no es cierto sobre el servidor SQL. Puede crear índices con wherecláusulas que, por ejemplo, le permiten excluir NULLvalores del índice.
Kirk Woll

1
La afirmación SQL Server allows a single NULL valuesigue siendo cierta. No dice que no hay forma de obtener múltiples NULLvalores. Creo que el respondedor estaba tratando de mantener la respuesta simple y no explicar detalles adicionales (como indexado filtrado).
Brandon

1
Sí, podría haber hundido el conejo completo de índices filtrados, pero una pregunta simple generalmente necesita una respuesta simple. Sin una plataforma de base de datos y una versión, mantengo mis respuestas genéricas.
mrdenny

2

Tener el índice único en EmailAddress está bien.

Como ya ha dicho que hay una validación en su solicitud para tener la dirección de correo electrónico como campo requerido, diría que la otra validación sería de la base de datos, no se acepta a un usuario sin una dirección de correo electrónico y se evita la entrada duplicada y estas validaciones se impondrá con este índice único.

Como se indicó en otra respuesta para SQL Server, debe hacer una columna que no permita un valor nulo antes de crear índices únicos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.