You are on page 1of 15

MySQL

Introduccin MySQL 4.0 soporta cinco tipos de tablas: MyISAM, ISAM, HEAP, BDB (Base de datos Berkeley), e InnoDB. BDB e InnoDB son ambas tipos de tablas transaccionales. Adems de poder trabajar con transacciones en MySQL, las tablas del tipo InnoDB tambin tienen soporte para la definicin de claves forneas, por lo que se nos permite definir reglas o restricciones que garanticen la integridad referencial de los registros. A partir de la versin 4.0, MySQL ha agregado InnoDB a la lista de tipos de tablas soportados en una instalacin tpica. En este artculo se asume que se cuenta ya con un servidor MySQL con soporte para el tipo de tablas InnoDB. En nuestro caso haremos uso de un servidor MySQL 4.013 ejecutndose en un sistema MSWindows. Nota: para asegurarnos que tenemos soporte para el tipo de tablas InnoDB podemos ejecutar la siguiente sentencia: mysql> SHOW VARIABLES LIKE '%innodb%'; +---------------------------------+------------------------+ | Variable_name | Value | +---------------------------------+------------------------+ | have_innodb | YES | | innodb_additional_mem_pool_size | 1048576 | | innodb_buffer_pool_size | 8388608 | | innodb_data_file_path | ibdata1:10M:autoextend | | innodb_data_home_dir | | | innodb_file_io_threads |4 | | innodb_force_recovery |0 | | innodb_thread_concurrency |8 | | innodb_flush_log_at_trx_commit | 1 | | innodb_fast_shutdown | ON | | innodb_flush_method | | | innodb_lock_wait_timeout | 50 | | innodb_log_arch_dir |. | | innodb_log_archive | OFF | | innodb_log_buffer_size | 1048576 | | innodb_log_file_size | 5242880 | | innodb_log_files_in_group |2 | | innodb_log_group_home_dir |. | | innodb_mirrored_log_groups |1 | | innodb_max_dirty_pages_pct | 90 | +---------------------------------+------------------------+ 20 rows in set (0.00 sec) La variable ms importante es por supuesto have_innodb que tiene el valor YES. Claves primarias Para entender lo que son las claves forneas, tal vez sea necesario entender primero lo que son las claves primarias.

Es un hecho que las claves juegan un papel muy importante no slo en MySQL, sino en cualquier base de datos relacional. De manera simple, las claves proporcionan una manera rpida y eficiente de buscar datos en una tabla, adems de que permiten preservar la integridad de los datos. Una clave candidata es un campo, o una combinacin de campos, que identifican de manera nica un registro de una tabla. stas no pueden contener valores nulos, y su valor debe ser nico. Una clave primaria es una clave candidata que ha sido diseada para identificar de manera nica a los registros de una tabla a travs de toda la estructura de la base de datos. La seleccin de una clave primaria es muy importante en el diseo de una base de datos, ya que es un elemento clave de los datos que facilita la unin de tablas y el concepto total de una base de datos relacional. Las claves primarias deben ser nicas y no nulas, de manera que garanticen que una fila de una tabla pueda ser siempre referenciada a travs de su clave primaria. MySQL requiere que se especifique NOT NULL para las columnas que se van a utilizar como claves primarias al momento de crear una tabla.

Una superclave es un conjunto de uno o ms atributos que, tomados colectivamente, permiten identificar de forma nica una entidad en el conjunto de entidades. Por ejemplo, el atributo id-cliente del conjunto de entidades cliente es suficiente para distinguir una entidad cliente de las otras. As, id-cliente es una superclave. Anlogamente, la combinacin de nombre-cliente e id-cliente es una superclave del conjunto de entidades cliente. El atributo nombrecliente de cliente no es una superclave, porque varias personas podran tener el mismo nombre. El concepto de una superclave no es suficiente para lo que aqu se propone, ya que, como se ha visto, una superclave puede contener atributos innecesarios. Si K es una superclave, entonces tambin lo es cualquier superconjunto de K. A menudo interesan las superclaves tales que los subconjuntos propios de ellas no son superclave. Tales superclaves mnimas se llaman claves candidatas. Es posible que conjuntos distintos de atributos pudieran servir como clave candidata. Supngase que una combinacin de nombre-cliente y calle-cliente es suficiente para distinguir entre los miembros del conjunto de entidades cliente. Entonces, los conjuntos {idcliente} y {nombre-cliente, calle-cliente} son claves candidatas. Aunque los atributos id-cliente y nombre-cliente juntos puedan distinguir entidades cliente, su combinacin no forma una clave candidata, ya que el atributo id-cliente por s solo es una clave candidata.

