Pregunta

Recientemente migré mi DB completo de myisam a innodb. Soy bastante nuevo en todo esto, así que tengo una pregunta sobre el uso de la clave externa.

Digamos que tengo dos tablas: usuarios, mensajes.

usuarios

id (pr_key)
name

mensajes

id (pr_key)
user_id
message

Los campos de identificación se incrementan automáticamente.

Así que ahora en mis consultas me uno a estas 2 tablas ya. Sigue siendo necesario colocar una clave externa aquí, en realidad no veo un punto. ¿Tiene beneficios de rendimiento.

Si elijo poner una clave foránea aquí, asumo que debo hacer la pr_key de los mensajes id, y user_id.

  

La adición de la otra prim_key no solo ocupará más espacio y dará como resultado un rendimiento más lento.

     

Ahora, si la tabla tiene dos teclas pr_, y solo hago consultas en una de ellas, seguiré teniendo los mismos beneficios de rendimiento. ¿O necesito usar explícitamente las dos claves?

Sé que en este ejemplo buscaré user_id, por lo que quizás sea inteligente indexar esto de todos modos. Pero qué pasa si el campo es un campo donde no hay búsquedas en. ¿Sigue siendo bueno colocar una clave primaria múltiple en este campo, solo para la relación externa?

¡Gracias!

¿Fue útil?

Solución

Tiene integridad de datos beneficios.

impedirá que el código de la aplicación ingrese user_id de 1234 en la tabla de mensajes cuando no haya un usuario con id = 1234 en la tabla de usuarios. Y evitará que la aplicación elimine al usuario cuando el usuario tenga algún mensaje en la tabla de mensajes.

El nombre de la PK no tiene que coincidir con el nombre de la FK en la tabla secundaria de referencia.

" Si elijo poner una clave foránea aquí, asumo que debo hacer la pr_key de los mensajes id y user_id. "

NO . No cambia la clave en la tabla de mensajes, simplemente establece una restricción de Clave Externa (FK) en la columna User_Id en la tabla de mensajes, que hace referencia (señala a) a la columna de identificación en la tabla de usuarios. No se requiere una PK adicional en los mensajes, y dado que la PK ya es única (no puede tener dos mensajes con el mismo Id. De mensaje), la PK tanto en el ID como en el ID de usuario no puede agregar más exclusividad.

La línea de fondo aquí es que puede tener un error fundamental acerca de lo que realmente son una clave principal y una clave externa.

  • Una PK es una restricción en la singularidad de una fila, requiere un índice.
  • Un FK es una restricción en el valor de una columna (exige que el valor exista como un valor de PK en otra tabla a la que se hace referencia) no requiere un índice.

@Noah, echa un vistazo a este Otra pregunta de SO

Otros consejos

Si establece una regla formal de FOREIGN KEY en los mensajes (user_id) o no, el simple hecho es que esta es una relación de clave externa.

Primero, recuerde que una clave primaria adecuada en una tabla debería ser suficiente para identificar de manera única cada registro en la tabla. Teniendo en cuenta que cada mensaje ya tendrá eso con el campo id , no es necesario ni desea incluir especialmente el user_id en la clave principal de la tabla de mensajes.

En segundo lugar, como ya declaró Charles declarando una CLAVE EXTRAÑA en los mensajes (user_id) que REFERENCES los usuarios (id) le permitirán garantizar la integridad de sus datos. Al utilizar una restricción de clave externa, puede especificar qué hacer cuando se elimina un registro en la tabla de usuarios que tiene registros correspondientes en la tabla de mensajes. Sus opciones son ON DELETE CASCADE (eliminar todos los registros secundarios de este registro de usuario), ON DELETE RESTRICT (no permitir que se elimine un usuario que tenga registros en la tabla de mensajes), ON DELETE NO ACTION (ignorar las operaciones de eliminación) , ON DELETE SET NULL (conserva los registros secundarios pero establece el campo user_id en NULL).

Cada una de estas opciones es apropiada dependiendo de las circunstancias, pero lo más importante aquí es que puede evitar los punteros nulos inesperados de la tabla secundaria a la tabla primaria.

En tercer lugar, el establecimiento de la relación FOREIGN KEY proporcionará mejoras de rendimiento, ya que esto generará un ÍNDICE en los mensajes (user_id) que se corresponde con la CLAVE PRIMARIA en la tabla de usuarios. Al realizar cualquier consulta que se una a estos campos, verá que la cantidad de registros que deben consultarse para devolver los registros secundarios se reduce sustancialmente en comparación con el hecho de no haber establecido la CLAVE EXTRAÑA.

@Charles Bretana: la pregunta a la que se vincula es específica de Microsoft SQL Server. La pregunta aquí es con respecto a MySQL / InnoDB.

Le recomendaría que consulte la documentación de Restricciones de clave foránea InnoDB .

  

InnoDB requiere índices en el extranjero   llaves y llaves referenciadas para que   Los controles de clave externa pueden ser rápidos y no   requiere una exploración de la tabla. En el   tabla de referencia, debe haber una   índice donde las columnas de clave externa   se enumeran como las primeras columnas en el   la misma orden. Se crea tal índice   en la tabla de referencia automática   Si no existe. (Esto es en   En contraste con algunas versiones anteriores, en   qué índices debían ser creados   explícitamente o la creación de extranjeros   las restricciones clave fallarían.)   index_name, si se da, se usa como   descrito anteriormente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top