Los pasos del diseño de una Base de Datos, representados en la siguiente figura, se pueden resumir en
Es un modelo de datos que representa la realidad a través de entidades , que son objetos que existen y se distinguen de otros por sus características, que llamamos atributos. Además, estas entidades podrán o no estar relacionadas unas con otras a través de lo que se conoce como relación. Hay que tener en cuenta que se trata solamente de un modelo de representación, por lo que no tiene correspondencia real con ningún sistema de almacenamiento. Se utiliza en la etapa de Análisis y Diseño de una Base de Datos, por lo que habrá que convertirla a otro modelo antes de poder empezar a trabajar con ella.
Una entidad es un objeto que existe en una realidad que queremos representar, por ejemplo, un alumno, que se distingue de otro por sus características como pueden ser: el nombre, los apellidos, el número de expediente, . . .
Las entidades se representan por el siguiente símbolo:
Esas características que hacen que unas entidades se distingan de otras, son los atributos. El nombre, los apellidos y el número de expediente serían atributos de la entidad alumno. Los atributos se representan por el siguiente símbolo:
A su vez, podemos relacionar unas entidades con otras a través de lo que se conoce como relación. Por ejemplo, dos entidades alumno y asignatura podrían estar relacionadas entre sí puesto que un alumno cursa una asignatura (o varias). Conviene resaltar que una relación entre dos entidades no expresa obligatoriedad de relación sino posibilidad de relacionarse.
En este caso, no será necesario que todos los alumnos cursen una asignatura o que una asignatura sea cursada por todos los alumnos para que la relación se establezca. Por tanto, en este caso se establece que entre esas dos entidades existe una relación a la que podríamos llamar cursa. Las relaciones se representan por el siguiente símbolo:
Si consideramos que dos entidades A y B están relacionadas a través de una relación R, deberemos determinar lo que se conoce como cardinalidad de la relación, que determina cuantas entidades de tipo A se relacionan, como máximo, con cuantas entidades de tipo B. Además, resulta conveniente, en cada caso, calcular cuántas entidades de tipo A se relacionan, cómo mínimo, con cuantas entidades de tipo B (que normalmente será 0 ó 1). De esa manera podremos indicar la obligatoriedad o no de relación entre elementos de las entidades A y B.
En esta relación una entidad de tipo A sólo se puede relacionar con una entidad de tipo B, y viceversa. Por ejemplo, si suponemos dos entidades Curso y Aula, relacionadas a través de una relación Se Imparte, podremos suponer que un Curso se imparte en una Aula y en una Aula sólo se puede impartir un Curso. Se representaría como sigue:
Indica que una entidad de tipo A se puede relacionar con un número indeterminado de entidades de tipo B, pero a su vez una entidad de tipo B sólo puede relacionarse con una entidad de tipo A. Si suponemos una entidad Propietario y otra entidad Vehículo relacionadas a través de una relación Posee, podremos suponer que un Propietario puede poseer varios Vehículos, mientras que cada Vehículo sólo puede pertenecer a un Propietario.
Quedaría representado de la siguiente manera:
Significa que una entidad de tipo A sólo puede relacionarse con una entidad de tipo B, pero una entidad de tipo B puede relacionarse con un número indeterminado de entidades de tipo A. En realidad se trata como una relación uno a muchos pero el sentido de la relación es el inverso.
En este caso, tanto las entidades de tipo A y B, pueden relacionarse con un número indeterminado de entidades del otro tipo. Por ejemplo, si suponemos las entidades Alumno y Asignatura y una relación Cursa, podremos suponer que un Alumno cursa varias asignaturas mientras que una Asignatura la cursan varios Alumnos. Quedaría representado de la siguiente manera:
Se conoce como Diagrama Entidad/Relación (E/R) al diagrama resultante de modelar un mundo real siguiendo el modelo Entidad/Relación. Como resultado, se modelan todas las entidades con sus atributos, así como todas las relaciones existentes entre ellas, junto con su cardinalidad.
También es posible representar otro tipo de relaciones entre objetos de nuestro sistema. La relación de herencia, representada como un triángulo (ver figura), expresa que un objeto es un subtipo de otro objeto. También se suele considerar al subtipo como una especialización del primero o al primero como una generalización del segundo.
En el caso del ejemplo, existen dos tipos de empleados que se relacionan de forma diferente con otros objetos del sistema, pero que a su vez pueden tener gran parte en común. Por ejemplo, trabajan de forma diferente pero muchos de los datos personales que almacenaremos de ambos son comunes. Es por eso que el objeto Empleado se puede considerar una generalización de los dos tipos de trabajadores que hay en el sistema. Todos aquellos atributos y relaciones que tengan en común se podrá representar como atributos y funcionalidad del objeto Empleado y los atributos y relaciones que tengan como trabajadores especializados serán representados en el correspondiente objeto.
Es posible que la misma entidad ocupe ambos lados de una relación. En ese caso estamos frente a lo que se conoce como relaciones reflexivas. La cardinalidad de la relación indicará si todos los elementos de la relación están relacionados reflexivamente o bien sólo algunos están relacionados entre sí. En el caso de la figura podríamos suponer una empresa en la que algunos empleados hacen de supervisor de otros empleados.
Los atributos multivaluados son aquellos atributos que pueden contener una cantidad indeterminada de valores.
Los atributos estructurados o compuestos son aquellos atributos que pueden estar compuestos por otros atributos. Normalmente son atributos que pueden descomponerse aunque dependiendo del contexto de la aplicación puede no interesar hacer esa descomposición y tratarlo como un atributo simple.
Los atributos derivados (o calculados) son aquellos atributos cuyo valor puede ser deducido realizando algunas operaciones con otros atributos de la misma entidad o de otras entidades. En algunas situaciones se podría considerar redundante (puesto que su valor se puede deducir) pero en otras puede resultar cómodo almacenarlo ya calculado puesto que se puede ahorrar mucho tiempo de cómputo si se trata de un valor de díficil y/o recurrente cálculo.
El modelo relacional es otro modelo de representación en el que los datos y sus relaciones se representan a través de tablas, y en el que los atributos se traducen en campos de esas tablas. Es el modelo de representación que siguen la gran mayoría de los SGBD relacionales (MySQL, SQL Server, Oracle, Ms Access, entre otros) en la actualidad, puesto que es el modelo de datos más extendido.
Así, es necesario transformar nuestro modelo Entidad/Relación a un modelo relacional si queremos crear nuestra Base de Datos en algún SGBD relacional.
El paso de un modelo E/R a un modelo relacional se puede llevar a cabo, en gran parte, siguiendo una serie de reglas o pautas, que se enumeran a continuación:
Las situaciones más particulares habrá que estudiarlas y aplicar algún patrón de diseño conocido, si lo hay, para generar el correspondiente modelo relacional. Estos casos no siempre se podrán reflejar en el correspondiente modelo Entidad-Relación puesto que algunos tienen que ver con exigencias técnicas o de tiempo, más que con el propio modelo de datos. Algunos casos particulares pueden ser:
En cualquier caso, aplicar correctamente al modelo relacional resultante las reglas de normalización eliminará todas las anomalías que nuestro modelo pueda contener. Así, hay que tener en cuenta que el modelo relacional que hemos obtenido en este momento todavía puede no ser el definitivo y puede sufrir transformaciones (e incluso se pueden añadir nuevas tablas) como resultado de aplicar las reglas de normalización que se pasan a explicar en el siguiente punto.
Uno de los retos en el diseño de toda Base de Datos es el obtener una estructura estable tal que:
Una Base de Datos bien diseñada tiene mayor esperanza de vida, incluso en un ambiente dinámico donde puedan aparecer nuevos requisitos, que una Base de Datos con un diseño pobre. Como media, una Base de Datos puede sufrir una reorganización cada seis años, dependiendo de lo dinámico que sean sus requisitos. Si la Base de Datos se diseño bien seguirán teniendo un buen rendimiento aunque aumente el tamaño, y será lo suficientemente flexible para soportar los nuevos requisitos y/o características adicionales.
Actualmente existen diversos riegos en el diseño de Bases de Datos relacionales. Los más habituales son la redundancia de información y la inconsistencia de datos.
La normalización es el proceso de simplificar la relación entre los campos de un registro de forma que éste se reemplaza por varios registros más simples y predecibles y, por tanto, más manejables. En definitiva, la normalización busca simplificar el diseño para que éste sea más fácil incorporar nuevas funcionalidades con el paso del tiempo y no baje su rendimiento cuando la cantidad de datos almacenados en ella aumenten considerablemente.
La teoría de la normalización se basa en lo que se conoce como Formas Normales. Cada una de estas Formas Normales establece una serie de restricciones que el diseño deberá cumplir para satisfacer dicha Forma. En este curso veremos las tres primeras FN (Formas Normales).
Se dice que una tabla está en primera forma normal si una tabla posee las siguientes propiedades:
Supongamos el caso más común, que un campo pueda tener más de un valor. Para normalizar una tabla que no está en primera forma normal por esta razón, se han de seguir estos pasos:
Para el caso de tablas que incumplen la última de las propiedades y posee columnas con valores repetidos (una tabla de clientes con los campos teléfono 1, teléfono 2, teléfono 3, . . .) se opera de forma muy similar, puesto que se dichos valores se deben almacenar en una nueva tabla y utilizar la clave principal de la primera para referenciar estos nuevos valores.
Esta formal normal sólo debe ser considerada para aquellas tablas en las que la clave principal sea compuesta. Si no fuera así, la tabla estaría, de forma directa, en segunda forma normal.
Decimos que una tabla está en segunda forma normal si se cumplen las siguientes condiciones:
Se dice un atributo B depende funcionalmente de A (A→B
) si cada valor de A se corresponde con un único valor de B. Visto de otra manera, si dado A puedo obtener B. Un caso típico podría ser DNI → Nombre
, puesto que dado un DNI puedo obtener, de forma unívoca, el nombre de la persona
Para convertir una tabla que no está en 2FN se creará una tabla con la clave y todas sus dependencias funcionales totales y otra tabla con la parte de la clave que tiene dependencias con los atributos secundarios.
En el ejemplo podemos ver como el campo TelefonoProveedor no depende totalmente de la clave (NombreProducto, NombreProveedor), sino únicamente del campo NombreProveedor.
Se dice que una tabla está en tercera forma normal si:
Para convertir una tabla que no está en 3FN se realizará una proyección de la clave a los elementos que no tengan dependencia funcional transitiva y otra tabla con una nueva clave a los elementos que anteriormente tenían esta dependencia.
En el ejemplo, es posible conocer la edad del inscrito a través del número de licencia, y dada la edad podemos conocer su categoría, tenemos una dependencia funcional transitiva. Lo importante es tener en cuenta que la categoría depende de un atributo que no forma parte de la clave. Para normalizar, debemos descomponer esa tabla en las tablas Atletas y Categorías
El lenguaje SQL (Structured Query Language) permite la comunicación con el SGBD. Actualmente es el lenguaje estándar para la gestión de Bases de Datos relacionales para ANSI (American National Standard Institute) e ISO (International Standarization Organization). Entre las principales características de este lenguaje destaca que es un lenguaje para todo tipo de usuarios ya que quién lo utiliza especifica qué quiere, pero no dónde ni cómo, de manera que permite realizar cualquier consulta de datos por muy complicada que parezca.
En el lenguaje SQL, dependiendo de las tareas que se quieran realizar, se distinguen dos tipos de sentencias. Sentencias DDL (Data Definition Language) que sirven para especificar y gestionar estructuras de datos, y las sentencias DML (Data Manipulation Language) que sirven para trabajar con los datos almacenados en dichas estructuras.
Puesto que por ahora abordaremos aquellas sentencias que nos van a permitir crear nuestras Bases de Datos en un SGBD relacional, comenzaremos por ver el grupo de sentencias DDL, que son las que se citan a continuación:
Es la sentencia utilizada para la creación de un objeto (base de datos, tabla, usuario, vista, procedimiento, . . .) en una Base de Datos.
La sintaxis para la creación de una tabla es la siguiente:
CREATE TABLE [IF NOT EXISTS] <nombre_tabla> ( <nombre_columna1> <tipo_dato> <restricciones>, <nombre_columna2> <tipo_dato> <restricciones>, ................................ )
Y para crear una Base de Datos:
CREATE DATABASE [IF NOT EXISTS] <nombre_base_de_datos>
Es la sentencia utilizada para eliminar objetos (tabla, usuario, vista, procedimiento, . . .) en una Base de Datos.
La sintaxis para la eliminación de tablas es la siguiente:
DROP TABLE [IF EXISTS] <nombre_tabla>
Y para eliminar una Base de Datos:
DROP DATABASE [IF EXISTS] <nombre_base_de_datos>
Es la sentencia utilizada para modificar objetos (tabla, usuario, vista, procedimiento, . . .) en una Base de Datos.
La sintaxis para modificar una tabla es la siguiente:
ALTER TABLE <nombre_tabla> [ ADD <definicion_columna> ] [ CHANGE <nombre_columna> <definicion_columna> ] [ DROP COLUMN <nombre_columna> ] [ ADD CONSTRAINT <restriccion> ]
Permite conceder privilegios sobre un objeto a un usuario de la Base de Datos.
GRANT <privilegio> ON <objeto> TO <usuario> [WITH GRANT OPTIONS]
Permite eliminar el privilegio sobre un objeto a un usuario.
REVOKE <privilegio> ON <objeto> FROM <usuario>
Permite realizar la conexión con una Base de Datos de MySQL.
USE <nombre_base_de_datos>
Este tipo de datos permite almacenar cadenas de texto fijas (CHAR
) o variables (VARCHAR
).
El tipo CHAR
permite almacenar cadenas de caracteres de longitud fija entre 1 y 255 caracteres. La longitud de la cadena se debe especificar entre paréntesis en el momento de la declaración (cadena CHAR(25)
).
Por otro lado, el tipo VARCHAR
permite almacenar cadenas de caracteres variables de hasta 4.000 caracteres. La declaración del tipo VARCHAR
es similar a la de un tipo CHAR (cadena VARCHAR(25)
). La principal y única diferencia entre estos dos tipos, es que el tipo CHAR
declara una cadena fija de la longitud que se especifica mientras que en la declaración de un tipo VARCHAR
lo que se especifica es un tamaño máximo, la cadena sólo ocupará el tamaño necesario para almacenar el dato que contenga (hasta llegar al máximo). En cualquier caso, no es posible almacenar cadenas de mayor tamaño al especificado en su declaración, puesto que el SGBD truncará el valor almacenándose sólo hasta la longitud establecida.
El tipo TEXT
permite almacenar cadenas de caracteres de hasta varios GB de longitud. Sólo se recomienda su uso para almacenar textos realmente grandes, puesto que presenta ciertas restricciones, aunque algunas pueden variar dependiendo del SGBD que se utiliza:
TEXT
por tabla
Para la representación de tipos de datos numéricos. Los tipos más utilizados son BIT
, TINYINT
, INT
, BIGINT
, FLOAT
y REAL
, para la representación de números enteros de menor o mayor tamaño, y para números en coma flotante de menor o mayor precisión, respectivamente.
En ocasiones el rango de los valores negativos resultará prescindible (claves numéricas, valores de dinero, cantidades, . . .) por lo que será posible ampliar el rango positivo de un tipo numérico añadiendo la restricción UNSIGNED
tras definir el tipo de éste.
id INT UNSIGNED
Para el caso de los números de coma flotante conviene tener en cuenta los problemas de precisión 1) que existen con estos tipos de datos.
Los tipos más utilizado para almacenar valores de fechas (DATE
) o fechas con hora (DATETIME
). Por defecto el formato más utilizado es DD/MM/YY
ó DD/MM/YYYY
.
También se puede usar el tipo TIMESTAMP
para almacenar una marca de tiempo (fecha y hora). Además, permite el uso de la constante CURRENT_TIMESTAMP
en la definición de la columna al definirle un valor por defecto cuando se crea la tabla.
Permite almacenar valores lógicos Verdadero/Falso o Sí/No. Realmente se define la columna como del tipo TINYINT
, que simplemente almacena los valores 0 y 1 para indicar los valores lógicos Verdadero y Falso, respectivamente. Así, podremos utilizar los valores TRUE
ó FALSE
o directamente asignar 1 ó 0 para asignar valor.
Las restricciones se pueden establecer, o no, a las columnas de cada tabla para forzar a que los datos almacenados en ellas cumplan una serie de condiciones, con la finalidad de que la información sea más correcta. Por ejemplo, podemos obligar a que un campo donde almacenamos el DNI de una persona tenga una longitud mínima, o bien un campo donde almacenamos la categoría de un equipo de fútbol, sólo pueda tomar unos determinados valores predefinidos (benjamín, juvenil, cadete, . . .) o bien podemos hacer que un campo no pueda repetirse, por tratarse de un valor único (DNI, NSS, teléfono, email, . . .).
Hay que tener en cuenta que, por lo general, las restricciones se definen en línea con la definición del campo (tal y como se muestra en la sintaxis de la sentencia de CREATE TABLE
, pero de forma opcional también pueden ser definidas por separado justo debajo de la definición de todos los campos de la tabla.
Una clave primaria dentro de una tabla, es una columna o conjunto de columnas cuyo valor identifica unívocamente a cada fila. Debe ser única, no nula y es obligatoria. Como máximo podremos definir una clave primaria por tabla y es muy recomendable definirla.
Para definir una clave primaria utilizamos la restricción PRIMARY KEY
.
dni VARCHAR(9) PRIMARY KEY
Y si lo hacemos al final de la definición de las columnas, quedaría así:
PRIMARY KEY (dni)
Hay que tener en cuenta que a la hora de definir claves primarias compuestas (la componen 2 ó más campos de la tabla), ésta deberá ser definida forzosamente tras la definición de los campos involucrados, siguiendo esta sintaxis
PRIMARY KEY (nombre, apellidos)
Especialmente útil en el caso de aquellas columnas que se definan como claves primarias de cada tabla, resulta añadir la restricción de campo autonumérico, siempre y cuando ésta sea una columna de tipo entero. De esa manera será el SGBD el encargado de asignarle valor de forma automática, siempre asignando un valor entero de forma secuencial a medida que se van insertando las filas en dicha tabla.
La forma de definirlo es añadiendo la restricción AUTO_INCREMENT
en la definición de la columna que se ha definido como clave primaria:
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT
Una clave ajena está formada por una o varias columnas que hacen referencia a una clave primaria de otra o de la misma tabla. Se pueden definir tantas claves ajenas como sea necesario (no hay límite). El valor de la columna o columnas que son clave ajena será NULL, o bien el valor de la clave primaria de la tabla a la que hacen referencia (integridad referencial). Así, a la hora de definir una clave ajena, deberemos indicar con la cláusula REFERENCES
la tabla a que ésta hace referencia (se tomará automáticamente la clave primaria de ésta como campo con el que mantener la integridad referencial).
Habrá que tener en cuenta que mientras que un campo definido como clave ajena haga referencia a un campo definido como clave primaria, la columna de la segunda tabla no podrá ser eliminada hasta que no lo haga la columna que le hace referencia (integridad referencial). Para evitar estos problemas (aunque no siempre es un problema) es posible definir la restricción de clave ajena añadiendo la cláusula ON DELETE
o bien ON UPDATE
para el caso de una actualización. De esa manera, cuando se vaya a eliminar o actualizar una fila a cuya clave primaria se haga referencia, podremos indicar a MySQL que operación queremos realizar con las filas que le hacen referencia:
NULL
el valor en las filas que hacen referenciaRESTRICT
A continuación, un par de ejemplos que definen claves ajenas con diferentes cláusulas:
FOREIGN KEY (id_curso) REFERENCES cursos (id) FOREIGN KEY (id_curso) REFERENCES cursos (id) ON DELETE CASCADE
Como ocurre con las claves primarias, si las claves ajenas son compuestas, se definen forzosamente al final de las definiciones de las columnas de la tabla, de la siguiente forma:
FOREIGN KEY (id_curso, id_aula) REFERENCES cursos FOREIGN KEY (id_curso, id_aula) REFERENCES cursos ON DELETE CASCADE
En cualquiera de los casos hay que tener en cuenta que habrá que definir primero el campo con el tipo de dato correcto (el mismo que dicho campo en la tabla donde aparece como clave principal) y luego la propia definición de dicho campo como clave ajena.
Para definir claves ajenas en MySQL habrá que tener en cuenta algunas consideraciones:
NOT NULL
) no podrá contener la claúsula (SET NULL
) para los casos de borrado (ON DELETE
) o actualización (ON UPDATE
)CREATE TABLE tabla ( . . . . . . ) ENGINE = Innodb;
Así, normalmente, en MySQL definiremos una clave ajena de la siguiente forma:
id_cliente INT UNSIGNED, INDEX (id_cliente), FOREIGN KEY (id_cliente) REFERENCES Clientes (id) ON DELETE SET NULL ON UPDATE SET NULL,
En el caso anterior suponemos que la clave primaria a la cual se hace referencia está definida como sigue:
CREATE TABLE Clientes ( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, . . . );
Actualmente, a partir de MySQL 8.0 (y versiones equivalentes de MariaDB) es suficiente definir el campo y la restricción de clave ajena para que el gestor haga el resto (definir dicho campo como índice). El caso anterior se podría reducir a:
id_cliente INT UNSIGNED, FOREIGN KEY (id_cliente) REFERENCES Clientes (id) ON DELETE SET NULL ON UPDATE SET NULL,
Esta restricción obliga a que se le tenga que dar valor obligatoriamente a una columna. Por tanto, no podrá tener el valor NULL. Se utiliza la palabra reservada NOT NULL
.
apellidos VARCHAR(250) NOT NULL
Se puede definir el valor que una columna tomará por defecto, es decir, si al introducir una fila no se especifica valor para dicha columna. Se utiliza la palabra reservada DEFAULT
.
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP nombre VARCHAR(250) DEFAULT 'Sin nombre'
De forma más genérica, podemos forzar a que los valores de determinados campos de la tabla cumplan una ciertas condiciones. En caso contrario no se permitirá la inserción de esa fila en dicha tabla.
nombre VARCHAR(250) CHECK (nombre = UPPER(nombre)) edad INT CHECK (edad > 0) curso INT CHECK (curso BETWEEN 1 AND 2)
Hay que tener en cuenta que en MySQL está restricción no tiene ningún efecto y lo habitual es definir una columna como de tipo enumeración (ENUM
en MySQL) si queremos indicar que solamente una serie de valores (definidos) son válidos:
curso ENUM ('0', '1', '2'), horario ENUM ('mañana', 'tarde', 'noche'),
La restricción UNIQUE
evita valores repetidos en una misma columna. Al contrario que ocurre con la restricción PRIMARY KEY
, la restricción de valor único se puede aplicar a varias columnas de una misma tabla y admite el valor NULL
. Con respecto a esta última consideración, conviene saber que si una columna se define como UNIQUE
, sólo una de sus filas podrá contener el valor NULL
email VARCHAR(100) UNIQUE
Los índices se utilizan para obtener datos de las tablas de una forma más rápida. En definitiva, lo que el SGBD hace es asociar el valor de una columna (sobre la que definimos el índice) con su posición en la tabla. De esa manera será más rápido buscar sobre esa columna puesto que al encontrar el valor, el SGBD conocerá su posición en la tabla.
Se recomienda su uso en aquellas columnas sobre las que se vayan a realizar búsquedas en una tabla. Por ejemplo, si tenemos una tabla donde almacenamos información sobre Libros, nos podría interesar crear un índice en el campo autor, puesto que puede ser muy común buscar qué libros ha escrito un autor determinado. Además, será un valor que contendrá pocos valores repetidos, por lo que maximizará el beneficio de usar un índice.
INDEX autor_index (autor)
Por otra parte, los índices presentan algún inconveniente como puede ser el hecho de que ocupan espacio en la tabla, y dependiendo del caso podría llegar a ocupar más espacio que la propia tabla, por lo que hay que tener cuidado a la hora de escoger una columna como índice. También hay que tener en cuenta que hay que actualizar el índice cada vez que se modifica la columna en la tabla por lo que no resulta conveniente elegir como índices aquellas columnas que creamos que van a escribirse con mucha frecuencia.
Como se vió en el tema anterior, una de las funciones del SGBD es la de proporcionar seguridad en el acceso a los datos a través de mecanismos de control de acceso.
En SQL, y así lo hacen todos los SGBD relacionales, se sigue un modelo Usuario-Privilegio para otorgar acceso a los objetos de la Base de Datos. Existen una serie de privilegios predefinidos y es el administrador del SGBD el encargado de asignar o no los privilegios 2) a los usuarios sobre determinados objetos (tablas, procedimientos, . . .).
Supongamos que somos los administradores de un SGBD MySQL y tenemos que proporcionar acceso a una Base de Datos para una aplicación biblioteca a un desarrollador de mi compañía:
-- Si no hemos creado la base de datos, podemos hacerlo ahora CREATE DATABASE biblioteca; -- Crea el usuario asignándole contraseña CREATE USER 'desarrollador' IDENTIFIED BY 'micontraseña'; -- Asigna todos los privilegios al usuario sobre la base de datos GRANT ALL PRIVILEGES ON biblioteca.* TO desarrollador;
Así, hemos creado la Base de Datos y el usuario, y hemos concedido todos los privilegios a dicho usuario sobre esa Base de Datos.
La forma más habitual de trabajo a la hora de lanzar órdenes en SQL sobre un SGBD relacional como MySQL es crear ficheros por lotes de órdenes SQL, lo que se conoce como scripts SQL, donde podemos escribir todas las sentencias SQL que queremos ejecutar una detrás de otra separadas por el carácter ;
.
Existe la posibilidad de añadir comentarios al código según la siguiente sintaxis:
-- Esto es un comentario y MySQL no lo ejecuta /* Esto también es un comentario y tampoco se ejecuta */
Por ejemplo, para la creación de una nueva Base de Datos y sus tablas podríamos preparar un script SQL como el siguiente:
CREATE DATABASE IF NOT EXISTS pagina_web; USE pagina_web; CREATE TABLE IF NOT EXISTS usuarios ( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, . . . . . . ); CREATE TABLE IF NOT EXISTS productos ( . . . . . . ); . . . . . .
Una vez creado el script podremos lanzar su ejecución sobre MySQL y se ejecutarán todas las sentencias contenidas en él de forma secuencial. Es una forma muy útil de crear scripts para la creación de una Base de Datos y todas sus tablas y restricciones y también para crear scripts de actualización o parcheo de una Base de Datos existentes de forma que se incluyan todas las sentencias SQL que actualicen o arreglen los problemas que actualmente pueda haber (añadir una nueva tabla, eliminar un campo, añadir una nueva restricción, . . .).
Para estos casos a veces resulta útil desactivar las claves ajenas, realizar algunas operaciones sobre tablas que puedan tener relaciones con otras y volver a activarlas. De esa manera es posible realizar ciertas operaciones sin que las reglas de validación de la integridad referencial lancen ningún error.
-- Desactivar claves ajenas SET FOREIGN_KEY_CHECKS = 0; . . . // Realizar algunos cambios en la estructura y datos de la Base de Datos . . . -- Activar claves ajenas SET FOREIGN_KEY_CHECKS = 1;
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT
)id_usuario
si es una clave ajena de una tabla usuarios. Si en una tabla hay dos claves ajenas que apuntan a la misma tabla, añadiremos algo al nombre para distinguirla (id_usuario_emisor
e id_usuario_receptor
, por ejemplo)users
mejor que user
, orders
mejor que order
)© 2016-2020 Santiago Faci