Se usar el trmino clave primaria para denotar una clave candidata que es elegida por el diseador de la base de datos como elemento principal para identificar las entidades dentro de un conjunto de entidades. Una clave (primaria, candidata y superclave) es una propiedad del conjunto de entidades, ms que de las entidades individuales. Cualesquiera dos entidades individuales en el conjunto no pueden tener el mismo valor en sus atributos clave al mismo tiempo. La designacin de una clave representa una restriccin en el desarrollo del mundo real que se modela. La clave primaria se debera elegir de manera que sus atributos nunca, o muy raramente, cambien. Por ejemplo, el campo direccin de una persona no debera formar parte de una clave primaria, porque probablemente cambiar. Los nmeros de D.N.I., por otra parte, es seguro que no cambiarn. Los identificadores nicos generados por empresas generalmente no cambian, excepto si se fusionan dos empresas; en tal caso el mismo identificador puede haber sido emitido por ambas empresas y es necesario la reasignacin de identificadores para asegurarse de que sean nicos.

Claves forneas e integridad referencial Podemos decir de manera simple que integridad referencial significa que cuando un registro en una tabla haga referencia a un registro en otra tabla, el registro correspondiente debe existir. Por ejemplo, consideremos la relacin entre una tabla cliente y una tabla venta. +------------+ +-------------+ | cliente | | venta | +------------+ +-------------+ | id_cliente | | id_factura | | nombre | | id_cliente | +------------+ | cantidad | +-------------+ Para poder establecer una relacin entre dos tablas, es necesario asignar un campo en comn a las dos tablas. Para este ejemplo, el campo id_cliente existe tanto en la tabla cliente como en la tabla venta. La mayora de las veces, este campo en comn debe ser una clave primaria en alguna de las tablas. Vamos a insertar algunos datos en estas tablas. Tabla cliente +------------+--------------+ | id_cliente | nombre | +------------+--------------+ | 1 | Juan penas | | 2 | Pepe el Toro | +------------+--------------+ Tabla venta

+------------+------------+----------+ | id_factura | id_cliente | cantidad | +------------+------------+----------+ | 1| 1| 23 | | 2| 3| 39 | | 3| 2| 81 | +------------+------------+----------+ Hay dos registros en la tabla cliente, pero existen 3 id_cliente distintos en la tabla venta. Habamos dicho que las dos tablas se relacionan con el campo id_cliente, por lo tanto, podemos decir que Juan Penas tiene una cantidad de 23, y Pepe el Toro 81, sin embargo, no hay un nombre que se corresponda con el id_cliente 3. Las relaciones de claves forneas se describen como relaciones padre/hijo (en nuestro ejemplo, cliente es el padre y venta es el hijo), y se dice que un registro es hurfano cuando su padre ya no existe. Cuando en una base de datos se da una situacin como esta, se dice que se tiene una integridad referencial pobre (pueden existir otra clase de problemas de integridad). Generalmente esto va ligado a un mal diseo, y puede generar otro tipo de problemas en la base de datos, por lo tanto debemos evitar esta situacin siempre que sea posible. En el pasado, MySQL no se esforzaba en evitar este tipo de situaciones, y la responsabilidad pasaba a la aplicacin. Para muchos desarrolladores, esta no era una situacin del todo grata, y por lo tanto no se consideraba a MySQL para ser usado en sistemas "serios". Por supuesto, esta fue una de las cosas ms solicitadas en las anteriores versiones de MySQL; que se tuviera soporte para claves forneas, para que MySQL mantenga la integridad referencial de los datos. Una clave fornea es simplemente un campo en una tabla que se corresponde con la clave primaria de otra tabla. Para este ejemplo, el campo id_cliente en la tabla venta es la clave fornea. Ntese que este campo se corresponde con el campo id_cliente en la tabla cliente, en dnde este campo es la clave primaria. Las claves forneas tienen que ver precisamente con la integridad referencial, lo que significa que si una clave fornea contiene un valor, ese valor se refiere a un registro existente en la tabla relacionada. Claves forneas en MySQL Estrictamente hablando, para que un campo sea una clave fornea, ste necesita ser definido como tal al momento de crear una tabla. Se pueden definir claves forneas en cualquier tipo de tabla de MySQL, pero nicamente tienen sentido cuando se usan tablas del tipo InnoDB. A partir de la versin 3.23.43b, se pueden definir restricciones de claves forneas con el uso de tablas InnoDB. InnoDB es el primer tipo de tabla que permite definir estas restricciones para garantizar la integridad de los datos. Para trabajar con claves forneas, necesitamos hacer lo siguiente:

