Lenguaje de Definición de Datos TEMA 6: LENGUAJE DE DEFINICIÓN DE DATOS (LDD) 6.1 Introducción Hasta ahora hemos estudiado las sentencias que forman parte del DML (Data Management Language) lenguaje de manipulación de datos, todas esas sentencias sirven para recuperar, insertar, borrar, modificar los datos almacenados en la base de datos; lo que veremos en este tema son las sentencias que afectan a la estructura de los datos. El LDD (Data Definition Language) es la parte del SQL que más varía de un sistema a otro ya que esa área tiene que ver con cómo se organizan internamente los datos y eso, cada sistema lo hace de una manera u otra. El LDD de SQL permite la especificación no sólo de un conjunto de relaciones, sino también de alguna información relativa a esas relaciones, incluyendo: ♦ El esquema de cada relación. ♦ El dominio de valores asociado a cada atributo. ♦ Las restricciones de integridad. ♦ El conjunto de índices que se deben mantener por cada relación. ♦ Información de seguridad y autorización para cada relación. ♦ La estructura de almacenamiento físico de cada relación en disco. El lenguaje de definición de datos (en inglés Data Definition Language, o DDL), es el que se encarga de la modificación de la estructura de los objetos de la base de datos. Existen cuatro operaciones básicas: CREATE, ALTER, DROP y TRUNCATE. 6.2 Tipos de dominios en SQL La norma SQL soporta un conjunto de tipos de dominios predefinidos, que incluye los siguientes: ♦ char(n): Cadenas de caracteres de tamaño fijo, con una longitud n especificada por el usuario de hasta un máximo de 255. También se puede utilizar la palabra completa character. ♦ varchar(n): Es una cadena de caracteres de longitud variable, con una longitud n especificada por el usuario de hasta un máximo de 2000 caracteres. También se puede utilizar la forma completa character varying. ♦ int: Es un entero. También se puede utilizar la palabra completa integer. ♦ smallint: Es un entero pequeño (Un subconjunto del dominio de los enteros). ♦ numeric(p,d): Es un número en coma flotante, cuya precisión la especifica el usuario. El número está formado por p dígitos y de esos p dígitos d pertenecen a la parte decimal. ♦ real, double precision: Son respectivamente números en coma flotante y números en coma flotante de doble precisión, con precisión dependiente de la máquina. ♦ float(n): Es un número en coma flotante, cuya precisión es de al menos n dígitos. ♦ date: Es una fecha del calendario, que contiene un año (de cuatro dígitos), un mes y un día del mes. ♦ time: Es la hora del día, expresada en horas, minutos y segundos. ♦ timestamp: Es una combinación de date y time. Los valores de fecha y hora se pueden especificar como: date ‘2009-05-11’ time ’09:30:00’ timestamp: ‘2009-05-11 09:35:00’ 1 Lenguaje de Definición de Datos ♦ raw(Longitud): Representa valores binarios de longitud máxima de 255 bytes. ♦ Long Raw: Igual que el tipo anterior con la diferencia que el tamaño máximo es de 2 gigabytes ♦ Rowid: Tipo de dato binario que representa la dirección de una tupla de una tabla. Ejemplo: create table Cine ( nombre_cine varchar(15) NOT NULL, ciudad_cine varchar(15), direccion_cine varchar(25), CONSTRAINT pk_cine PRIMARY KEY (cine), CONSTRAINT (ck_cin)); 6.3 Definición de esquemas en SQL 6.3.1 Create Table Un esquema de relación se define utilizando la orden create table: create table r (A1D1,A2D2……AnDn, (restricción_integridad1), ……. restricción_integridadk)) Donde r es el nombre de la relación, cada Ai es el nombre de un atributo del esquema de relación r y Di es el dominio de los valores del atributo Ai. Para escribir una sentencia CREATE TABLE se empieza por indicar el nombre de la tabla que queremos crear y a continuación entre paréntesis indicamos separadas por comas las definiciones de cada columna de la tabla, la definición de una columna consta de su nombre, el tipo de dato que tiene y podemos añadir si queremos una serie de especificaciones que deberán cumplir los datos almacenados en la columna, después de definir cada una de las columnas que compone la tabla se pueden añadir una serie de restricciones, esas restricciones son las mismas que se pueden indicar para cada columna pero ahora pueden afectar a más de una columna por eso tienen una sintaxis ligeramente diferente. ♦ primary key: (Aj1,Aj2…..Ajn): la especificación de clave primaria dice que los atributos Aj1,Aj2…..Ajn forman la clave primaria de la relación. Los atributos de la clave primaria deben ser no nulos y únicos; es decir, ninguna tupla puede tener un valor nulo para un atributo de la clave primaria y ningún par de tuplas pueden de la relación pueden ser iguales en todos los atributos de la clave primaria. Aunque la especificación de clave primaria es opcional, es generalmente buena idea especificar una clave primaria para cada relación. En una tabla no pueden haber varias claves principales, por lo que no podemos incluir la cláusula PRIMARY KEY más de una vez, en caso contrario la sentencia da un error. No hay que confundir la definición de varias claves principales con la definición de una clave principal compuesta por varias columnas, esto último sí está permitido. ♦ check(P): Especifica un predicado P que debe satisfacer cada tupla de la relación. 2 Lenguaje de Definición de Datos Ejemplo: Utilización de la cláusula check para simular un tipo enumerado especificando que nivel_estudios debe ser <<Graduado>>, <<Licenciado>>, <<Doctorado>>. create table estudiante( (nombre_est varchar(30) not null, no_carnet varchar(10) not null, nivel_estudios char(15) not null, primary key(no_carnet), check (nivel_estudios in (‘Graduado’, ‘Licenciado’, ‘Doctorado’)) ) ♦ unique (Aj1,Aj2…..Ajn): Indica que los atributos Aj1,Aj2…..Ajn forman una clave candidata; es decir; no puede haber tuplas en la relación con todos los atributos que forman la clave candidata iguales. Sin embargo, se permite que los atributos que formal la clave candidata sean nulos, a menos que se hayan declarado como not null. Ejemplo: create table ejemplo( col1 integer constraint pk primary key, col2 char(25) not null, col3 CHAR(10) constraint uni1 unique, col4 integer, col5 int constraint fk5 references ejemplo2 ); Con este ejemplo estamos creando la tabla ejemplo compuesta por: una columna llamada col1 de tipo entero definida como clave principal, una columna col2 que puede almacenar hasta 25 caracteres alfanuméricos y no puede contener valores nulos, una columna col3 de hasta 10 caracteres que no podrá contener valores repetidos, una columna col4 de tipo entero sin ninguna restricción, y una columna col5 de tipo entero clave foránea que hace referencia a valores de la clave principal de la tabla ejemplo2. Ejemplo: Definición de datos en SQL para parte de la Base de Datos del Banco create table Cliente( (nombre_cliente char(20) not null), calle_cliente varchar(50), ciudad_cliente char(30)), primary key (nombre_cliente) ) create table Sucursal( (nombre_sucursal varchar(30) not null) ciudad_sucursal char(30)), activo float, primary key (nombre_sucursal), check (activo>=0) ) 3 Lenguaje de Definición de Datos create table Cuenta( (numero_cuenta char(10) not null) nombre_sucursal varchar(30)), saldo float, primary key (numero_cuenta), check (saldo>=0) ) 6.3.2 Integridad Referencial en SQL Las claves primarias pueden especificarse como parte de la instrucción create table de SQL usando las cláusula foreign key. De manera predeterminada, una clave externa referencia los atributos que forman la clave primaria de la tabla referenciada. SQl también soporta una versión de la cláusula referentes, donde se puede especificar explícitamente una lista de atributos de la relación referenciada. Esta lista se debe declarar como clave candidata de la relación referenciada. Se puede usar la siguiente forma abreviada como parte de la definición de un atributo para declarar que el atributo forma una clave externa: ♦ nombre_sucursal char (30) references Sucursal Cuando se viola una restricción de integridad referencial, el procedimiento normal es rechazar la acción que provocó la violación. Sin embargo, la cláusula foreign key puede especificar que si una acción de borrado o de actualización de la relación a la que hace referencia viola la restricción, en lugar de rechazar la acción, hay que adoptar las medidas para modificar la tupla de la relación que hace la referencia con objeto de restaurar la restricción create table Impositor( (numero_cliente char(20) not null) numero_cuenta char(10), primary key (numero_cuenta, nombre_cliente), foreign key (numero_cuenta) referentes Cuenta, foreign key (nombre_cliente) referentes Cliente ) create table Cuenta( (numero_cuenta char(10) not null) nombre_sucursal varchar(30)), saldo float, primary key (numero_cuenta), foreign key (nombre_sucursal) references Sucursal, check (saldo>=0) ) 6.3.3 Alter table La sentencia ALTER TABLE sirve para modificar la estructura de una tabla que ya existe. Mediante esta instrucción podemos añadir columnas nuevas, eliminar columnas. Ten cuenta que cuando eliminamos una columna se pierden todos los datos almacenados en ella. 4 Lenguaje de Definición de Datos También nos permite crear nuevas restricciones o borrar algunas existentes. La sintaxis puede parecer algo complicada pero sabiendo el significado de las palabras reservadas la sentencia se aclara bastante; ADD (añade), ALTER (modifica), DROP (elimina), COLUMN (columna), CONSTRAINT (restricción). La sintaxis de la instrucción es: ♦ alter table r add A D Donde r es el nombre de la relación existente, A es el nombre del atributo que se desea añadir y D es el dominio (tipo de dato) del atributo A. ♦ Para añadir una nueva restricción en la tabla podemos utilizar la cláusula ADD restriccion2 (ADD CONSTRAINT...). Ejemplo: ♦ alter table tab1 add constraint c1 unique (col3) Con este ejemplo estamos añadiendo a la tabla tab1 un índice único (sin duplicados) llamado c1 sobre la columna col3. ♦ Para borrar una columna basta con utilizar la cláusula drop column (column es opcional) y el nombre de la columna que queremos borrar, se perderán todos los datos almacenados en la columna. Ejemplo: ♦ alter table tab1 drop column col3 También podemos escribir: ♦ alter table tab1 drop col3 El resultado es el mismo, la columna col3 desaparece de la tabla tab1. ♦ Para borrar una restricción basta con utilizar la cláusula drop constraint y el nombre de la restricción que queremos borrar, en este caso sólo se elimina la definición de la restricción pero los datos almacenados no se modifican ni se pierden. Ejemplo: ♦ alter table tab1 drop constraint c1 Con esta sentencia borramos el índice c1 creado anteriormente pero los datos de la columna col3 no se ven afectados por el cambio. 6.3.4 Drop Table La sentencia drop table sirve para eliminar una tabla. No se puede eliminar una tabla si está abierta, tampoco la podemos eliminar si el borrado infringe las reglas de integridad referencial (si interviene como tabla padre en una relación y tiene registros relacionados). 5 Lenguaje de Definición de Datos La sintaxis es la siguiente: ♦ drop table r Tiene una repercusión más drástica que: delete from r 6.3.5 Truncate table Esta sentencia elimina todas las filas de una tabla sin registrar las eliminaciones individuales de filas. truncate table es similar a la instrucción DELETE sin una cláusula WHERE; no obstante, TRUNCATE TABLE es más rápida y utiliza menos recursos de registros de transacciones y de sistema. La sintaxis es la siguiente: ♦ truncate table r Por ejemplo, queremos vaciar la tabla "Cliente", usamos: truncate table Cliente En comparación con la instrucción DELETE, TRUNCATE TABLE: ♦ La instrucción delete quita una a una las filas y graba una entrada en el registro de transacciones por cada fila eliminada. TRUNCATE TABLE quita los datos al cancelar la asignación de las páginas de datos utilizadas para almacenar los datos de la tabla y sólo graba en el registro de transacciones las cancelaciones de asignación de páginas. ♦ No es transaccional. No se puede deshacer. ♦ La sentencia TRUNCATE no admite cláusula WHERE. Borra toda la tabla. ♦ No todos los gestores de bases de datos admiten la sentencia TRUNCATE. ♦ truncate table quita todas las filas de una tabla, pero permanecen la estructura y sus columnas, las restricciones, etc. Para quitar la definición de tabla además de los datos, utilice la instrucción DROP TABLE. ♦ Otra diferencia es la siguiente: cuando la tabla tiene un campo "Autonumérico", si borramos todos los registros con "delete" y luego ingresamos un registro, al cargarse el valor en el campo autoincrementable, continúa con la secuencia teniendo en cuenta el valor mayor que se había guardado; si usamos "truncate table" para borrar todos los registros, al ingresar otra vez un registro, la secuencia del campo autoincrementable vuelve a iniciarse en 1. Por ejemplo, tenemos la tabla "Cliente" con el campo "codigo" definido "Autonumérico", y el valor más alto de ese campo es "5", si borramos todos los registros con "delete" y luego ingresamos un registro sin valor de código, se guardará el valor "6"; si en cambio, vaciamos la tabla con "truncate table", al ingresar un nuevo registro sin valor para el código, iniciará la secuencia en 1 nuevamente. Restricciones: No puede utilizar TRUNCATE TABLE en: Tablas a las que se hace referencia mediante una restricción FOREIGN KEY. (Puede truncar una tabla que tenga una clave externa que haga referencia a sí misma). 6