sql - tabla - ¿Por qué utilizar una clave principal de incremento automático cuando existen otros campos únicos?
que es una clave principal de campo simple (12)
Estoy tomando un curso llamado "sistemas de bases de datos" y para nuestro proyecto de clase tengo que diseñar un sitio web.
Aquí hay un ejemplo de una tabla que creé:
CREATE TABLE users
(
uid INT NOT NULL AUTO_INCREMENT,
username VARCHAR(60),
passhash VARCHAR(255),
email VARCHAR(60),
rdate DATE,
PRIMARY KEY(uid)
);
El profesor me dijo que "uid" (identificación de usuario) era completamente inútil e innecesario, y debería haber usado el nombre de usuario como clave principal, ya que ningún usuario puede tener el mismo nombre de usuario.
Le dije que era conveniente para mí usar una identificación de usuario porque cuando llamo a algo como domain.com/viewuser?id=5 simplemente miro el parámetro con: is_numeric($_GET[''id''])
... no hace falta decirlo él no estaba convencido.
Como he visto user_id y otros atributos similares (thread_id, comment_id, entre otros) en muchos tutoriales y mirando el esquema de la base de datos del software popular (por ejemplo, vbulletin), debe haber muchas otras razones (más fuertes).
Así que mi pregunta es: ¿cómo justificaría la necesidad de una identificación no incremental auto nulo como clave principal frente a otro atributo como el nombre de usuario?
¿Y desea almacenar sus nombres de usuario en texto sin cifrar para que alguien robe? Nunca consideraría usar una clave natural que podría cifrar algún día (o si quisiera encriptar ahora).
Debido a que se supone que userid es único (no se puede duplicar) y algunas veces es índice.
Esto generalmente se llama una clave sustituta y tiene muchos beneficios. Una de ellas es aislar las relaciones de su base de datos de los datos de la aplicación. Se pueden encontrar más detalles y las desventajas correspondientes en el enlace de la wiki provisto arriba.
Las claves primarias de incremento automático son útiles por varias razones:
- Permiten nombres de usuario duplicados como en Desbordamiento de pila
- Permiten cambiar el nombre de usuario (o la dirección de correo electrónico, si se utiliza para iniciar sesión) (fácilmente)
- Las selecciones, las uniones y las inserciones son más rápidas que las claves primarias varchar, ya que es mucho más rápido mantener un índice numérico
- Como mencionaste, la validación se vuelve muy simple:
if ((int)$id > 0) { ... }
- El saneamiento de la entrada es trivial:
$id = (int)$_GET[''id'']
- Hay mucha menos sobrecarga, ya que las claves externas no tienen que duplicar valores de cadena potencialmente grandes.
Diría que tratar de usar cualquier información de cadena como un identificador único para un registro es una mala idea cuando una clave numérica de auto incremento está tan disponible.
Los sistemas con nombres de usuario únicos están bien para un número muy reducido de usuarios, pero Internet los ha dañado fundamentalmente. Cuando considera la gran cantidad de personas llamadas "john" que podrían tener que interactuar con un sitio web, es ridículo exigir que cada uno de ellos use un nombre único para mostrar. Conduce al horrible sistema que vemos con tanta frecuencia con dígitos aleatorios y letras que decoran un nombre de usuario.
Sin embargo, incluso en un sistema donde se aplicaron nombres de usuario únicos, sigue siendo una mala elección para una clave principal. Imagine un usuario con 500 publicaciones: la clave externa en la tabla de posts
contendrá el nombre de usuario, duplicado 500 veces. La sobrecarga es prohibitiva incluso antes de considerar que alguien eventualmente necesite cambiar su nombre de usuario.
Necesitaré a alguien con más conocimiento de base de datos que me respalde en este caso, pero creo que obtendrá una respuesta más rápida en el tiempo de búsqueda de claves externas.
Además, puede decidir más adelante que desea cambiar los nombres de usuario, o que los requisitos para los nombres de usuario pueden cambiar (¿quizás una cadena más larga?). El uso de una identificación evita tener que cambiar todas las claves externas.
Enfrentémoslo, la mayoría de los proyectos no se van a expandir tanto, pero ¿realmente quieres arriesgar el dolor de cabeza dentro de 12 meses, cuando podrías cumplir con los buenos estándares de programación ahora?
Por ejemplo, la búsqueda de enteros (? Id = 5) es mucho más rápida y tiene mayor cardinalidad que la búsqueda de cadenas (? Username = bob). Otro ejemplo, uid es auto_increment, por lo que no tiene que insertarlo explícitamente, pero se incrementará automáticamente en cada consulta de inserción.
PD: Su profesor está muuuy equivocado al respecto: D
Porque alguien podría querer cambiar su nombre de usuario (o cualquier nombre para ese asunto).
Si el nombre de usuario es la clave principal y un usuario cambia su nombre de usuario, deberá actualizar todas las tablas que tengan referencias de claves externas a la tabla de usuarios.
Si le ha demostrado a su profesor que asignarle un número entero arbitrario único a cada usuario es valioso para su aplicación, entonces, por supuesto, se equivocaría al decir que es "completamente inútil e innecesario".
Sin embargo, tal vez te perdiste su punto. Si él le dijo que el requisito es que "no dos usuarios pueden tener el mismo nombre de usuario", entonces no ha cumplido ese requisito.
Muchas gracias por publicar su SQL DDL, es muy útil, pero la mayoría no se molesta en SO.
Usando su mesa, puedo hacer esto:
INSERT INTO users (username) VALUES (NULL);
INSERT INTO users (username) VALUES (NULL);
INSERT INTO users (username) VALUES (NULL);
INSERT INTO users (username) VALUES (NULL);
INSERT INTO users (username) VALUES (NULL);
Lo que resulta en esto:
SELECT uid, username, passhash, email, rdate
FROM users;
uid username passhash email rdate
1 <NULL> <NULL> <NULL> <NULL>
2 <NULL> <NULL> <NULL> <NULL>
3 <NULL> <NULL> <NULL> <NULL>
4 <NULL> <NULL> <NULL> <NULL>
Creo que es el punto que tu profesor estaba tratando de hacer: sin aplicar la clave natural en el username
de username
, en realidad no tienes ninguna integridad de datos.
Si yo fuera el prof, también le pediría que elimine las columnas que aceptan nulos de su diseño.
Su profesor está haciendo lo correcto al señalar que debería haber hecho un nombre de usuario único y no anulable si era un requisito que los nombres de usuario fueran únicos. El uid también podría ser una clave, pero a menos que realmente lo estés usando en algún lugar, entonces no es necesario. El aspecto más importante del diseño debería ser implementar la clave natural. Así que estoy de acuerdo con el comentario de tu profesor.
Voy con todas las respuestas anteriores. Yo diría que una ID es fácil de implementar y cuando se trata de indexar, siempre se prefiere Int en comparación con una varchar. Tu profesor debería saberlo mejor, ¿por qué diría que no a Int ID está por encima de mí?
usamos ID para evitar la duplicación de datos y puede hacer que algunos procesos no sean complicados (si queremos actualizar o eliminar datos), es más simple si usamos ID.
si no quieres usar ID, puedes usar otros campos. pero no olvides hacer que se vuelvan ÚNICOS. puede hacer que sus datos se vuelvan preventivos a partir de los datos de duplicación.
otra forma fuera de PRIMARY es ÚNICA.