Crear ambas tablas del tipo InnoDB.

Usar la sintaxis FOREIGN KEY(campo_fk) REFERENCES nombre_tabla (nombre_campo) Crear un ndice en el campo que ha sido declarado clave fornea.

InnoDB no crea de manera automtica ndices en las claves forneas o en las claves referenciadas, as que debemos crearlos de manera explcita. Los ndices son necesarios para que la verificacin de las claves forneas sea ms rpida. A continuacin se muestra como definir las dos tablas de ejemplo con una clave fornea. CREATE TABLE cliente ( id_cliente INT NOT NULL, nombre VARCHAR(30), PRIMARY KEY (id_cliente) ) TYPE = INNODB; CREATE TABLE venta ( id_factura INT NOT NULL, id_cliente INT NOT NULL, cantidad INT, PRIMARY KEY(id_factura), INDEX (id_cliente), FOREIGN KEY (id_cliente) REFERENCES cliente(id_cliente) ) TYPE = INNODB; La sintaxis completa de una restriccin de clave fornea es la siguiente: [CONSTRAINT smbolo] FOREIGN KEY (nombre_columna, ...) REFERENCES nombre_tabla (nombre_columna, ...) [ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}] [ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}] Las columnas correspondientes en la clave fornea y en la clave referenciada deben tener tipos de datos similares para que puedan ser comparadas sin la necesidad de hacer una conversin de tipos. El tamao y el signo de los tipos enteros debe ser el mismo. En las columnas de tipo caracter, el tamao no tiene que ser el mismo necesariamente. Si MySQL da un error cuyo nmero es el 1005 al momento de ejecutar una sentencia CREATE TABLE, y el mensaje de error se refiere al nmero 150, la creacin de la tabla fall porque la restriccin de la clave fornea no se hizo de la manera adecuada. De la misma manera, si falla una sentencia ALTER TABLE y se hace referencia al error nmero 150, esto significa que la definicin de la restriccin de la clave fornea no se hizo adecuadamente. A partir de la versin 4.0.13 de MySQL, se puede usar la sentencia SHOW INNODB STATUS para ver una explicacin detallada del ltimo error que se gener en relacin a la definicin de una clave fornea. Si en una tabla, un registro contiene una clave fornea con un valor NULO, significa que no existe niguna relacin con otra tabla.

A partir de la versin 3.23.50, se pueden agregar restricciones de clave fornea a una tabla con el uso de la sentencia ALTER TABLE. La sintaxis es: ALTER TABLE nombre_tabla ADD [CONSTRAINT smbolo] FOREIGN KEY(...) REFERENCES otra_tabla(...) [acciones_ON_DELETE][acciones_ON_UPDATE] Por ejemplo, la creacin de la clave fornea en la tabla venta que se mostr anteriormente pudo haberse hecho de la siguiente manera con el uso de una sentencia ALTER TABLE: CREATE TABLE venta ( id_factura INT NOT NULL, id_cliente INT NOT NULL, cantidad INT, PRIMARY KEY(id_factura), INDEX (id_cliente) ) TYPE = INNODB; ALTER TABLE cliente(id_cliente); venta ADD FOREIGN KEY(id_cliente) REFERENCES

