sql >> Base de Datos >  >> RDS >> Mysql

Claves foráneas de MySQL

Las claves foráneas son una parte integral de la creación de una relación en bases de datos relacionales. He aquí por qué y cómo crearlos.

Entonces, hemos establecido que una clave principal proporciona un identificador único para la tabla. Pero las claves primarias no son el único tipo de "clave". Nuestra base de datos también puede contener claves foráneas.

¿Qué es una clave externa?

Una clave externa es una columna (o colección de columnas) en una tabla que identifica de forma única una fila de otra tabla. Esto define una relación entre las dos tablas.

Una clave externa le permite hacer referencias cruzadas de datos relacionados entre tablas. Esto resulta útil cuando una columna contiene datos que se representan en otra tabla.

Ejemplo

Aquí hay un diagrama de nuestra FruitShop base de datos que muestra la relación entre la Fruit tabla y las Unidades mesa.

La línea negra que une las dos tablas indica una clave externa. El UnitId campo en la Fruta la tabla es una clave externa para el UnitId campo en las Unidades mesa. Por lo tanto, el valor que insertamos en Fruit.UnitId debe corresponder a un valor en Units.UnitId . Esto habilita el Fruit.UnitId para hacer referencia a los datos en las otras columnas para ese registro (es decir, el registro que tiene el UnitId correspondiente ).

Los datos

Entonces, si nuestra Fruit la tabla contiene un registro como este:

Id de fruta Nombre de la fruta Inventario ID de unidad Fecha de ingreso Fecha de actualización
1 manzana 10 3 2012-11-27 12:42:10 2012-11-27 12:42:10

Y nuestras Unidades la tabla contiene los siguientes registros:

Id. de unidad Nombre de la unidad Fecha de ingreso Fecha de actualización
1 Pieza 2011-12-30 12:46:15 2011-12-30 12:46:15
2 Montón 2011-12-30 12:46:15 2011-12-30 12:46:15
3 Kilogramo 2011-12-30 12:46:15 2011-12-30 12:46:15
4 Contenedor 2011-12-30 12:46:15 2011-12-30 12:46:15
5 Libra 2011-12-30 12:46:15 2011-12-30 12:46:15
6 Onza 2011-12-30 12:46:15 2011-12-30 12:46:15

Puede ver que Fruit.UnitId el campo contiene un 3 . Ahora mira las Unidades tabla para el registro que contiene un 3 en el UnitId campo. Puede ver que este registro representa Kilogramo . Por lo tanto, ahora sabemos que las manzanas se miden en kilogramos.

Lo bueno de configurar la base de datos de esta manera es que no necesitamos repetir "Kilogramos" para cada registro que use esa unidad. Reducir la duplicación es un beneficio clave de los sistemas de administración de bases de datos relacionales.

Ver tantos registros en el Fruit compartirá el mismo nombre de unidad (p. ej., "Kilogramos", "Contenedor", "Montón", etc.), debemos pensar detenidamente antes de agregar duplicados a nuestra base de datos. Sin utilizar una relación de clave externa, podríamos simplemente escribir los nombres de las unidades directamente en el Fruit table (y tal vez llamar a la columna "Unidad", "UnitType" o "UnitName"). Entonces terminaríamos con muchos registros compartiendo el mismo valor para la columna del nombre de la unidad. Veríamos "Kilogram" repetido una y otra vez contra muchos récords. También veríamos "Bunch" repetido y cualquier otro tipo de unidad popular.

Si bien no es necesariamente "incorrecto" hacer esto, generalmente es más eficiente almacenar un registro para cada nombre de unidad en una tabla separada y luego hacer referencia a esa tabla a través de UnitId columna. Hacer esto es más eficiente que repetir esos nombres de unidades una y otra vez para cada registro que se crea en Fruits mesa. También lo hace más fácil si alguna vez decidimos actualizar el nombre de una unidad (cambiar "Kilogramos" a "Kilos", por ejemplo). Si actualizamos el nombre de una unidad, no afectaría a Fruit tabla porque el UnitId seguirá siendo el mismo. Además, también ayuda a evitar que aparezcan datos inconsistentes en nuestra base de datos.

Restricción de clave externa

