mundoxbase.info
Mysql, la integridad referencial en la práctica
Diciembre 31st, 2006 - [Enlace local]
Una vez aquí, vamos a introducir nuestro primer registro en una de las tablas, por ejemplo, la de artículos:
Query OK, 1 row affected (0.03 sec)
-
Como podemos ver, utilizamos la instrucción INSERT INTO seguido del nombre de la tabla dónde vamos a insertar los datos (VALUES) y los datos a insertar encerrados entre paréntesis y separados por comas.
En nuestro ejemplo, el primer dato (correspondiente al campo “Codigo”) que como recordaréis es un campo autoincremental, lo dejamos a “null”, de tal forma que el propio Mysql se encargará de asignarle un código correlativo.
El segundo dato, corresponde al campo “Descripcion” y el tercer dato corresponde al campo “similar”, que como esta artículo no tiene ningúno similar, lo dejamos a null (sin datos).
También podemos ver como Mysql nos indica que todo está OK, y que nuestra instrucción afecta a un registo (el que hemos insertado) y el tiempo empleado en terminar la operación.
Podemos ver cómo ha quedado nuestra tabla “Articulos” haciendo una selección
+——–+—————–+———+
| Codigo | Descripcion | Similar |
+——–+—————–+———+
| 1 | Primer articulo | NULL |
+——–+—————–+———+
1 row in set (0.00 sec)
A la hora de insertar un nuevo registro, también podemos indicar los campos que intervienen en la inserción. Imaginaros una tabla con, no sé, 30 campos, y que sólo queremos insertar el nombre del artículo, en lugar de poner
-
Podemos hacerlo mucho más sencillo con
Query OK, 1 row affected (0.02 sec)
-
Como vemos, todo consiste en indicar, además del nombre de la tabla, los campos que se ven afectados por la inserción encerrados entre paréntesis.
Así, en este caso, el campo autoincremental se incrementará automáticamente y el campo similar tomará el valor Null, su valor por defecto.
+——–+——————+———+
| Codigo | Descripcion | Similar |
+——–+——————+———+
| 1 | Primer articulo | NULL |
| 2 | Segundo articulo | NULL |
+——–+——————+———+
2 rows in set (0.00 sec)
Otra opción que nos ofrece Mysql es insertar varios registros a la vez, para ello tan sólo es necesario encerrar entra paréntesis los distintos registros y separarlos por comas
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
+——–+——————+———+
| Codigo | Descripcion | Similar |
+——–+——————+———+
| 1 | Primer articulo | NULL |
| 2 | Segundo articulo | NULL |
| 3 | Tercer articulo | NULL |
| 4 | Cuarto articulo | NULL |
| 5 | Quinto articulo | NULL |
+——–+——————+———+
5 rows in set (0.00 sec)
Vamos ahora a insertar las características de nuestro primer artículo
Query OK, 1 row affected (0.02 sec)
Query OK, 1 row affected (0.02 sec)
+——————+——-+———+
| Articulos_Codigo | Peso | Volumen |
+——————+——-+———+
| 1 | 10.25 | NULL |
| 2 | 2.20 | NULL |
+——————+——-+———+
2 row in set (0.00 sec)
Veamos ahora que pasa si intentamos pasarnos de listos y pretendemos insertar de nuevo otras características para nuestro primer artículo
ERROR 1062 (23000): Duplicate entry ‘1′ for key 1
¡Exacto!, fijaos que el campo Articulo_Codigo de la tabla Características es una clave primaria, y por lo tanto no pueden existir dos registro con el código 1 en dicho campo.
¿Y si intentamos crear las características de un artículo que no existe?
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint
fails (`prueba/caracteristicas`, CONSTRAINT `caracteristicas_ibfk_1` FOREIGN KEY
(`Articulos_Codigo`) REFERENCES `articulos` (`Codigo`) ON DELETE CASCADE ON UPDATE NO ACTION)
¡Mysql nos ha vuelto a pillar! Al insertar unas características para un artículo inexistente estamos rompiendo una de las reglas de integridad referencial, que dice que todo artículo puede tener unas características, pero que las características siempre corresponderán a un determinado artículo.
Y… si borramos nuestro primer artículo?
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM articulos;
+——–+——————+———+
| Codigo | Descripcion | Similar |
+——–+——————+———+
| 2 | Segundo articulo | NULL |
| 3 | Tercer articulo | NULL |
| 4 | Cuarto articulo | NULL |
| 5 | Quinto articulo | NULL |
+——–+——————+———+
4 rows in set (0.00 sec)
¡Ojo con el delete!!. Si se nos ocurre poner simplemente DELETE FROM articulos nos “pulimos” TODOS los datos de la tabla !!.
Recordar siempre que en sql trabajamos sobre la base de datos completa, no como con las dbf que estábamos posicionados en un determinado registro y nuestras acciones actuaban sólo sobre ese registro.
En clipper, al hacer un “delete” afectaba al registro sobre el que estábamos posicionados, en cambio, en sql no estamos “posicionados” en “ningún sitio”, por eso, al hacer un delete en Mysql le tenemos que decir qué tabla (FROM) y qué registro de la tabla (WHERE)
Hemos visto que nuestro “delete” ha borrado el registro indicado, pero… qué ha pasado con las características asociadas al artículo borrado. Veamos la tabla características
+——————+——+———+
| Articulos_Codigo | Peso | Volumen |
+——————+——+———+
| 2 | 2.20 | NULL |
+——————+——+———+
1 row in set (0.00 sec)
¿Os acordáis del ON DELETE CASCADE?
Mysql se ha encargado por nosotros de “propagar” el borrado de datos a las tablas indicadas.
Hoy hemos visto cómo efectivamente la integridad referencial funciona y nos ahorra el trabajo de realizar por nosotros mismos parte del mantenimiento propio de una base de datos.
El año próximo veremos con un poco más de detalle la inserción y modificación de datos dentro de una tabla, y cómo nos pueden ayudar los procedimientos almacenados.
Pero antes de terminar, hagamos una pequeña ampliación a nuestra tabla “artículos”. Vamos a añadir dos nuevos campos a la tabla. Veremos cómo usarlos en el próximo capítulo
-> ADD creado date,
-> ADD modificado date,
-> ADD cambios Tinyint;
Query OK, 4 rows affected (0.16 sec)
Records: 4 Duplicates: 0 Warnings: 0
+————-+——————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————-+——————+——+—–+———+—————-+
| Codigo | int(10) unsigned | NO | PRI | NULL | auto_increment |
| Descripcion | varchar(30) | YES | | NULL | |
| Similar | int(10) unsigned | YES | MUL | NULL | |
| creado | date | YES | | NULL | |
| modificado | date | YES | | NULL | |
| cambios | tinyint(4) | YES | | NULL | |
+————-+——————+——+—–+———+—————-+
6 rows in set (0.01 sec)