En las versiones 3.23.50 y menores no deben usarse las sentencias ALTER TABLE o CREATE INDEX en tablas que ya tienen definidas restricciones de claves forneas o bien, que son referenciadas en restricciones de claves forneas: cualquier sentencia ALTER TABLE elimina todas las restricciones de claves forneas definidas para la tabla. No debe usarse una sentencia ALTER TABLE en una tabla que est siendo referenciada, si se quiere modificar el esquema de la tabla, se recomienda eliminar la tabla y volverla a crear con el nuevo esquema. Cuando MySQL hace un ALTER TABLE, puede que use de manera interna un RENAME TABLE, y por lo tanto, se confundan las restricciones de clave fornea que se refieren a la tabla. Esta restriccin aplica tambin en el caso de la sentencia CREATE INDEX, ya que MySQL la procesa como un ALTER TABLE. Cuando se ejecute un script para cargar registros en una base de datos, es recomendable agregar las restricciones de claves forneas va un ALTER TABLE. De esta manera no se tiene el problema de cargar los registros en las tablas de acuerdo a un orden lgico (las tablas referenciadas deberan ir primero). Insercin de registros con claves forneas La integridad referencial se puede comprometer bsicamente en tres situaciones: cuando se est insertando un nuevo registro, cuando se est eliminando un registro, y cuando se est actualizando un registro. La restriccin de clave fornea que hemos definido se asegura que cuando un nuevo registro sea creado en la tabla venta, ste debe tener su correspondiente registro en la tabla cliente. Una vez que hemos creado las tablas, vamos a insertar algunos datos que nos sirvan para demostrar algunos conceptos importantes: mysql> INSERT INTO cliente VALUES(1,'Juan Penas'); Query OK, 1 row affected (0.05 sec)

mysql> INSERT INTO cliente VALUES(2,'Pepe el toro'); Query OK, 1 row affected (0.05 sec) mysql> INSERT INTO venta VALUES(1,1,23); Query OK, 1 row affected (0.03 sec) mysql> INSERT INTO venta VALUES(3,2,81); Query OK, 1 row affected (0.03 sec) En este momento no hay ningn problema, sin embargo, vamos a ver que sucede cuando intentamos insertar un registro en la tabla venta que se refiera a un cliente no existente cuyo id_cliente es 3: mysql> INSERT INTO venta VALUES(2,3,39); ERROR 1216: Cannot add or update a child row: a foreign key constraint fails El hecho es que MySQL no nos permite insertar este registro, ya que el cliente cuyo id_cliente es 3 no existe. La restriccin de clave fornea asegura que nuestros datos mantienen su integridad. Sin embargo, qu sucede cuando eliminamos algn registro?. Vamos a agregar un nuevo cliente, y un nuevo registro en la tabla venta, posteriormente eliminaremos el registro de nuestro tercer cliente: mysql> INSERT INTO cliente VALUES(3,'Pepe pecas'); Query OK, 1 row affected (0.05 sec) mysql> INSERT INTO venta VALUES(2,3,39); Query OK, 1 row affected (0.05 sec) mysql> DELETE FROM cliente WHERE id_cliente=3; ERROR 1217: Cannot delete or update a parent row: a foreign key constraint fails Debido a nuestra restriccin de clave fornea, MySQL no permite que eliminemos el registro de cliente cuyo id_cliente es 3, ya que se hace referencia a ste en la tabla venta. De nuevo, se mantiene la integridad de nuestros datos. Sin embargo existe una forma en la cul podramos hacer que la sentencia DELETE se ejecute de cualquier manera, y la veremos brevemente, pero primero necesitamos saber como eliminar (quitar) una clave fornea. Eliminacin de una clave fornea No podemos slo eliminar una restriccin de clave fornea como si fuera un ndice ordinario. Veamos que sucede cuando lo intentamos. mysql> ALTER TABLE venta DROP FOREIGN KEY; ERROR 1005: Can't create table '.test#sql-228_4.frm' (errno: 150) Para eliminar la clave fornea se tiene que especificar el ID que ha sido generado y asignado internamente por MySQL a la clave fornea. En este caso, se puede usar la sentencia SHOW CREATE TABLE para determinar dicho ID. mysql> SHOW CREATE TABLE venta; +--------+-----------------------------------------------------+ | Table | Create Table |