Una restricción de clave externa es un objeto de base de datos que ayuda a mantener la coherencia de los datos de la clave externa. Cree una restricción de clave externa para mantener la integridad referencial. Al crear una restricción de clave externa, le está diciendo a MySQL que aplique ciertas reglas sobre los datos. Cuando se insertan, eliminan o actualizan datos, MySQL verificará que se adhiera a la clave externa que creó entre las tablas. De lo contrario, evitará que los datos se escriban, sobrescriban o eliminen, manteniendo así la integridad referencial.

Por ejemplo, si un usuario intenta ingresar un valor de UnitId en Fruit.UnitId columna pero no hay ningún registro correspondiente en Units.UnitId columna, MySQL evitará que el usuario ingrese ese valor.

Cuando creamos nuestras dos tablas, agregamos una restricción de clave externa a Fruit mesa. Aquí está el código que usamos para crear la restricción:

CONSTRAINT fkFruitUnits FOREIGN KEY (UnitId) REFERENCES Units (UnitId) ON DELETE RESTRICT ON UPDATE CASCADE

Cuando expande los nodos en la izquierda SCHEMAS pestaña, puede ver la clave externa que creamos (así como las claves principales):

Si intenta insertar datos que no se ajustan a la restricción de clave externa, debería recibir un error.

Por ejemplo, si intento insertar un registro en Fruit tabla usando un UnitId valor que no existe en las Unidades tabla, recibo el siguiente error:

Esto ocurre porque intento insertar un valor de 5 en el UnitId columna cuando no hay un valor correspondiente en Units.UnitId campo.

Para que esto tenga éxito, tendría que asegurarme de que haya un registro en las Unidades tabla con un UnitId de 5 .

¿La clave externa no funciona?

Es posible que se encuentre con la situación ocasional en la que una clave externa no parece funcionar. Por ejemplo, puede insertar correctamente datos en una tabla aunque haya una clave externa que debería evitar que se inserten esos datos.

Hay algunas cosas que puede comprobar en esta situación.

  • Asegúrese de haber agregado ON DELETE y ON UPDATE cláusulas en su código. Por ejemplo, ON DELETE RESTRICT ON UPDATE CASCADE . Vea nuestro ejemplo CREATE TABLE para saber cuándo colocar este código.
  • Asegúrese de que la tabla sea InnoDB . Puede hacer esto agregando ENGINE=InnoDB hasta el final de tu CREATE TABLE declaración (ver mi ejemplo de cuando creamos nuestras tablas). Algunos motores (como MyISAM ) no admiten restricciones de clave externa, pero no proporcionan ninguna advertencia al respecto cuando intenta crear su restricción de clave externa. Si su motor predeterminado no es InnoDB entonces es probable que sus claves foráneas no sean compatibles.
  • Asegúrese de que MySQL esté verificando las claves externas. Puede hacerlo ejecutando el siguiente código:SET FOREIGN_KEY_CHECKS=1 .

Deshabilitar la comprobación de claves foráneas

Puede haber ocasiones en las que las restricciones de clave externa se vuelvan innecesariamente restrictivas, hasta el punto en que obstaculicen gravemente sus esfuerzos para cargar datos. Por ejemplo, cuando acaba de crear una base de datos y necesita cargar los datos iniciales. O si necesita eliminar un montón de tablas y volver a cargar los datos.

Si no carga los datos en el orden correcto, probablemente seguirá recibiendo errores de clave externa debido a que los datos se cargan en el orden incorrecto (es decir, está tratando de cargar las tablas secundarias antes de que las tablas principales hayan tenido su datos cargados).

Esto no es solo un problema para cuando carga los datos. También podría encontrar este problema al crear la base de datos en primer lugar. Si no crea las tablas en el orden correcto, podría encontrar errores debido a restricciones de clave externa.

Si no conoce el orden padre-hijo correcto, es posible que le lleve mucho tiempo y esfuerzo establecer el orden correcto para crear la base de datos o cargar los datos. En casos como estos, es mejor que le diga a MySQL temporalmente que no verifique las claves foráneas por ahora.

Puede deshabilitar la verificación de clave externa con el siguiente código:

FOREIGN_KEY_CHECKS=0

Para habilitarlo nuevamente, haga esto:

FOREIGN_KEY_CHECKS=1