Story Transcript
Integridad Referencial
Restricciones (constraints)
Integridad de Referencial
Integridad referencial: asegura la integridad entre las llaves foráneas y primarias (relaciones padre/hijo). Existen cuatro actualizaciones de la base de datos que pueden corromper la integridad referencial:
Integridad de Referencial Error 1
La inserción de una fila hijo se produce cuando no coincide la llave foránea con la llave primaria del padre.
Integridad de Referencial Error 2
La actualización en la llave foránea de la fila hijo, donde se produce una actualización en la clave ajena de la fila hijo con una sentencia UPDATE y la misma no coincide con ninguna llave primaria.
Integridad de Referencial Error 3
La supresión de una fila padre, con la que, si una fila padre -que tiene uno o más hijos- se suprime, las filas hijos quedarán huérfanas.
Integridad de Referencial Error 4
La actualización de la clave primaria de una fila padre, donde si en una fila padre, que tiene uno o más hijos se actualiza su llave primaria, las filas hijos quedarán huérfanas.
Restricciones (constraints) InnoDB también soporta restricciones de claves foráneas. La sintaxis para definir una restricción de clave foránea en InnoDB es así:
[CONSTRAINT símbolo] FOREIGN KEY [id] (nombre_índice, ...) REFERENCES nombre_de_tabla (nombre_índice, ...) [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
Limitaciones ●
●
●
●
Ambas tablas deben ser InnoDB y no deben ser tablas temporales. En la tabla que hace referencia, debe haber un índice donde las columnas de clave extranjera estén listadas en primer lugar, en el mismo orden. No están soportados los índices prefijados en columnas de claves foráneas. Una consecuencia de esto es que las columnas BLOB y TEXT no pueden incluirse en una clave foránea, porque los índices sobre dichas columnas siempre deben incluir una longitud prefijada. Si se proporciona un CONSTRAINTsímbolo, éste debe ser único en la base de datos. Si no se suministra, InnoDB crea el nombre automáticamente.
Acciones
InnoDB rechaza cualquier operación INSERT o UPDATE que intente crear un valor de clave foránea en una tabla hija sin un valor de clave candidata coincidente en la tabla padre. La acción que InnoDB lleva a cabo para cualquier operación UPDATE o DELETE que intente actualizar o borrar un valor de clave candidata en la tabla padre que tenga filas coincidentes en la tabla hija depende de la accion referencial especificada utilizando las subcláusulas ON UPDATE y ON DETETE en la cláusula FOREIGN KEY.
Acciones Cuando el usuario intenta borrar o actualizar una fila de una tabla padre, InnoDB soporta cinco acciones respecto a la acción a tomar: • CASCADE: Borra o actualiza el registro en la tabla padre y automáticamente borra o actualiza los registros coincidentes en la tabla hija. Tanto ON DELETE CASCADE como ON UPDATE CASCADE están disponibles en MySQL 5.0. Entre dos tablas, no se deberían definir varias cláusulas ON UPDATE CASCADE que actúen en la misma columna en la tabla padre o hija. • SET NULL: Borra o actualiza el registro en la tabla padre y establece en NULL la o las columnas de clave foránea en la tabla hija. Esto solamente es válido si las columnas de clave foránea no han sido definidas como NOT NULL. MySQL 5.0 soporta tanto ON DELETE SET NULL como ON UPDATE SET NULL.
Acciones • NO ACTION: En el estándar ANSI SQL-92, NO ACTION significa ninguna acción en el sentido de que unintento de borrar o actualizar un valor de clave primaria no sera permitido si en la tabla referenciada hay una valor de clave foránea relacionado. (Gruber, Mastering SQL, 2000:181). En MySQL 5.0, InnoDB rechaza la operación de eliminación o actualización en la tabla padre. • RESTRICT: Rechaza la operación de eliminación o actualización en la tabla padre. NO ACTION y RESTRICT son similares en tanto omiten la cláusula ON DELETE u ON UPDATE. (Algunos sistemas de bases de datos tienen verificaciones diferidas o retrasadas, una de las cuales es NO ACTION. En MySQL, las restricciones de claves foráneas se verifican inmediatamente, por eso, NO ACTION y RESTRICT son equivalentes.) • SET DEFAULT: Esta acción es reconocida por el procesador de sentencias (parser), pero InnoDB rechaza definiciones de tablas que contengan ON DELETE SET DEFAULT u ON UPDATE SET DEFAULT.
Agregando constrains posteriormente En ocasiones tenemos una tabla que queremos agregarle un constraint una sobre una tabla ya existente: ALTER TABLE nombre_tabla ADD [CONSTRAINT nombre_restriccion] FOREIGN KEY (columna) REFERENCES tabla_referenciada (indice_tabla) [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
Ejemplo Imagine la base de datos de un negocio en donde existen las tablas clientes y ventas como se muestran a continuación: CREATE TABLE clientes ( id INT NOT NULL, nombre VARCHAR(30), PRIMARY KEY (id) ) TYPE = INNODB; CREATE TABLE ventas ( id_factura INT NOT NULL, id_cliente INT NOT NULL, cantidad INT, PRIMARY KEY(id_factura), INDEX (id_cliente) ) TYPE = INNODB;
Ejemplo Ahora vamos a agregar una restricción que impida agregar una venta si no existe el cliente correspondiente, que haga NULL el campo id_cliente en caso que se llegara a borrar el cliente en cuestión y que actualice los indices en caso que sea modificado el id del cliente: ALTER TABLE ventas ADD CONSTRAINT ventas_clientes FOREIGN KEY(id_cliente) REFERENCES clientes(id) ON UPDATE CASCADE ON DELETE SET NULL;
Ejemplo 2 Ahora imagine que tiene las tablas productos y categorias la cual es una relación de muchos a muchos, es decir un producto puede pertenecer a varias categorías y una categoría puede pertenecer a varios productos, por lo cual necesitamos una tabla intermedia categorias_productos: CREATE TABLE categorias ( id int(4) not null primary key, name VARCHAR(255) default null ); CREATE TABLE productos ( id int(4) not null primary key, name VARCHAR(255) default null );
Ejemplo 2 En casos generales de las relaciones de muchos a muchos las restricciones se colocan siempre en la tabla intermedia en este caso categorias_productos como se muestra a continuación: CREATE TABLE categorias_productos ( categoria_id int(4) not null, producto_id int(4) not null, PRIMARY KEY (producto_id, categoria_id), FOREIGN KEY (categoria_id) REFERENCES categorias (id) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (producto_id) REFERENCES productos (id) ON DELETE CASCADE ON UPDATE CASCADE );
Bibliografía:
Clave foránea: Definición de clave foránea y ejemplos en sql, disponible en: https://es.wikipedia.org/wiki/Clave_for%C3%A1nea
Definicion de Restricciones (constraints foreign key): Implementación de claves foráneas en mysql, definición y ejemplos: http://mirror.metrocast.net/mysql/doc/refman/5.0/es/innodb-foreign-key-constraints .html