+--------+-----------------------------------------------------+ | venta | CREATE TABLE 'venta' ( | | | 'id_factura' int(11) NOT NULL default '0', | | | 'id_cliente' int(11) NOT NULL default '0', | | | 'cantidad' int(11) default NULL, | | | PRIMARY KEY ('id_factura'), | | | KEY 'id_cliente' ('id_cliente'), | | | CONSTRAINT '0_22' FOREIGN KEY ('id_cliente') | | | REFERENCES 'cliente' ('id_cliente') ) TYPE=InnoDB | +-------+------------------------------------------------------+ 1 row in set (0.00 sec) En nuestro ejemplo, la restriccin tiene el ID 0_22 (es muy probable que este valor sea diferente en cada caso). mysql> ALTER TABLE venta DROP FOREIGN KEY 0_22; Query OK, 3 rows affected (0.23 sec) Records: 3 Duplicates: 0 Warnings: 0 Eliminacin de registros con claves forneas Una de las principales bondades de las claves forneas es que permiten eliminar y actualizar registros en cascada. Con las restriccciones de clave fornea podemos eliminar un registro de la tabla cliente y a la vez eliminar un registro de la tabla venta usando slo una sentencia DELETE. Esto es llamado eliminacin en cascada, en donde todos los registros relacionados son eliminados de acuerdo a las relaciones de clave fornea. Una alternativa es no eliminar los registros relacionados, y poner el valor de la clave fornea a NULL (asumiendo que el campo puede tener un valor nulo). En nuestro caso, no podemos poner el valor de nuestra clave fornea id_cliente en la tabla venta, ya que se ha definido como NOT NULL. Las opciones estndar cuando se elimina una registro con clave fornea son:

ON DELETE ON DELETE ON DELETE ON DELETE ON DELETE

RESTRICT NO ACTION SET DEFAULT CASCADE SET NULL

ON DELETE RESTRICT es la accin predeterminada, y no permite una eliminacin si existe un registro asociado, como se mostr en el ejemplo anterior. ON DELETE NO ACTION hace lo mismo. ON DELETE SET DEFAULT actualmente no funciona en MySQL - se supone que pone el valor de la clave fornea al valor por omisin (DEFAULT) que se defini al momento de crear la tabla. Si se especifica ON DELETE CASCADE, y una fila en la tabla padre es eliminada, entonces se eliminarn las filas de la tabla hijo cuya clave fornea sea igual al valor de la clave referenciada en la tabla padre. Esta accin siempre ha estado disponible en MySQL.

Si se especifica ON DELETE SET NULL, las filas en la tabla hijo son actualizadas automticamente poniendo en las columnas de la clave fornea el valor NULL. Si se especifica una accin SET NULL, debemos asegurarnos de no declarar las columnas en la tabla como NOT NULL. A continuacin se muestra un ejemplo de eliminacin en cascada: mysql> ALTER TABLE venta ADD FOREIGN KEY(id_cliente) -> REFERENCES cliente(id_cliente) ON DELETE CASCADE; Query OK, 3 rows affected (0.23 sec) Records: 3 Duplicates: 0 Warnings: 0 Vamos a ver como estn nuestros registros antes de ejecutar la sentencia DELETE: mysql> SELECT * FROM cliente; +------------+--------------+ | id_cliente | nombre | +------------+--------------+ | 1 | Juan Penas | | 2 | Pepe el toro | | 3 | Pepe pecas | +------------+--------------+ 3 rows in set (0.00 sec) mysql> SELECT * FROM venta; +------------+------------+----------+ | id_factura | id_cliente | cantidad | +------------+------------+----------+ | 1| 1| 23 | | 2| 3| 39 | | 3| 2| 81 | +------------+------------+----------+ 3 rows in set (0.00 sec) Ahora eliminaremos a Pepe Pecas de la base de datos: mysql> DELETE FROM cliente WHERE id_cliente=3; Query OK, 1 row affected (0.05 sec) mysql> SELECT * FROM venta; +------------+------------+----------+ | id_factura | id_cliente | cantidad | +------------+------------+----------+ | 1| 1| 23 | | 3| 2| 81 | +------------+------------+----------+ 2 rows in set (0.00 sec) mysql> SELECT * FROM cliente; +------------+--------------+ | id_cliente | nombre | +------------+--------------+ | 1 | Juan Penas | | 2 | Pepe el toro |

+------------+--------------+ 2 rows in set (0.00 sec) Con la eliminacin en cascada, se ha eliminado el registro de la tabla venta al que estaba relacionado Pepe Pecas. Actualizacin de registros con claves forneas Las opciones correspondientes a ON UPDATE estn disponibles a partir de la versin 4.0.8. Estas opciones son muy similares cuando se ejecuta una sentencia UPDATE, en lugar de una sentencia DELETE. Estas son:

ON UPDATE CASCADE ON UPDATE SET NULL ON UPDATE RESTRICT

Vamos a ver un ejemplo, pero antes que nada, tenemos que eliminar la restriccin de clave fornea (debemos usar el ID especfico de nuestra tabla). mysql> ALTER TABLE venta DROP FOREIGN KEY 0_26; Query OK, 2 rows affected (0.22 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> ALTER TABLE venta ADD FOREIGN KEY(id_cliente) -> REFERENCES cliente(id_cliente) ON DELETE RESTRICT ON UPDATE CASCADE; Query OK, 2 rows affected (0.22 sec) Records: 2 Duplicates: 0 Warnings: 0 NOTA: Se debe especificar ON DELETE antes de ON UPDATE, ya que de otra manera se recibir un error al definir la restriccin. Ahora est lista la clave fornea para una actualizacin en cascada. Este es el ejemplo: mysql> SELECT * FROM venta; +------------+------------+----------+ | id_factura | id_cliente | cantidad | +------------+------------+----------+ | 1| 1| 23 | | 3| 2| 81 | +------------+------------+----------+ 2 rows in set (0.00 sec) mysql> UPDATE cliente SET id_cliente=10 WHERE id_cliente=1; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT * FROM venta; +------------+------------+----------+ | id_factura | id_cliente | cantidad | +------------+------------+----------+

| 1| 10 | 23 | | 3| 2| 81 | +------------+------------+----------+ 2 rows in set (0.00 sec) En este caso, al actualizar el valor de id_cliente en la tabla cliente, se actualiza de manera automtica el valor de la clave fornea en la tabla venta. Esta es la actualizacin en cascada. MySQL 3.23.37 S N N S N N N (nivel tabla) N N Muy bien N N S N N S S S N S Bien S N PostgreSQL 7.1 S S S S S S S S S Medio S S N S S S S S S S Muy Bien S S

Integridad Referencial Procedimientos Almacenados Vistas (views) Secuencias (generadores de nmeros) Subselects Rules (reglas) Locks a nivel de fila Concurrencia Multi Versin Tratamiento de Blobs Control acceso de usuarios Transacciones Triggers Multithread Limite tamao registro Orientacin a objetos Drivers JDBC Drivers ODBC Soporte nativo PHP Creacin de nuevos tipos de datos Backup OnLine Indexacin de texto Soporte Perl, C, Python, TCL, Java, Delphi Herencia

Facilidad instalacin Facilidad administracin Documentacin Web oficial Documentacin no oficial (news, webs, tutoriales) Configuracin PHP Potencia Velocidad Utilidad Web oficial Grandes Bases de datos Escalable Utilidades Backups Administracin remota desde Windows Estable (daemon no se muere) Multiplataforma Bsqueda de texto (Full-text-indexing) Consumo recursos (CPU y memoria) Adecuado para almacenar binarios

MySQL 3.23.37 de Muy bien Muy bien Muy bien Muy bien Muy bien Medio Muy bien Bien Medio Bien Medio Medio Bien Muy Bien Muy Bien Muy Bien Mal

PostgreSQL 7.1 Bien Bien Medio Muy bien Bien Muy bien Medio Bien Medio Medio Medio Medio Medio Muy Bien Bien Medio Muy bien

Insercin mil tuplas 100.000 17seg variados 1000 selects 55seg complejos

MySQL 3.23.37 PostgreSQL 7.1 100 10 seg. 12min 38seg 6min 30seg 1min 26seg

POSTGRESQL
INTEGRIDAD REFERENCIAL Una llave fornea es un atributo (puede ser compuesto) de una relacin 84#84 cuyos valores deben de concordar con los de una llave primaria de alguna relacin 85#85. Las relaciones 85#85 y 84#84 pueden incluso ser la misma. La idea es que tengamos concordancia entre datos de dos relaciones. Por ejemplo, si en una tabla de facturacin tenemos un atributo que es la llave de referencia a clientes, stos necesariamente deben de existir, en la tabla de clientes. En este caso la llave primaria de la tabla de clientes, es la llave ajena en la tabla de facturacin y no podemos emitir una factura a alguien que no es un cliente. A esta correspondencia se le conoce como integridad referencial. CLAVES FORANEAS Consideremos el siguiente problema: Usted desea estar seguro de que nadie pueda insertar registros de ciudades en la tabla weather, a menos que estas existan en la tabla cities. A esto se le llama integridad referencial de los datos. En sistemas de bases de datos simples esto se podra implementar mirando en la tabla cities si existe el registro de ciudad existe, y de acuerdo a esto insertando o rechazando la insercin de un nuevo registro en la tabla weather. Este mtodo tiene varios problemas y es poco conveniente, as que PostgreSQL hace eso por usted. La nueva declaracin de tablas sera as: CREATE TABLE cities ( city varchar(80) primary key, location point ); CREATE TABLE weather ( city varchar(80) references cities, temp_lo int, temp_hi int, prcp real, date date ); Ahora trate de ingresar un valor invalido: INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28'); ERROR: <unnamed> referential integrity violation - key referenced f rom weather not found in cities El comportamiento de las llaves foraneas puede ser correctamente sintonizado para su aplicacin. El hacer un uso correcto de las llaves foraneas definitivamente mejorar la calidad de sus aplicaciones para bases de datos.

VISTAS Suponga que para usted es de particular inters combinar un listado de registros climticos y ubicacin de las ciudades, pero no quiere digitar la bsqueda cada vez que lo necesita. Puede crear una vista sobre la bsqueda, con lo cual le da un nombre a la bsqueda,y en cualquier momento se puede referir a ella como una tabla: CREATE VIEW myview AS SELECT city, temp_lo, temp_hi, prcp, date, location FROM weather, cities WHERE city = name; SELECT * FROM myview; Hacer un buen uso de las vistas es un aspecto clave en el buen diseo de una base de datos SQL. Las vistas le permiten encapsular los detalles de la estructura de sus tablas, y consecuentemente le permiten cambiar segn evolucionen. Las vistas pueden ser usados casi en cualquier lugar donde podra ser usada una tabla verdadera. Hacer vistas de vistas no es algo inusual. RESTRICCIONES Constraints son restricciones en alguna columna en la definicin de una tabla. Hay varios tipos de restricciones disponibles tanto para las tablas como para las columnas, y se implementan de varias maneras. Algunas restricciones son implementadas como triggers, algunas como ndices, y otras son atributos de la definicin de una columna. Hay algunas indicaciones cuando se crea una tabla acerca de los triggers e ndices que se crean para llaves primarias y forneas. Son estos mensajes NOTICE: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 't1_pkey' for table 't1' NOTICE: CREATE TABLE / UNIQUE will create implicit index 't1_unq_key' for table 't1' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) Pero cuando el momento en que se entregaron estos mensajes pas hace mucho, es bueno poder saber exactamente cmo se implementan las restricciones definidas. Aqu hay una lista de las posibles restricciones y cmo se implementan. Las letras entre parntesis indican el tipo de restriccin: (p)rimary key, (u)nique, (f)function, (c)heck.

Clusula Constraint PRIMARY KEY UNIQUE FOREIGN KEY tabla referida tabla referida CHECK

de Nombre Constraint table_pkey (p)

de

Usos ndice ndice

Nombre de ndice/Trigger Funcin de Trigger table_pkey table_column_key RI_FKey_check_ins RI_FKey_noaction_del RI_FKey_noaction_upd

table_column_key (u) $n (f) $n (f) $n (f) table_column (c)

trigger RI_ConstraintTrigger_n trigger RI_ConstraintTrigger_n trigger RI_ConstraintTrigger_n check ninguno

Checks y otras restricciones


La restriccin CHECK se almacena como una restriccin especfica del atributo: no es una funcin ni un ndice. La expresin compilada de CHECK, junto con su cdigo fuente, se almacenan en la tabla pg_constraint. Los valores DEFAULT y las condiciones NOT NULL son, conceptualmente, restricciones, pero no son implementadas como otras restricciones, sino que son atributos de las columnas y se almacenan en las tablas pg_attributes y pg_attrdef.

Restricciones con Nombre


Los nombres por omisin de FOREIGN KEY, UNIQUE y CHECK pueden ser reemplazados. Para darle un nombre a una restriccin, preceda su definicin con CONSTRAINT nombre como se ilustra en el siguiente ejemplo. create table showconstraints ( id integer PRIMARY KEY, unq integer CONSTRAINT sc_unq UNIQUE, checkme integer CONSTRAINT posval CHECK ( checkme > 0 ) );