Mysql AulaMentor PDF

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 222

Lenguaje SQL con MySQL Parte I - Lenguaje Sql.

Gestión de datos

PARTE I
LENGUAJE SQL. GESTION DE DATOS

Tema 1. EL LENGUAJE DE GESTIÓN DE BASES DE DATOS ............................................... 3


1 – Bases de datos ............................................................................................................... 3
1.1 - Lenguaje de gestión de bases de datos..................................................................................................... 3
1.2 - ¿Qué es una Base de Datos?........................................................................................................................ 3
1.3 - ¿Qué es un Sistema de Gestión de Bases de Datos?............................................................................ 4
2 – Modelos de datos y bases de datos relacionales........................................................... 6
2.1 – Tipos de bases de datos ................................................................................................................................ 6
2.2 - El Modelo de Datos Relacional. Componentes........................................................................................ 6
2.3 – Bases de datos relacionales......................................................................................................................... 7
3 – Lenguaje SQL ................................................................................................................12
3.1 - ¿Qué podemos hacer con SQL? ................................................................................................................12
3.2 - Tipos de sentencias SQL..............................................................................................................................12
3.3 - Sentencias SQL...............................................................................................................................................13
TEMA 2. ELEMENTOS DEL LENGUAJE...............................................................................15
1 - Introducción. ..................................................................................................................15
2 – Elementos de SQL .........................................................................................................15
2.1 – Identificadores................................................................................................................................................15
2.2 – Palabras reservadas.....................................................................................................................................15
3 - Datos ..............................................................................................................................16
3.1 – Datos constantes o literales......................................................................................................................16
3.2 – Datos variables...............................................................................................................................................16
4 - Operadores.....................................................................................................................19
4.1 - Operadores aritméticos ................................................................................................................................19
4.2- Operadores de comparación........................................................................................................................19
4.3 - Operadores lógicos ........................................................................................................................................20
4.4 – Precedencia o prioridad en los operadores...........................................................................................23
5 - Funciones predefinidas..................................................................................................25
5.1 - Funciones numéricas o aritméticas..........................................................................................................25
5.2 - Funciones de caracteres..............................................................................................................................26
5.3 - Funciones de fecha ........................................................................................................................................27
5.4 - Funciones de comparación .........................................................................................................................29
5. 5 - Otras funciones..............................................................................................................................................30
6 – Valores Nulos ( NULL ) ..................................................................................................31
7 – Expresiones y condiciones............................................................................................33
Tema 3. CREACIÓN DE TABLAS .........................................................................................34
1 - Consideraciones previas a la creación de una tabla ......................................................34
1.1 – Definición de la tabla ....................................................................................................................................34
1.2 - Restricciones en las tablas..........................................................................................................................34
2 - Formato genérico para la creación de tablas. .................................................................36
2.1 - Formato básico para la creación de tablas .............................................................................................36

Página: 1
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

2.2 – Ejemplos básicos de creación de tablas.................................................................................................36


2.3 – Formatos para la creación de tablas con la definición de restricciones........................................37
2.4 - Integridad referencial.....................................................................................................................................42
2.5 - Formato completo de la creación de tablas............................................................................................43
3 - Modificación de la definición de una tabla. ....................................................................45
3.1 - Formato general para la modificación de tablas....................................................................................45
3.2 – Ejemplos de modificaciones de tablas....................................................................................................46
4 - Eliminación de una tabla. ...............................................................................................48
4.1 - Formato para eliminar una tabla. ...............................................................................................................48
4.2 – Ejemplos de borrado de una tabla ............................................................................................................48
5 – Renombrado de una tabla..............................................................................................49
5.1 - Formato para renombrar una tabla ............................................................................................................49
5.2 – Ejemplos de renombrado de una tabla ....................................................................................................49
Tema 4. ACTUALIZACION DE TABLAS ...............................................................................50
1 - Introducción ...................................................................................................................50
2 - Inserción de nuevas filas en la base de datos................................................................50
2.1 – Formato de la inserción una fila ................................................................................................................50
2.2 – Ejemplos de inserción de filas...................................................................................................................51
3 - Modificación de filas. ......................................................................................................56
3.1 – Formato de la modificación de filas .........................................................................................................56
3.2 – Ejemplos de modificación de filas ............................................................................................................56
4 - Eliminación de filas. .......................................................................................................58
4.1 – Formato de la eliminación de filas ............................................................................................................58
4.2 – Ejemplos de la eliminación de filas ..........................................................................................................58
5 - Restricciones de integridad y actualizaciones. ..............................................................60
5.1 - Control de las restricciones de integridad referencial.........................................................................60
5.2 - Ejemplos de borrados y modificaciones en cascada...........................................................................61
6 - Control de transacciones: COMMIT y ROLLBACK. ........................................................64

Página: 2
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

TEMA 1. EL LENGUAJE DE GESTIÓN DE BASES DE


DATOS

Paulina Barthelemy

1 – Bases de datos

1.1 - Lenguaje de gestión de bases de datos.


SQL son las siglas de Structured Query Language que significa lenguaje estructurado de
consulta

Se trata de un lenguaje definido por el estándar ISO/ANSI_SQL que utilizan para la gestión de las
bases de datos los principales fabricantes de Sistemas de Gestión de Bases de Datos Relacionales.

Es un lenguaje estándar no procedimental que se utiliza para definir, gestionar y manipular la


información contenida en una Base de Datos Relacional.

En los lenguajes procedimentales se deben especificar todos los pasos que hay que dar para
conseguir el resultado. Sin embargo, como ya hemos dicho, SQL es un lenguaje no procedimental en
el que tan solo deberemos indicar al sistema qué es lo que queremos obtener, y el sistema decidirá
cómo obtenerlo.

Es un lenguaje sencillo y potente que se emplea para la gestión de la base de datos a distintos
niveles de utilización: usuarios, programadores y administradores de la base de datos.

1.2 - ¿Qué es una Base de Datos?


Una base de datos está constituida por un conjunto de información relevante para una empresa o
entidad, junto con los procedimientos para almacenar, controlar, gestionar y administrar esa
información.

Además, la información contenida en una base de datos cumple una serie de requisitos o
características:

• Los datos están interrelacionados, sin redundancias innecesarias.


• Los datos son independientes de los programas que los usan.
• Se emplean métodos determinados para recuperar los datos almacenados o para incluir
datos nuevos y borrar o modificar los existentes

Una base de datos estará organizada de forma que se cumplan los requisitos para que la información
se almacene con las mínimas redundancias, con capacidad de acceso para diferentes usuarios pero
con un control de seguridad y privacidad. Debe tener mecanismos que permitan recuperar la
información en caso de pérdida y la capacidad de adaptarse fácilmente a nuevas necesidades de

Página: 3
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

almacenamiento.

1.3 - ¿Qué es un Sistema de Gestión de Bases de Datos?


Un Sistema de Gestión de Bases de Datos (SGBD) es una aplicación formada por un conjunto de
programas que permite construir y gestionar bases de datos. Proporciona al usuario de la base de
datos las herramientas necesarias para realizar, al menos, las siguientes tareas:
• Definir las estructuras de los datos.
• Manipular los datos. Es decir, insertar nuevos datos, así como modificar, borrar y consultar los
datos existentes.
• Mantener la integridad de la información.
• Proporcionar control de la privacidad y seguridad de los datos en la Base de Datos,
permitiendo sólo el acceso a los mismos a los usuarios autorizados.

Para realizar las funciones que acabamos de describir, el Sistema Gestor de Bases de Datos
necesita un conjunto de programas que gestionen el almacenamiento y la recuperación de dichos
datos y un personal informático que maneje dichos programas.

Los componentes principales de un SGBD son:


• GESTOR DE LA BASE DE DATOS
Es un conjunto de programas transparentes al usuario que se encargan de gestionar la
seguridad de los datos y el acceso a ellos. Interacciona con el sistema operativo
proporcionando una interfaz entre el usuario y los datos. Cualquier operación que se
realice ha de estar procesada por este gestor.

• DICCIONARIO DE LA BASE DE DATOS


Es donde se almacena toda la descripción de los diferentes objetos de la base de datos.
Esta información se almacena con la misma estructura que los datos de los usuarios. El
almacenamiento de esta información lo realiza el sistema gestor y cualquier usuario
puede acceder a su contenido con el mismo lenguaje que al resto de los datos
almacenados (SQL)

• LENGUAJES
El sistema gestor ha de proporcionar lenguajes que permitan definir la estructura de los
datos, almacenar la información y recuperarla. Podrán utilizar estos lenguajes los
usuarios y lo administradores de la base de datos.
Estos lenguajes son:
• Lenguaje de definición de datos (DDL)
Para definir la estructura con la que almacenaremos los datos.
• Lenguaje de manipulación de datos (DML)
Para añadir, modificar o eliminar datos, así como recuperar la información
almacenada.
• Lenguaje de control de datos (DCL)
Para controlar el acceso a la información y la seguridad de los datos.
Permiten limitar y controlar los accesos a la información almacenada. De
esta tarea se ocupa el administrador de la base de datos.

• ADMINISTRADOR DE LA BASE DE DATOS


Es una persona o grupo de personas responsables de la seguridad y la eficiencia de
todos los componentes del sistema de bases de datos. Deben conocer el sistema tanto a
nivel físico como lógico y a todos los usuarios que interaccionan con él.

Página: 4
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

• USUARIOS DE LA BASE DE DATOS


Tradicionalmente considerados como un componente más de los sistemas gestores de
bases de datos, debido a que estos fueron los primeros en considerarlos una parte
importante para el correcto funcionamiento del sistema. Pueden ser usuarios terminales
(usuarios no especializados que interaccionan con la base de datos), usuarios técnicos
(usuarios que desarrollan programas de aplicación para ser utilizados por otros) y
usuarios especializados (usuarios que utilizan el sistema gestor de la base de datos como
una herramienta de desarrollo dentro de otros sistemas más complejos).

Algunos de los productos comerciales más difundidos son:


• ORACLE de Oracle Corporation.
• DB2 de I.B.M. Corporation
• Informix de Informix Software Inc.
• SQL Server de Microsoft Corporation.
• MySQL producto Open Source (código abierto)

Página: 5
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

2 – Modelos de datos y bases de datos relacionales


Un modelo de datos es una filosofía de trabajo que permite realizar una abstracción de la realidad
y representarla en el mundo de los datos.

2.1 – Tipos de bases de datos


Existen, tradicionalmente, varios tipos de bases de datos:
Bases de Datos Jerárquicas
Bases de Datos en Red
Bases de Datos Relacionales
Bases de Datos Objeto-Relacionales

Estas dos últimas son, con diferencia, las más difundidas y utilizadas en la actualidad debido a su
potencia, versatilidad y facilidad de utilización. Se basan en el Modelo Relacional cuyas principales
características veremos a continuación. Para gestionarlas se utiliza el lenguaje SQL.

2.2 - El Modelo de Datos Relacional. Componentes.


Un modelo de datos es un conjunto de reglas y convenciones que nos permiten describir, con los
elementos del modelo, los datos y las relaciones entre ellos.

Analizaremos el modelo de datos relacional, en él se basan las bases de datos relacionales.


Sus principales componentes son:

Entidad.
Es un objeto acerca del cual se recoge información relevante.
Ejemplo de entidades: EMPLEADO, CLIENTE, PRODUCTO.

Atributo
Es una propiedad o característica de la entidad.
Por ejemplo pueden ser atributos de la entidad PERSONA los siguientes: DNI, NOMBRE,
EDAD, etc.

Relación o Inter-Relación
Representa la relación que puede haber entre dos entidades.

Por ejemplo, una relación compra representa la relación entre las entidades CLIENTE y
PRODUCTO

CLIENTE -> compra -> PRODUCTO.................................. “Un cliente compra un producto”

Y también, una relación pertenece a representa la relación entre las entidades EMPLEADO Y
DEPARTAMENTO

EMPLEADO -> pertenece a -> DEPARTAMENTO.....“Un empleado pertenece a un


departamento”

Con este modelo podemos representar, utilizando los componentes anteriores, la información que
deseamos almacenar en la base de datos. Posteriormente este modelo se va a convertir en una base
de datos relacional.

Página: 6
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

2.3 – Bases de datos relacionales


La definición de Bases de Datos Relacionales fue enunciada por E.F. Codd. En 1972
estableciendo las reglas que debía cumplir cualquier base de datos para ser una base de
datos relacional. Son 12 reglas, llamadas reglas de Codd, más una teoría matemática,
llamada cálculo y álgebra relacional, que marcan las características de los sistemas
relacionales.

Es un modelo basado en la teoría de las relaciones, álgebra y calculo relacional, con las
siguientes características:

Ø Hay una parte de definición de datos, llamada estática, que nos da la estructura del
modelo, donde los datos se encuentran almacenados en forma de relaciones, llamadas
generalmente tablas, ya que su estructura es muy similar a las tablas convencionales.
Estas tablas son independientes de la forma física de almacenamiento. A estos datos se
añaden unas restricciones que son unas reglas que limitan los valores que podemos
almacenar en las tablas de la base de datos y nos permiten implementar las relaciones
entre las tablas.
Ø A esta parte se añade otra, llamada dinámica, con las operaciones que se pueden
realizar sobre las tablas, anteriormente definidas, para gestionar los datos almacenados

El modelo de datos relacional que acabamos de exponer se almacena en una base de datos
relacional. Al realizar la conversión de un modelo relacional a una base de datos relacional las
entidades y las relaciones del modelo se transforman en tablas y restricciones de la base de
datos. Estas tablas junto con las restricciones forman la clave de las bases de datos relacionales.

2.3.1 - Tablas
Son los objetos de la Base de Datos donde se almacenan los datos. Tienen la forma de una tabla
tradicional, de ahí su nombre. Normalmente una tabla representa una entidad aunque también puede
representar una asociación de entidades. Cada fila representa una ocurrencia de la entidad y cada
columna representa un atributo o característica de la entidad.
Las tablas tienen un nombre que las identifica y están formadas por atributos representados en las
columnas, y por tuplas representadas en las filas.

Ejemplos de atributos: para la tabla departamentos las columnas con el número de departamento,
el nombre del departamento y la localidad donde se encuentra.
La tabla empleados puede tener como columnas o atributos: numero de empleado, nombre, fecha
de alta, salario,...

Ejemplos de tuplas son: los datos de un empleado si es una tabla de empleados, de un


departamento si es una tabla de departamentos, de un cliente si se trata de una tabla de
clientes, o de un producto si es una tabla de productos.

Página: 7
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

Ejemplos de tablas:
Tabla DEPARTAMENTOS:

Columna 1 Columna 2 Columna 3

DEP_NO DNOMBRE LOCALIDAD


Fila 1 -> 10 CONTABILIDAD BARCELONA
Fila 2 -> 20 INVESTIGACION VALENCIA
Fila 3 -> 30 VENTAS MADRID
Fila 4 -> 40 PRODUCCION SEVILLA

Tabla de EMPLEADOS:

EMP_NO APELLIDO OFICIO DIRECTOR FECHA_AlTA SALARIO COMISION DEP_NO

7499 ALONSO VENDEDOR 7698 20/02/81 1400.00 400.00 30

7521 LOPEZ EMPLEADO 7782 08/05/81 1350.00 NUL0 10

7654 MARTIN VENDEDOR 7698 28/09/81 1500.00 1600.00 30

7698 GARRIDO DIRECTOR 7839 01/05/81 3850.00 NULO 30

7782 MARTINEZ DIRECTOR 7839 09/06/81 2450.00 NUL0 10

7839 REY PRESIDENTE NULO 17/11/81 6000.00 NULO 10

7844 CALVO VENDEDOR 7698 08/09/81 1800.00 0.00 30

7876 GIL ANALISTA 7782 06/05/82 3350.00 NULO 20

7900 JIMENEZ EMPLEADO 7782 24/03/82 1400.00 NULO 20

2.3.2 - Tablas del curso


A lo largo de este curso utilizaremos, además de las tablas EMPLEADOS y DEPARTAMENTOS cuya
forma y contenido ya hemos visto, las tablas de CLIENTES, PRODUCTOS y PEDIDOS cuya forma y
contenido es el siguiente:
TABLA DE CLIENTES

mysql> SELECT *
-> FROM clientes;
+----------+------------------------+-----------+-----------+-----+------+---------------+
|CLIENTE_NO| NOMBRE | LOCALIDAD |VENDEDOR_NO|DEBE | HABER| LIMITE_CREDITO|
+----------+------------------------+-----------+-----------+-----+------+---------------+
| 101 | DISTRIBUCIONES GOMEZ | MADRID | 7499 |0.00 | 0.00| 5000.00 |
| 102 | LOGITRONICA S.L | BARCELONA | 7654 |0.00 | 0.00| 5000.00 |
| 103 | INDUSTRIAS LACTEAS S.A.| LAS ROZAS | 7844 |0.00 | 0.00| 10000.00 |

Página: 8
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

| 104 | TALLERES ESTESO S.A. | SEVILLA | 7654 |0.00 | 0.00| 5000.00 |


| 105 | EDICIONES SANZ | BARCELONA | 7499 |0.00 | 0.00| 5000.00 |
| 106 | SIGNOLOGIC S.A. | MADRID | 7654 |0.00 | 0.00| 5000.00 |
| 107 | MARTIN Y ASOCIADOS S.L.| ARAVACA | 7844 |0.00 | 0.00| 10000.00 |
| 108 | MANUFACTURAS ALI S.A. | SEVILLA | 7654 |0.00 | 0.00| 5000.00 |
+----------+------------------------+-----------+-----------+-----+------+----------------
8 rows in set (0.00 sec)

TABLA PRODUCTOS

mysql> SELECT *
-> FROM productos;
+-------------+-----------------------------+---------------+------------------+
| PRODUCTO_NO | DESCRIPCION | PRECIO_ACTUAL | STOCK_DISPONIBLE |
+-------------+-----------------------------+---------------+------------------+
| 10 | MESA DESPACHO MOD. GAVIOTA | 550.00 | 50 |
| 20 | SILLA DIRECTOR MOD. BUFALO | 670.00 | 25 |
| 30 | ARMARIO NOGAL DOS PUERTAS | 460.00 | 20 |
| 40 | MESA MODELO UNIÓN | 340.00 | 15 |
| 50 | ARCHIVADOR CEREZO | 1050.00 | 20 |
| 60 | CAJA SEGURIDAD MOD B222 | 252.00 | 15 |
| 70 | DESTRUCTORA DE PAPEL A3 | 450.00 | 25 |
| 80 | MODULO ORDENADOR MOD. ERGOS | 495.00 | 25 |
+-------------+-----------------------------+---------------+------------------+
8 rows in set (0.03 sec)

TABLA PEDIDOS

mysql> SELECT *
-> FROM pedidos;
+-----------+-------------+------------+----------+--------------+
| PEDIDO_NO | PRODUCTO_NO | CLIENTE_NO | UNIDADES | FECHA_PEDIDO |
+-----------+-------------+------------+----------+--------------+
| 1000 | 20 | 103 | 3 | 1999-10-06 |
| 1001 | 50 | 106 | 2 | 1999-10-06 |
| 1002 | 10 | 101 | 4 | 1999-10-07 |
| 1003 | 20 | 105 | 4 | 1999-10-16 |
| 1004 | 40 | 106 | 8 | 1999-10-20 |
| 1005 | 30 | 105 | 2 | 1999-10-20 |
| 1006 | 70 | 103 | 3 | 1999-11-03 |
| 1007 | 50 | 101 | 2 | 1999-11-06 |
| 1008 | 10 | 106 | 6 | 1999-11-16 |
| 1009 | 20 | 105 | 2 | 1999-11-26 |
| 1010 | 40 | 102 | 3 | 1999-12-08 |
| 1011 | 30 | 106 | 2 | 1999-12-15 |
| 1012 | 10 | 105 | 3 | 1999-12-06 |
| 1013 | 30 | 106 | 2 | 1999-12-06 |
| 1014 | 20 | 101 | 4 | 2000-01-07 |
| 1015 | 70 | 105 | 4 | 2000-01-16 |
+-----------+-------------+------------+----------+--------------+
16 rows in set (0.02 sec)

Página: 9
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

2.3.3 – Restricciones
Son una parte importante para la implementación del modelo relacional. Restringen los valores
que pueden tomar los datos en cada una de las columnas.

Estas restricciones son:


• Clave primaria (PRIMARY KEY)
Una de las características del modelo relacional es que cada fila debe ser única. Ello
obliga a la existencia de un identificativo que permita y controle esta unicidad. Este
identificativo es la clave primaria. Estará formada por una columna o grupo de columnas y
se elegirá de tal forma que su valor en cada fila sea único.
En una base de datos relacional es obligatoria su existencia en cada una de las tablas.

• Clave Ajena (FOREIGN KEY)


Será la forma de implementar las relaciones entre las tablas. Una columna o grupo de
columnas que sea clave ajena referenciará a la tabla con la que está relacionada. Los
valores que podrá tomar la clave ajena serán valores que ya existan en la tabla
relacionada, o en su defecto un valor nulo.
La importancia de su definición radica en que será la encargada de implementar las
relaciones entre las tablas, para ajustarnos al Modelo Relacional
Por ejemplo la tabla EMPLEADOS está relacionada con la tabla DEPARTAMENTOS a
través de la columna DEP_NO (numero de departamento) que se encuentra en ambas
tablas. Esta columna es clave primaria de la tabla DEPARTAMENTOS y en la tabla
EMPLEADOS es la clave ajena. Esto quiere decir que los valores que tome el campo
DEP_NO en la tabla EMPLEADOS solo pueden ser valores que ya existan en el campo
DEP_NO de la tabla DEPARTAMENTOS.

• Unicidad (UNIQUE)
Es una restricción que obliga a que una columna o conjunto de columnas tenga un valor
único o un valor nulo. También admite valores nulos.

• Restricción de valores permitidos (CHECK)


Es una restricción que nos permitirá controlar el conjunto de valores que serán válidos en
una columna. Solo serán validos los valores que cumplan la condición especificada.
Nota: MySQL lo acepta dentro del formato pero no lo implementa en la versión actual.

• Obligación de valor (NOT NULL)


Una de las características de las bases de datos relacionales es que se permite la
ausencia de valor en los datos. Esta ausencia puede ser debida a que en el momento de
introducir los datos se desconoce el valor de un atributo para esa fila o a que ese atributo
es inaplicable para esa fila. El valor que se le asigna a ese atributo en esa fila se llama
valor nulo (NULL). Esta restricción obliga a que una columna tenga que tener siempre
valor no permitiéndose que tome el valor nulo.
En el siguiente capítulo hablaremos de forma más extensa de estos valores nulos.

2.3.4 - Restricciones en las tablas del curso

Para implementar el modelo relacional con las restricciones propias (cada fila debe ser única) y las
restricciones de nuestro modelo necesitamos, al menos, las siguientes restricciones en las tablas:

Página: 10
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

TABLA DEPARTAMENTOS
dep_no CLAVE PRIMARIA

TABLA EMPLEADOS
emp_no CLAVE PRIMARIA
dep_no CLAVE AJENA QUE REFERENCIA A dep_no DE DEPARTAMENTOS
dir CLAVE AJENA QUE REFERENCIA A emp_no DE EMPLEADOS

La tabla EMPLEADOS está relacionada con la tabla DEPARTAMENTOS a través de la columna


DEP_NO (numero de departamento) que se encuentra en ambas tablas. De esta forma
podemos saber, por ejemplo que el empleado GIL pertenece al departamento 20. Y si vamos
a la tabla departamentos comprobaremos que el departamento 20 es INVESTIGACION y se
encuentra en VALENCIA. Por tanto, el empleado GIL pertenece al departamento de
INVESTIGACION que está en VALENCIA.
La tabla EMPLEADOS también se relaciona consigo misma mediante las columnas EMP_NO y
DIRECTOR. Cada empleado tiene un número de empleado (EMP_NO) y suele tener también
un DIRECTOR. Esta última columna contiene un número de empleado que, suponemos, es el
director del empleado en cuestión. Así podemos saber que REY es el director de GARRIDO y
de MARTINEZ; y que el director de JIMENEZ es MARTINEZ, etcétera. El director de un
empleado debe ser a su vez empleado de la empresa, de ahí la existencia de esta clave
ajena. La columna DIRECTOR deberá contener un valor que se corresponda con un valor de
EMP_NO o tener el valor nulo.

TABLA CLIENTES
cliente_no CLAVE PRIMARIA
vendedor_no CLAVE AJENA QUE REFERENCIA emp_no DE EMPLEADOS

La tabla CLIENTES se relaciona con EMPLEADOS por medio de la columna VENDEDOR_NO


de la primera que hace referencia a la columna EMPLEADO_NO de la segunda. Así cada
cliente tendrá asignado un vendedor, que será un empleado de la empresa existente en la
tabla EMPLEADOS.

TABLA PRODUCTOS
producto_no CLAVE PRIMARIA

TABLA PEDIDOS
pedido_no CLAVE PRIMARIA
producto_no CLAVE AJENA QUE REFERENCIA A producto_no DE PRODUCTOS
cliente_no CLAVE AJENA QUE REFERENCIA A cliemte_no DE CLIENTES

La tabla PEDIDOS se relaciona con PRODUCTOS mediante la columna PRODUCTO_NO y con


CLIENTES mediante la columna CLIENTE_NO. De esta forma sabemos que el pedido
número 1000 lo ha realizado el cliente INDUSTRIAS LACTEAS S.A. y que el producto
solicitado es SILLA DIRECTOR MOD. BUFALO a un precio de 670.00, etcétera.

El SGBD velará porque todas las operaciones que se realicen respeten estas restricciones
manteniendo así la integridad de la información (integridad referencial)

El resto de las restricciones las estudiaremos en el tema 3 de creación de tablas.

Página: 11
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

3 – Lenguaje SQL
Como ya hemos dicho al inicio del tema, SQL significa lenguaje estructurado de consulta (Structured
Query Language).
Es un lenguaje desarrollado sobre un prototipo de gestor de bases de datos relacionales con su
primera implementación en el año 1979.
Posteriormente, en 1986, fue adoptado como estándar por el instituto ANSI (American National
Standard Institute) como estándar y en 1987 lo adopta ISO (Internacional Standardization
Organization). Aparece así el ISO/ANSI SQL que utilizan los principales fabricantes de Sistemas de
Gestión de Bases de Datos Relacionales.
El lenguaje SQL es un lenguaje relacional que opera sobre relaciones (tablas) y da como resultado
otra relación.

3.1 - ¿Qué podemos hacer con SQL?


Todos los principales SGBDR incorporan un motor SQL en el Servidor de Base Datos, así como
herramientas de cliente que permiten enviar comandos SQL para que sean procesadas por el motor
del servidor. De esta forma, todas las tareas de gestión de la Base de Datos (BD) pueden realizarse
utilizando sentencias SQL.
Lo que podemos hacer con este lenguaje SQL es:
Ø Consultar datos de la Base de Datos.
Ø Insertar, modificar y borrar datos.
Ø Crear, modificar y borrar objetos de la Base de Datos.
Ø Controlar el acceso a la información.
Ø Garantizar la consistencia de los datos.

Actualmente se ha impuesto el almacenamiento de la información en bases de datos. El SQL es, por


tanto, un lenguaje muy extendido y muchos lenguajes de programación incorporan sentencias SQL
como parte de su repertorio o permiten la comunicación con los motores de SQL.

3.2 - Tipos de sentencias SQL.


Entre los trabajos que se pueden realizar en una base de datos podemos distinguir tres tipos:
definición, manipulación y control de datos. Por ello se distinguen tres tipos de sentencias SQL:

• Sentencias de definición de datos. ( Lenguaje de Definición de Datos DDL)


Se utilizan para:
Crear objetos de base de datos ----------------------------- SENTENCIA CREATE
Eliminar objetos de base de datos -------------------------- SENTENCIA DROP
Modificar objetos de base de datos ------------------------ SENTENCIA ALTER

• Sentencias de manipulación de datos. (Lenguaje de Manipulación de Datos DML)


Se utilizan para:
Recuperar información ---------------------------------------- SENTENCIA SELECT
Actualizar la información:
Añadir filas -------------------------------------- SENTENCIA INSERT
Eliminar filas ------------------------------------- SENTENCIA DELETE
Modificar filas ----------------------------------- SENTENCIA UPDATE

• Sentencias de control de datos. (Lenguaje de Control de datos DCL)

Página: 12
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

Se utilizan para:
Crear privilegios de acceso a los datos -------------------- SENTENCIA GRANT
Quitar privilegios de acceso a los datos ------------------- SENTENCIA REVOKE

3.3 - Sentencias SQL


Realizaremos algunas consideraciones sobre las notaciones y formatos utilizados.

a) Formatos de las instrucciones


Estos formatos están recuadrados. Se escriben utilizando una notación que recordamos a
continuación:

• Las palabras reservadas de SQL aparecen en mayúsculas.

• Los nombres de objetos (tablas, columnas, etcétera) aparecen en el formato TipoTítulo (las
iniciales de las palabras en mayúsculas)

• Las llaves { } indican la elección obligatoria entre varios elementos.

• La barra vertical | separa los elementos en una elección.

• Los corchetes [ ] encierran un elemento opcional.

• El punto y coma ; que aparece al final de cada comando es el separador de instrucciones y en


realidad no forma parte de la sintaxis del lenguaje SQL, pero suele ser un elemento requerido por las
herramientas de cliente para determinar el final del comando SQL y enviar la orden (sin él ;) al servidor.

Los formatos de las instrucciones, cuando sean complejos, se irán viendo por partes. Cada vez
que añadamos algo nuevo lo remarcaremos en negrita.

b) Consulta de los datos.


Realizar una consulta en SQL consiste en recuperar u obtener aquellos datos que, almacenados en
filas y columnas de una o varias tablas de una base de datos, cumplen unas determinadas
especificaciones. Para realizar cualquier consulta se utiliza la sentencia SELECT.

Aunque la sentencia de consulta de datos en las tablas, SELECT, se tratará con profundidad en los
temas del 5 al 9, necesitaremos hacer alguna pequeña consulta para poder verificar los datos que
tenemos en las tablas. Las primeras consultas van a ser escritas con un formato inicial de la sentencia
SELECT, que se completará en el bloque siguiente.

SELECT { * | [NombreColumna [, NombreColumna]....] }


FROM NombreTabla
[ WHERE Condicion ] ;

Notación: hay que escoger obligatoriamente una de las opciones, entre indicar los nombres de
las columnas y el asterisco * (por eso aparecen las posibles opciones entre llaves y separadas
por una barra). En caso de escoger la segunda opción se pueden indicar una o varias
columnas (por eso aparece entre corchetes y seguido de puntos suspensivos). La cláusula
WHERE es opcional (por eso aparece entre corchetes).

Página: 13
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

El funcionamiento de esta sentencia es el siguiente: visualizará las correspondientes filas de la


tabla. Si hemos escrito los nombres de las columnas separados por comas visualizará solo los
valores de esas columnas y si hemos escrito el signo * visualizará todas las columnas. Si
además, hemos escrito una condición con la cláusula WHERE visualizará solo las filas que
cumplan esa condición.

c) Notación de los ejemplos


Otras directrices importantes de notación. Vamos a escribir cada cláusula de la instrucción en una
línea, como los espacios en blanco y saltos de línea dentro de la instrucción son ignorados, hasta
que encuentra el ; que es el fin de la instrucción. Ello facilita enormemente la lectura de las
instrucciones de selección.

Vamos a ver un ejemplo aunque todavía no conozcamos el significado.

Supongamos que escribimos:

select apellido,(salario+ifnull(comisio,0)) “salario total”,


dept_no from empleados where oficio = ’analista’ order by dept_no;

O bien que escribimos:

SELECT apellido, salario+IFNULL(comision,0) “Salario total”, dept_no


FROM empleados
WHERE oficio = ’ANALISTA’
ORDER BY dept_no;

Este segundo formato es más claro y visual. Cada cláusula, comenzando con una palabra
reservada, aparece en una línea y se han introducido algunos espacios en blancos y saltos de línea
para separar.
Utilizaremos este formato en todos los ejemplos y ejercicios.

Página: 14
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

TEMA 2. ELEMENTOS DEL LENGUAJE

Paulina Barthelemy

1 - Introducción.
Antes de abordar esta unidad hay que tener en cuenta:

1º Se trata de una guía para que sirva de referencia o de consulta cuando se necesite a lo largo del
curso. Posteriormente haremos ejemplos utilizando los elementos estudiados en este tema. Permitirá
irse familiarizando con el vocabulario y la sintaxis de las sentencias que se explicarán posteriormente.

2º En esta unidad se abordan cuestiones que, aunque están definidas por el estándar ANSI/ISO
SQL, no están asumidas al 100% por todos los fabricantes. Por tanto, pueden existir ligeras
diferencias de algunos productos con algunas de las especificaciones que aquí se exponen.
Se ha escogido el gestor de bases de datos MySQL para realizar los ejemplos y los ejercicios. Aunque
como este es un curso de SQL, no se profundizará en las particularidades de este SGBD hasta los
temas de Administración (temas 10, 11 y 12 del curso) que si son específicos de MySQL.

2 – Elementos de SQL

2.1 – Identificadores
Es la forma de dar nombres a los objetos de la base de datos y a la propia base de datos. Un
objeto tendrá un nombre (NombreObjeto) que lo identifique de forma única dentro de su base de
datos.

El estándar define que pueden tener hasta 18 caracteres empezando con un carácter alfabético y
continuando con caracteres numéricos y/o alfabéticos.

En la práctica este estándar se ha ampliado y MySQL permite nombres de identificadores de hasta 64


caracteres sin espacios en blanco. Para los nombres de las bases de datos y de las tablas no están
permitidos ‘/’, ‘\’ ni ‘.’

2.2 – Palabras reservadas


Al igual que en el resto de los lenguajes de programación, existen palabras que tiene un
significado especial para el gestor de la base de datos y no pueden ser utilizadas como
identificadores.
Serán todas las palabras que irán apareciendo en los formatos de las instrucciones, más algunas
que se verán en este curso.
Puede encontrarse una lista completa en el manual de MySQL en la dirección:
http://dev.mysql.com en el apartado Reserved_words.html

Página: 15
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

3 - Datos

3.1 – Datos constantes o literales


En SQL podemos utilizar los siguientes tipos de constantes:

Constantes numéricas.
Construidas mediante una cadena de dígitos que puede llevar un punto decimal, y que pueden ir
precedidos por un signo + ó -. (Ej. : -2454.67)
También se pueden expresar constantes numéricas empleado el formato de coma flotante, notación
científica. (Ej. : 34.345E-8).

Constantes de cadena.
Consisten en una cadena de caracteres encerrada entre comillas simples. (Ej.: 'Hola Mundo')

Constantes de fecha.
En realidad las constantes de fecha, en MySQL y otros productos que soportan este tipo, se escriben
como constantes de cadena sobre las cuales se aplicarán las correspondientes funciones de conversión.
Existe una gran cantidad de formatos aplicables a estas constantes (americano, europeo, japonés,
etcétera). La mayoría de los productos pueden trabajar también con FECHA Y HORA en distintos
formatos.

3.2 – Datos variables


Las columnas de la base de datos almacenan valores que tendrán diferentes valores en cada fila.
Estos datos se definen indicando su nombre (NombreColumna) y el tipo de datos que almacenarán.
La forma de almacenarlos no es la misma para todos, por lo tanto una parte importante de la
definición de un dato es la especificación de su tipo. Al indicar el tipo de datos se suele indicar también
el tamaño.

La cantidad de tipos de datos posibles es muy extensa, quedando la enumeración completa fuera de
los objetivos de este curso. A continuación se indican algunos de los tipos de datos más utilizados
suficientes para este curso (para mayor detalle consultar el manual).

a) Datos numéricos

INT[(num)] o INTEGER [(num)]


Se utiliza para guardar datos numéricos enteros, siendo num el número de dígitos

FLOAT(escala, precision)
Se utiliza para guardar datos numéricos en coma flotante. La escala indica el número total
de dígitos. La precisión el número de posiciones decimales

NUMERIC(escala, precisión)
Se utiliza para guardar datos numéricos. La escala indica el número total de dígitos. La
precisión el número de posiciones decimales, y si no se especifica se supone 0
(correspondería a un número entero)

Página: 16
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

b) Datos alfanuméricos o cadenas de caracteres

CHAR (long)
Se utiliza para guardar cadenas de caracteres de longitud fija especificada entre paréntesis. La
longitud, long, puede ser un número entre 0 y 255 (ver nota)

VARCHAR (long)
Se utiliza igualmente para almacena cadenas de caracteres de longitud variable cuyo límite
máximo es el valor especificado como long (ver nota)
La longitud puede ser un número entre 0 y 255

TEXT
Un texto de longitud máxima 65.535 caracteres. (2 ^ 16 – 1).
Se almacena como un VARCHAR

LONGTEXT
Un texto de longitud máxima 4 Gigas caracteres. (2 ^ 32 – 1)
Se almacena como un VARCHAR

NOTA:

La diferencia entre ambos tipos, CHAR y VARCHAR, está en la forma de


almacenarlos. Teniendo en cuenta que un carácter necesita un byte para su
almacenamiento, un dato definido como CHAR(5) se almacena reservando espacio
para los 5 caracteres, aunque el datos almacenado tenga menos de 5. Sin embargo,
un dato definido como VARCHAR(5) en el que se almacene un datos solo reserva
espacio para el número de caracteres que tenga ese dato más uno para indicar el final
de la cadena.

VALOR CHAR(5) TAMAÑO VARCHAR(5) TAMAÑO


RESERVADO RESERVADO
‘‘ ‘‘ 5 BYTES ‘‘ 1 BYTE
‘AB’ ‘AB ‘ 5 BYTES ‘AB’ 3 BYTES

‘ABCDE’ ‘ABCDE’ 5 BYTES ‘ABCDE’ 6 BYTES

c) Fechas
Estos datos se tratan externamente como cadenas de caracteres por lo que estar entre comillas para
su utilización.

DATE
Este tipo de dato permite almacenar fechas, incluyendo en esa información: año, mes y día con
la forma ‘YYYY-MM-DD’.

DATETIME
Este tipo de dato permite almacenar fechas y horas, incluyendo en esa información: año, mes,
día, horas, minutos y segundos con la forma ‘YYYY-MM-DD HH:MM:SS’.

Página: 17
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

TIME
Este tipo de dato permite almacenar horas, incluyendo en esa información: horas, minutos y
segundos con la forma ‘HH:MM:SS’.

d) Binarios

BOOLEAN
Almacena valores binarios formados por combinaciones de los valores 1(verdadero) y 0 (falso).

Nota: hemos escogido los tipos datos más utilizados con la notación de MySQL que se ajustan a las
especificaciones del estándar ANSI/ISO SQL estándar. Pero si se utiliza otro sistema gestor debe
tenerse en cuenta que puede haber variaciones a la hora de indicar los tipos de datos.

Página: 18
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

4 - Operadores

4.1 - Operadores aritméticos


Operan entre valores numéricos y devuelven un valor numérico como resultado de realizar los cálculos
indicados, algunos de ellos se pueden utilizar también con fechas. Se emplean para realizar cálculos
numéricos.
Los operadores aritméticos son:

+ Suma
- Resta
* Multiplicación
/ División
Div División entera ( parte entera de la división, sin decimales)

4.2- Operadores de comparación


Las expresiones formadas con operadores de comparación dan como resultado un valor de tipo
Verdadero/Falso/Nulo (True/False/Null).
Los operadores de comparación son:

= Igual
!= Distinto
<> Distinto
< Menor
<= Menor o igual
> Mayor
>= Mayor o igual

BETWEEN / NOT BETWEEN


IN / NOT IN
IS NULL / IS NOT NULL
LIKE

Los primeros son los operadores relaciones ya conocidos. Los segundos son pares de un operador y
su negación con la siguiente forma de actuar:

BETWEEN valor1 AND valor2


Da como resultado VERDADERO si el valor comparado es mayor o igual que valor1 y
menor o igual que valor2 y FALSO en el caso contrario

IN (lista de valores separados por comas)


Da como resultado VERADADERO si el valor comparado está dentro de la lista de valores
especificado y FALSO en el caso contrario

IS NULL
Da como resultado VERDADERO si el valor del dato comparado es nulo (NULL) y FALSO
en el caso contrario

Página: 19
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

LIKE
Permite comparar dos cadenas de caracteres con la peculiaridad de que admite caracteres
comodines. Los caracteres comodines son '%' y '_'. Estos caracteres permiten utilizar
patrones en la comparación. El '%' puede ser sustituido por un grupo de caracteres (de 0 a
cualquier número) y el '_' por un carácter cualquiera en esa posición.

Ejemplos:

1. La expresión: APELLIDO = 'JIMENEZ' será verdadera (true) en el caso de que el valor de la


columna APELLIDO (suponemos que se trata de una columna) sea 'JIMENEZ' y falsa (false) en
caso contrario.

2. La expresión: SALARIO > 300000 será verdadera (true) en el caso de que SALARIO tenga un
valor superior a 300000 y falsa (false) en caso contrario.

3. La expresión APELLIDO LIKE 'A%' será verdadera (true) si el apellido empieza por A y después
tiene cualquier grupo de caracteres y falsa (false) en caso contrario. La expresión APELLIDO LIKE
'A_B_C' será verdadera (true) si el primer carácter es una A, el segundo cualquiera, el tercero una
B, el cuarto cualquiera y el quinto una C y falsa (false) en caso contrario.
Estos operadores de comparación se utilizan fundamentalmente para construir condiciones de
búsqueda en la base de datos. De esta forma se seleccionarán aquellas filas que cumplan la condición
especificada (aquellas filas para las que el valor de la expresión sea true). Por ejemplo, el siguiente
comando seleccionará todas las filas de la tabla empleados que en la columna OFICIO aparezca el
valor 'VENDEDOR'.

mysql> SELECT emp_no, apellido,oficio,fecha_alta,comision,salario


-> FROM empleados
-> WHERE oficio = 'VENDEDOR';

+--------+---------+----------+------------+----------+---------+
| EMP_NO | APELLIDO| OFICIO | FECHA_ALTA | COMISION | SALARIO |
+--------+---------+----------+------------+----------+---------+
| 7499 | ALONSO | VENDEDOR | 1981-02-23 | 400.00 | 1400.00 |
| 7654 | MARTIN | VENDEDOR | 1981-09-28 | 1600.00 | 1500.00 |
| 7844 | CALVO | VENDEDOR | 1981-09-08 | 0.00 | 1800.00 |
+--------+---------+----------+------------+----------+---------+
3 rows in set (0.00 sec)

4.3 - Operadores lógicos


Operan entre datos con valores lógicos Verdadero/Falso/Nulo y devuelven el valor lógico
Verdadero/Falso/Nulo. Los operadores lógicos son:

! NOT
&& AND
|| OR
XOR

A continuación se detallan las tablas de valores de los operadores lógicos NOT, AND y OR, teniendo
en cuenta todos los posibles valores, incluida la ausencia de valor (NULL).

Página: 20
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

NOT VERDADERO FALSO NULO

FALSO VERDADERO NULO

AND VERDADERO FALSO NULO

VERDADERO VERDADERO FALSO NULO

FALSO FALSO FALSO FALSO

NULO NULO FALSO NULO

OR VERDADERO FALSO NULO

VERDADERO VERDADERO VERDADERO VERDADERO

FALSO VERDADERO FALSO NULO

NULO VERDADERO NULO NULO

XOR VERDADERO FALSO NULO

VERDADERO FALSO VERDADERO NULO

FALSO VERDADERO FALSO NULO

NULO NULO NULO NULO

Podemos establecer:
• El operador NOT devuelve VERDADERO cuando el operando es falso, y FALSO cuando el
operando es verdadero y NULO cuando el operando es nulo.
• El operador AND devolverá VERDADERO cuando los dos operandos sean verdaderos, FALSO
cuando alguno de los dos operandos sea falso y NULO en los demás casos.
• El operador OR devolverá VERDADERO cuando alguno de los operandos sea verdadero,
FALSO cuando los dos operandos sean falsos; y NULO en los demás casos.
• El operador XOR devolverá VERDADERO si uno de los operandos es verdadero y el otro falso,
FALSO cuando ambos sean verdaderos o ambos falsos y NULO si alguno de ellos es nulo.

Ya hemos indicado que los operadores de comparación devuelven un valor de tipo


Verdadero/Falso/Nulo (True/False/Null). En ocasiones se necesita trabajar con varias
expresiones de comparación (por ejemplo cuando queremos formar una condición búsqueda que
cumpla dos condiciones, etcétera) en estos casos debemos recurrir a los operadores lógicos AND, OR,
XOR y NOT.

Página: 21
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

Supongamos que queremos consultar los empleados cuyo OFICIO = 'VENDEDOR' y que además su
SALARIO > 1500. En este caso emplearemos el operador lógico AND. Este operador devolverá el valor
true cuando los dos operandos o expresiones son verdaderas. Podemos decir que se utiliza el
operador AND cuando queremos que se cumplan las dos condiciones.

Ejemplo:

mysql> SELECT apellido, salario, oficio


-> FROM empleados
-> WHERE oficio = 'VENDEDOR' AND salario > 1500;

+----------+---------+----------+
| APELLIDO | SALARIO | OFICIO |
+----------+---------+----------+
| CALVO | 1800.00 | VENDEDOR |
+----------+---------+----------+
1 row in set (0.00 sec)

Cuando lo que queremos es buscar filas que cumplan alguna de las condiciones que se indican
emplearemos el operador OR. Este operador devolverá el valor VERDADERO cuando alguno de los
dos operandos o expresiones es verdadero .Podemos decir que se utiliza el operador OR cuando
queremos que se cumpla la primera condición, o la segunda o ambas.

Ejemplo:
mysql> SELECT apellido, salario, oficio
-> FROM empleados
-> WHERE oficio = 'VENDEDOR' OR salario > 1500;

+----------+---------+------------+
| APELLIDO | SALARIO | OFICIO |
+----------+---------+------------+
| ALONSO | 1400.00 | VENDEDOR |
| MARTIN | 1500.00 | VENDEDOR |
| GARRIDO | 3850.12 | DIRECTOR |
| MARTINEZ | 2450.00 | DIRECTOR |
| REY | 6000.00 | PRESIDENTE |
| CALVO | 1800.00 | VENDEDOR |
| GIL | 3350.00 | ANALISTA |
+----------+---------+------------+
7 rows in set (0.00 sec)

El operador NOT se utiliza para cambiar el valor devuelto por una expresión lógica o de comparación,
tal como se ilustra en el siguiente ejemplo:

mysql> SELECT apellido, salario, oficio


-> FROM empleados
-> WHERE NOT (oficio = 'VENDEDOR');

+----------+---------+------------+
| APELLIDO | SALARIO | OFICIO |
+----------+---------+------------+
| LOPEZ | 1350.50 | EMPLEADO |
| GARRIDO | 3850.12 | DIRECTOR |
| MARTINEZ | 2450.00 | DIRECTOR |

Página: 22
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

| REY | 6000.00 | PRESIDENTE |


| GIL | 3350.00 | ANALISTA |
| JIMENEZ | 1400.00 | EMPLEADO |
+----------+---------+------------+
6 rows in set (0.00 sec)

Observamos en el ejemplo anterior que han sido seleccionadas aquellas filas en las que no se cumple
la condición de que el oficio sea vendedor.

Podemos formar expresiones lógicas en las que intervengan varios operadores lógicos de manera
similar a como se haría con expresiones aritméticas en las que intervienen varios operadores
aritméticos.

Ejemplos:
mysql> SELECT apellido, salario, oficio
-> FROM empleados
-> WHERE NOT (oficio = 'VENDEDOR' AND salario > 1500);

+----------+---------+------------+
| APELLIDO | SALARIO | OFICIO |
+----------+---------+------------+
| ALONSO | 1400.00 | VENDEDOR |
| LOPEZ | 1350.50 | EMPLEADO |
| MARTIN | 1500.00 | VENDEDOR |
| GARRIDO | 3850.12 | DIRECTOR |
| MARTINEZ | 2450.00 | DIRECTOR |
| REY | 6000.00 | PRESIDENTE |
| GIL | 3350.00 | ANALISTA |
| JIMENEZ | 1400.00 | EMPLEADO |
+----------+---------+------------+
8 rows in set (0.00 sec)

mysql> SELECT apellido, salario, oficio, dep_no


-> FROM empleados
-> WHERE oficio = 'VENDEDOR'
AND salario>1500 OR dep_no = 20;

+----------+---------+----------+--------+
| APELLIDO | SALARIO | OFICIO | DEP_NO |
+----------+---------+----------+--------+
| CALVO | 1800.00 | VENDEDOR | 30 |
| GIL | 3350.00 | ANALISTA | 20 |
| JIMENEZ | 1400.00 | EMPLEADO | 20 |
+----------+---------+----------+--------+
3 rows in set (0.00 sec)

4.4 – Precedencia o prioridad en los operadores


En todo caso deberemos tener en cuenta la prioridad o precedencia del operador ya que puede
afectar al resultado de la operación.
La precedencia u orden de prioridad es un concepto matemático, conocido por todos, que nos
indica que operación se realizará primero en una expresión cuando hay varios operadores.

Página: 23
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

La evaluación de las operaciones en las expresiones se realiza de izquierda a derecha, pero


respetando las reglas de prioridad.

Por ejemplo
8 + 4 * 5 = 28
Aunque la suma esté antes (más a la izquierda) que la multiplicación, primero se realiza la
multiplicación y luego la suma. Esto es debido a que el operador * tiene mayor prioridad que el
operador +.

El orden de precedencia o prioridad de los operadores determina, por tanto, el orden de evaluación de
las operaciones de una expresión.

La tabla siguiente muestra los operadores disponibles agrupados y ordenados de mayor a menor por
su orden de precedencia.

Prioridad Operador Operación

1º *, /, DIV Multiplicación, división

2º +, - Suma, resta.

3º = , != , < , > , <= , >= , Comparación.


IS, LIKE , BETWEEN, IN
4º NOT Negación

5º AND Conjunción

6º OR, XOR Inclusión, exclusión

Esta es la prioridad establecida por defecto, los operadores que se encuentran en el mismo grupo
tienen la misma precedencia. Se puede cambiar utilizando paréntesis.

En la expresión anterior, si queremos que la suma se realice antes que la división, lo indicaremos:
(8 + 4) * 5
En este caso el resultado será: 60

Página: 24
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

5 - Funciones predefinidas
Son funciones incorporadas por el gestor y son muy utilizadas en SQL y dan mucha potencia al
lenguaje. Estas funciones predefinidas devuelven un valor dependiendo del valor de un argumento
que se pasa en la llamada.

Cabe subrayar que las funciones no modifican los valores del argumento, indicado entre paréntesis,
sino que devuelven un valor creado a partir de los argumentos que se le pasan en la llamada, y ese
valor puede ser utilizado en cualquier parte de una sentencia SQL.

Existen muchas funciones predefinidas para operar con todo tipo de datos. A continuación se indican
las funciones predefinidas más utilizadas. Estas funciones se tratarán con más detalle y se realizarán
ejemplos en el tema 5 (punto 5.4) Y se realizarán ejercicios con estas funciones lo que ayudará a su
mejor comprensión.

Vamos a ver estas funciones agrupadas según el tipo de datos con los que operan y/o el tipo de datos
que devuelven.

Nota: estas funciones pueden variar según el sistema gestor que se utilice.

5.1 - Funciones numéricas o aritméticas

Función Valor que devuelve.

Valor absoluto.
ABS(num) Valor absoluto de num.

Función “Techo”
CEIL( num) Devuelve el entero mas pequeño mayor que num

Función “Suelo”
FLOOR(num) Devuelve el entero mas grande menor que num

Potencia del número e


EXP(num) Devuelve el número e elevado a num

Logaritmo neperiano
LN(num) Devuelve el logaritmo en base e de num

Logaritmo
LOG(num) Devuelve el logaritmo en base 10 de num

Módulo
MOD(num1, num2). Resto de la división entera de num1 por num2

Pi
PI() Devuelve el valor de la constante PI

Página: 25
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

Potencia
POWER(num1, num2). Devuelve num1 elevado a num2.

Número aleatorio
RAND() Genera un número aleatorio entre 0 y 1

Redondeo
ROUND(num1, num2) Devuelve num1 redondeado a num2 decimales.
Si se omite num2 redondea a 0 decimales.
Signo Si num < 0 devuelve -1,
SIGN(num). Si num = 0 devuelve 0
Si num > 0 devuelve 1.
Raíz cuadrada
SQRT(num). Devuelve la raíz cuadrada de num

Truncado
TRUNCATE(num1, num2). Devuelve num1 truncado a num2 decimales.
Si se omite num2 trunca a 0 decimales.

5.2 - Funciones de caracteres

Función Valor que devuelve.

ASCII
ASCII(cad1). Código ASCII del carácter cad1.

Carácter ASCII
CHAR(num) Devuelve el carácter cuyo código ASCII es num

Concatenar
CONCAT(cad1,cad2 [,cad3…].) Concatena cad1 con cad2. Si existiesen más cadenas, cad3…,l
las concatenaría a continuación

Insertar
INSERT(cad1, pos, ,len, cad2) Devuelve cad1 con len caracteres desde pos en adelante
sustituidos en cad2

Longitud
LENGTH(cad1) Devuelve la longitud de cad1.

Localizar
LOCATE(cad1,cad2,pos) Devuelve la posición de la primera ocurrencia de cad1 en cad2
empezando desde pos
Minúsculas
LOWER(cad1) La cadena cad1 en minúsculas.

Página: 26
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

Rellenar (Izquierda)
LPAD(cad1, n, cad2) Añade a cad1 por la izquierda cad2, hasta que tenga n caracteres.
Si se omite cad2, añade blancos.
Suprimir (Izquierda)
LTRIM(cad1) Suprime blancos a la izquierda de cad1.

Reemplazar
REPLACE(cad1,cad2,cad3) Devuelve cad1 con todas las ocurrencias de cad2 reemplazadas
por cad3
Rellenar (Derecha)
RPAD(cad1, n, cad2) Igual que LPAD pero por la derecha.

Suprimir (Derecha)
RTRIM(c1) Suprime blancos a la derecha de c1.
Igual que LTRIM pero por la izquierda.
Subcadena
SUBSTR(c1, n, m) Devuelve una subcadena a partir de c1 comenzando en
La posición n tomando m caracteres.
Mayúsculas
UPPER(cad1) La cadena cad1 en mayúsculas.

5.3 - Funciones de fecha

Función Valor que devuelve.

Incremento de días
ADDDATE(Fecha, Num) Devuelve Fecha incrementada en Num días

Decremento de días
SUBDATE(Fecha, Num) Devuelve Fecha decrementada en Num días

Incremento Devuelve Fecha incrementada en


DATE_ADD(Fecha, INTERVAL Num Formato) Num veces lo indicado en Formato
Formato puede ser entre otros: DAY, WEEK,
MONTH, YEAR, HOUR, MINUTE, SECOND
Decremento Devuelve Fecha decrementada en
DATE_SUB(Fecha, INTERVAL num Formato) Num veces lo indicado en Formato
Formato puede ser entre otros: DAY, WEEK,
MONTH, YEAR, HOUR, MINUTE, SECOND
Diferencia de fechas
DATEDIFF(Fecha1,Fecha2) Devuelve el número de días entre Fecha1 y
Fecha2
Nombre del día de la semana
DAYNAME(Fecha) Devuelve el nombre del día de la semana de
Fecha
Día del mes
DAYOFMONTH(Fecha) Devuelve el número del día del mes de Fecha

Página: 27
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

Día de la semana
DAYOFWEEK(Fecha) Devuelve el número del día de la semana de
Fecha (1.Domingo, 2:Lunes.....7:Sábado)
Día del año
DAYOFYEAR(Fecha) Devuelve el número de día del año de Fecha (de 1
a 366)
Semana
WEEKOFYEAR(Fecha) Devuelve el número de semana de Fecha (de 1 a
53)
Mes
MONTH(Fecha) Devuelve el número de mes de Fecha ( de 1 a 12)

Año
YEAR(Fecha) Devuelve el número de año con 4 dígitos de Fecha
(de 0000 a 9999)
Hora
HOUR(Tiempo) Devuelve la hora de Tiempo (de 0 a 23)

Minutos
MINUTE(Tiempo) Devuelve los minutos de Tiempo (de 0 a 59)

Segundos
SECOND(Tiempo) Devuelve los segundos de Tiempo (de 0 a 59)

Devuelve la fecha actual con el formato ‘YYYY-


CURDATE() MM-DD’

Devuelve la hora actual con el formato ‘HH:MM:SS’


CURTIME()

Devuelve la fecha y la hora actual con el formato


SYSDATE() ‘YYYY-MM-DD HH:MM:SS’

Para la conversión de fechas a otro tipo de datos:

Función Valor que devuelve.

Devuelve una cadena de caracteres con la Fecha con el


DATE_FORMAT(Fecha,Formato) Formato especificado.
El formato es una cadena de caracteres que incluye las
siguientes máscaras:
Mascara Descripción

Página: 28
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

%a Abreviatura (3 letras) del nombre del día de la semana


%b Abreviatura (3 letra ) del nombre mes
%c Número del mes (1 a 12)
%e Número del día del mes (0 a 31)
%H Número de la hora en formato 24 horas (00 a 23)
%h Número de la hora en formato 12 horas (01 a 12)
%i Número de minutos (00 a 59)
%j Número del día del año (001 a 366)
%M Nombre del mes
%m Número de mes (01 a 12)
%p Am o PM
%r Hora en formato 12 horas (hh:mm seguido de AM o PM)
%s Número de segundos (00 a 59)
%T Hora en formato 24 horas (hh:mm:ss)
%u Número de semana en el año (00 a 53)
%W Nombre del día de la semana
%w Número del día de la semana (0:domingo a 6:Sábado)
%Y Número de año con cuatro dígitos
%y Número de año con dos dígitos

5.4 - Funciones de comparación

Función Valor que devuelve.

Mayor de la lista
GREATEST(lista de valores) Devuelve el valor más grande de una lista de columnas
o expresiones de columna
Menor de la lista
LEAST(lista de valores) Devuelve el valor más pequeño de una lista de
columnas o expresiones de columna

Conversión de nulos
IFNULL(exp1, exp2) Si exp1 es nulo devuelve exp2, sino devuelve exp1

Comprobación de nulo
ISNULL(exp) Devuelve 1( True) si exp es NULL y 0 (False) en caso
contrario
Comparación de cadenas
STRCMP(cad1,cad2) Devuelve 1(True) si cad1 y cad2 son iguales, 0(False)
si no lo son y NULL si alguna de ellas es nula

Página: 29
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

5. 5 - Otras funciones

Función Valor que devuelve.

Base de datos
DATABASE() Nombre de la base de datos actual

Usuario
USER() Devuelve el usuario y el host de la sesión
usuario@host
Versión
VERSION() Devuelve una cadena indicando la versión que estamos
utilizando

Página: 30
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

6 – Valores Nulos ( NULL )


En SQL la ausencia de valor se expresa como valor nulo (NULL). Es importante ser conscientes de
que esta ausencia de valor o valor nulo no equivale en modo alguno al valor 0 o a una cadena de
caracteres vacía.

Hay que tener cuidado al operar con columnas que pueden contener valores nulos, pues la lógica
cambia. Vamos a ver como se trabaja con estos valores nulos.
• Si realizamos operaciones aritméticas hay que tener en cuenta que cualquier expresión aritmética
que contenga algún valor nulo dará como resultado un valor nulo.
Así, por ejemplo, si intentamos visualizar la expresión formada por las columnas SALARIO +
COMISION de la tabla empleados la salida será similar a la siguiente:

mysql> SELECT apellido, salario, comision, salario + comision


-> FROM empleados;
+----------+---------+----------+--------------------+
| APELLIDO | SALARIO | COMISION | SALARIO + COMISION |
+----------+---------+----------+--------------------+
| ALONSO | 1400.00 | 400.00 | 1800.00 |
| LOPEZ | 1350.50 | NULL | NULL |
| MARTIN | 1500.00 | 1600.00 | 3100.00 |
| GARRIDO | 3850.12 | NULL | NULL |
| MARTINEZ | 2450.00 | NULL | NULL |
| REY | 6000.00 | NULL | NULL |
| CALVO | 1800.00 | 0.00 | 1800.00 |
| GIL | 3350.00 | NULL | NULL |
| JIMENEZ | 1400.00 | NULL | NULL |
+----------+---------+----------+--------------------+

En el ejemplo anterior observamos que la expresión SALARIO + COMISION retornará un valor nulo
siempre que alguno de los valores sea nulo incluso aunque el otro no lo sea. También podemos
observar que el valor 0 en la comisión retorna el valor calculado de la expresión.

• Si comparamos expresiones que contienes el valor nulo con otro valor nulo el resultado no es ni
mayor ni menor ni igual. En SQL un valor nulo ni siquiera es igual a otro valor nulo tal como podemos
apreciar en el siguiente ejemplo:

mysql> SELECT *
-> FROM empleados
-> WHERE comision = NULL;
Empty set (0.00 sec)

La explicación es que un valor nulo es indeterminado, y por tanto, no es igual ni distinto de otro valor
nulo. Cuando queremos comprobar si un valor es nulo emplearemos el operador IS NULL (o IS NOT
NULL para comprobar que es distinto de nulo):

mysql> SELECT emp_no, apellido,oficio,fecha_alta,comision,salario


-> FROM empleados
-> WHERE comision IS NULL;
+--------+----------+------------+------------+----------+---------+
| EMP_NO | APELLIDO | OFICIO | FECHA_ALTA | COMISION | SALARIO |
+--------+----------+------------+------------+----------+---------+
| 7521 | LOPEZ | EMPLEADO | 1981-05-08 | NULL | 1350.50 |

Página: 31
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

| 7698 | GARRIDO | DIRECTOR | 1981-05-01 | NULL | 3850.12 |


| 7782 | MARTINEZ | DIRECTOR | 1981-06-09 | NULL | 2450.00 |
| 7839 | REY | PRESIDENTE | 1981-11-17 | NULL | 6000.00 |
| 7876 | GIL | ANALISTA | 1982-05-06 | NULL | 3350.00 |
| 7900 | JIMENEZ | EMPLEADO | 1983-03-24 | NULL | 1400.00 |
+--------+----------+------------+------------+----------+---------+

Como acabamos de ver, los valores nulos en muchas ocasiones pueden representar un problema,
especialmente en columnas que contienen valores numéricos.
Para evitar estos problemas y asegurarnos de la ausencia de valores nulos en una columna ya vimos
que existe una restricción NOT NULL (es una orden de definición de datos) que impide que se incluyan
valores nulos en una columna.
En caso de que permitamos la existencia de valores nulos hay que evitar estos problemas y utilizar la
función IFNULL (que veremos en detalle más adelante) que se utiliza para devolver un valor
determinado en el caso de que el valor del argumento sea nulo. Así nos aseguramos en las
operaciones aritméticas que no hay nulos con los que operar. Por ejemplo si queremos sumar el
salario + comision debemos utilizar IFNULL (comision,0) retornará 0 cuando el valor de comisión sea
nulo y sumaremos un 0 a salario.

mysql> SELECT apellido, salario, comision,


-> salario + IFNULL(comision,0) "SALARIO TOTAL"
-> FROM empleados;
+----------+---------+----------+---------------+
| APELLIDO | SALARIO | COMISION | SALARIO TOTAL |
+----------+---------+----------+---------------+
| ALONSO | 1400.00 | 400.00 | 1800.00 |
| LOPEZ | 1350.50 | NULL | 1350.50 |
| MARTIN | 1500.00 | 1600.00 | 3100.00 |
| GARRIDO | 3850.12 | NULL | 3850.12 |
| MARTINEZ | 2450.00 | NULL | 2450.00 |
| REY | 6000.00 | NULL | 6000.00 |
| CALVO | 1800.00 | 0.00 | 1800.00 |
| GIL | 3350.00 | NULL | 3350.00 |
| JIMENEZ | 1400.00 | NULL | 1400.00 |
+----------+---------+----------+---------------+
9 rows in set (0.00 sec)

Página: 32
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

7 – Expresiones y condiciones
Una expresión es un conjunto variables, constantes o literales, funciones, operadores y paréntesis.
Los paréntesis sirven para variar el orden de prioridad y sólo son obligatorios en ese caso.
Un caso especial de expresión es lo que llamamos condición. Condición es un expresión cuyo
resultado es Verdadero/Falso/Nulo (True/False/Null)

Las sentencias SQL pueden incluir expresiones y condiciones con nombres de columnas y literales.
Ejemplos de expresiones:
• SALARIO + COMISION -> Devuelve un valor numérico como resultado de sumar al
salario del empleado la comisión correspondiente.

• EMPLEADOS.DEPT_NO = DEPARTAMENTOS.DEPT_NO -> Devuelve verdadero o falso


dependiendo de que el número de departamento del empleado seleccionado coincida con el
número de departamento del departamento seleccionado.

• FECHA_AL BETWEEN ‘1980-01-01’ AND ‘1982-10-01’-> Devuelve verdadero si


la fecha de alta del empleado seleccionado se encuentra entre las dos fechas especificadas.

• COMISION IS NULL -> dará como resultado verdadero si la comisión del empleado
seleccionado no tiene ningún valor.

Por ejemplo la siguiente sentencia visualizará el apellido, la fecha de alta, el salario y la suma del
salario más una gratificación de 1.000 euros
mysql> SELECT apellido, fecha_alta, salario,
-> salario + 1000 "SALARIO CON GRATIFICACION"
-> FROM EMPLEADOS;
+----------+------------+---------+---------------------------+
| APELLIDO | FECHA_ALTA | SALARIO | SALARIO CON GRATIFICACION |
+----------+------------+---------+---------------------------+
| ALONSO | 1981-02-23 | 1400.00 | 2400.00 |
| LOPEZ | 1981-05-08 | 1350.50 | 2350.50 |
| MARTIN | 1981-09-28 | 1500.00 | 2500.00 |
| GARRIDO | 1981-05-01 | 3850.12 | 4850.12 |
| MARTINEZ | 1981-06-09 | 2450.00 | 3450.00 |
| REY | 1981-11-17 | 6000.00 | 7000.00 |
| CALVO | 1981-09-08 | 1800.00 | 2800.00 |
| GIL | 1982-05-06 | 3350.00 | 4350.00 |
| JIMENEZ | 1983-03-24 | 1400.00 | 2400.00 |
+----------+------------+---------+---------------------------+
9 rows in set (0.00 sec)

Hay unas reglas de sintaxis que se deben respetar. Un error relativamente frecuente consiste en
utilizar expresiones del tipo: 1000 >= SALARIO <= 2000

Este tipo de expresiones no es correcto y no producirá el resultado deseado, ya que al evaluar la


primera parte de la expresión se sustituirá por un valor lógico de tipo true/false/null y este
resultado no puede compararse con un valor numérico.
La expresión correcta sería:
SALARIO BETWEEN 1000 AND 2000
O bien:
SALARIO >= 1000 AND SALARIO <= 2000.

Página: 33
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

TEMA 3. CREACIÓN DE TABLAS

Paulina Barthelemy

1 - Consideraciones previas a la creación de una tabla


Antes de escribir la sentencia para crear una tabla debemos pensar una serie de datos y
requisitos que va a ser necesario definir en la creación.
Es importante pensar en la tabla que se quiere crear tomando las decisiones necesarias antes
de escribir el formato de la creación.

1.1 – Definición de la tabla


Por una parte unas consideraciones básicas como:
• El nombre de la tabla.
• El nombre de cada columna.
• El tipo de dato almacenado en cada columna.
• El tamaño de cada columna.

1.2 - Restricciones en las tablas


Por otra parte, información sobre lo que se pueden almacenar las filas de la tabla. Esta información
serán las restricciones que almacenamos en las tablas. Son una parte muy importante del modelo
relacional pues nos permiten relacionar las tablas entre sí y poner restricciones a los valores de que
pueden tomas los atributos (columnas) de estas tablas.

Restricciones, llamadas CONSTRAINTS, son condiciones que imponemos en el momento de crear


una tabla para que los datos se ajusten a una serie de características predefinidas que mantengan su
integridad.

Se conocen con su nombre en inglés y se refieren a los siguientes conceptos:

a) NOT NULL. Exige la existencia de valor en la columna que lleva la restricción.

b) DEFAULT. Proporciona un valor por defecto cuando la columna correspondiente no se le da


valor en la instrucción de inserción.
Este valor por defecto debe ser una constante. No se permiten funciones ni expresiones.

c) PRIMARY KEY. Indica una o varias columnas como dato o datos que identifican unívocamente
cada fila de la tabla. Sólo existe una por tabla y en ninguna fila puede tener valor NULL, por
definición.
Es obligatoria su existencia en el modelo relacional.

Página: 34
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

d) FOREIGN KEY. Indica que una determinada columna de una tabla, va a servir para referenciar a
otra tabla en la que está definida la misma columna (columna o clave referenciada). El valor de la
clave ajena deberá coincidir con uno de los valores de esta clave referenciada o ser NULL. No existe
límite en el número de claves ajenas que pueda tener una tabla. Como caso particular, una clave
ajena puede referenciar a la misma tabla en la que está. Para poder crear una tabla con clave ajena
deberá estar previamente creada la tabla maestra en la que la misma columna es clave primaria.

e) UNIQUE. Indica que esta columna o grupo de columnas debe tener un valor único. También
admite valores nulos. Al hacer una nueva inserción se comprobará que el valor es único o NULL.
Algunos sistemas gestores de bases de datos relacionales generan automáticamente índices para
estas columnas

f) CHECK. Comprueba si el valor insertado en esa columna cumple una determinada


condición.

Página: 35
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

2 - Formato genérico para la creación de tablas.


La sentencia SQL que permite crear tablas es CREATE TABLE.

2.1 - Formato básico para la creación de tablas


Comenzaremos con un formato básico de creación de tabla al que iremos añadiendo,
posteriormente, otras informaciones.

CREATE TABLE [IF NOT EXISTS] NombreTabla


( NombreColumna TipoDato [ , NombreColumna TipoDato ]…. );

donde NombreTabla ................ es el identificador elegido para la tabla


NombreColumna ........... es el identificador elegido para cada columna
TipoDato.......................... indica el tipo de dato que se va a almacenar en esa columna.
(Ver apartado 3 del Tema 2).

El nombre de la tabla debe ser único en la base de datos. Los nombres de columnas deben ser
únicos dentro de la tabla.

Para el nombre de la tabla y de las columnas se elegirán identificadores de acuerdo con las reglas del
gestor de la base de datos (Ver apartado 2.1 del Tema 2). Estos identificadores no pueden
coincidir con palabras reservadas.

Existirán tantas definiciones de columna como datos diferentes se vayan a almacenar en la tabla que
estamos creando, todas ellas separadas por comas.

La cláusula IF NOT EXISTS previene el posible error generado si existiese una tabla
con ese nombre.

2.2 – Ejemplos básicos de creación de tablas


Los siguientes ejemplos de creación de tablas se van a utilizar siempre nuevas tablas para no alterar
las tablas anteriormente utilizadas.

Realizaremos con un ejemplo de una biblioteca queremos guardar los datos de los socios en una
tabla socios y los préstamos que se realizan en una tabla prestamos. Empezaremos con los
formatos básicos e iremos añadiendo cláusulas. En cada apartado le daremos un nombre
diferente a las tablas para evitar problemas (si en la instrucción e creación el nombre de la tabla
ya existe se produce un error )

1-. Crear una tabla socios con los datos de los socios:
• Numero de socio Número entero de 4 dígitos
• Apellidos del socios Cadena de 14 caracteres máximo
• Teléfono Cadena de 9 caracteres
• Fecha de alta como socio Fecha
• Dirección Cadena de 20 carateres máximo

Página: 36
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

• Codigo postal Número entero de 5 dígitos

mysql> CREATE TABLE socios_0


-> (socio_no INT(4),
-> apellidos VARCHAR(14),
-> telefono CHAR(9),
-> fecha_alta DATE,
-> direccion VARCHAR(20),
-> codigo_postal INT(5));
Query OK, 0 rows affected (0.30 sec)

El campo telefono lo creamos tipo CHAR en lugar de VARCHAR porque siempre tendrá 9 caracteres

2. Crear una tabla prestamos para guardar los préstamos hechos a los socios con los datos:
• Número del préstamo Número entero de 2 dígitos
• Código del socio Número entero de 4 dígitos

mysql> CREATE TABLE prestamos_0


-> (num_prestamo INT(2),
-> socio_no INT(4));
Query OK, 0 rows affected (0.08 sec)

2.3 – Formatos para la creación de tablas con la definición de


restricciones
Los valores por defecto pueden ser: constantes, funciones SQL o las variables USER o SYSDATE.
La restricciones pueden definirse de dos formas, que llamaremos

1. Restriccion1 Definición de la restricción a nivel de columna


2. Restriccion2 Definición de la restricción a nivel de tabla

Estas restricciones , llamadas CONSTRAINTS se pueden almacenar con o sin nombre. Si no se lo


damos nosotros lo hará el sistema siguiendo una numeración correlativa, que es poco representativa.

Es conveniente darle un nombre, para después podernos referirnos a ellas si las queremos borrar o
modificar. Estos nombres que les damos a las CONSTRAINTS deben ser significativos para hacer
mas fácil las referencias. Por ejemplo:

• pk_NombreTabla para PRIMARY KEY


• fk_NombreTabla1_NombreTabla2 FOREIGN KEY donde NombreTabla1 es la tabla donde
se crea y NombreTabla2 es la tabla a la que referencia.
• uq_NombreTabla_NombreColumna para UNIQUE

Página: 37
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

2.3.1 - Formato para la creación de tablas con restricciones definidas a nivel de columna
Definimos cada restricción al mismo tiempo que definimos la columna correspondiente.

CREATE TABLE [IF NOT EXISTS] NombreTabla


( NombreColumna TipoDato [Restriccion1]
[ , NombreColumna TipoDato [Restriccion1] ….. ] );

donde Restriccion1....... es la definición de la restricción a nivel de columna

Las restricciones solo se pueden definir de esta forma si afectan a una sola columna, la que estamos
definiendo es ese momento.

Definición de los diferentes tipos de CONSTRAINTS a nivel de tabla (Restriccion1)

a) CLAVE PRIMARIA
PRIMARY KEY
b) POSIBILIDAD DE NULO
NULL | NOT NULL
c) VALOR POR DEFECTO
DEFAULT ValorDefecto
d) UNICIDAD
UNIQUE
e) COMPROBACION DE VALORES
CHECK (Expresion)
Nota: Esta cláusula de SQL estándar, en MySQL en la versión 5 está permitida pero no
implementada
f) CLAVE AJENA
REFERENCES NombreTabla [( NombreColumna )]
Notación: el nombre de tabla referenciada es el nombre de la tabla a la que se va a acceder
con la clave ajena. Si la columna que forma la clave referenciada en dicha tabla no tiene el
mismo nombre que en la clave ajena, debe indicarse su nombre detrás del de la tabla
referenciada y dentro del paréntesis. Si los nombres de columnas coinciden en la clave ajena y en
la primaria, no es necesario realizar esta indicación.

g) AUTO INCREMENTO
AUTO_INCREMENT
Aunque no es propiamente una restricción, pero como parte de la definición de una columnas
podemos indicar que sea AUTO_INCREMENT. De esta forma el sistema gestor irá poniendo
valores en esta columna incrementándolos de 1 en 1 respecto al anterior y empezando por 1
(opción por defecto que se puede modificar cambiando las opciones de las tabla en la creación lo
que queda fuera de este curso). Esta definición sólo se puede aplicar sobre columnas definidas
como y enteras y que sean claves.

2.3.2 - Ejemplos de definición de restricciones a nivel de columna


Veremos un ejemplo de cada caso donde se van definiendo las columnas con las
correspondientes restricciones.

Página: 38
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

a)PRIMARY KEY. El numero de socio en la tabla socios

mysql> CREATE TABLE socios_1a


-> (socio_no INT(4) PRIMARY KEY,
-> apellidos VARCHAR(14),
-> telefono CHAR(9),
-> fecha_alta DATE,
-> direccion VARCHAR(20),
-> codigo_postal INT(5));
Query OK, 0 rows affected (0.08 sec)

b) NOT NULL. La columna teléfono es obligatoria en la tabla socios, nunca irá sin información.

mysql> CREATE TABLE socios_1b


-> (socio_no INT(4) PRIMARY KEY,
-> apellidos VARCHAR(14),,
-> telefono CHAR(9) NOT NULL,
-> fecha_alta DATE,
-> direccion VARCHAR(20),
-> codigo_postal INT(5));
Query OK, 0 rows affected (0.05 sec)

c) DEAFAULT. En ausencia de valor el campo fecha _ alta tomará el valor de 1 de enero de 2000.

mysql> CREATE TABLE socios_1c


-> (socio_no INT(4) PRIMARY KEY,
-> apellidos VARCHAR(14),
-> telefono CHAR(9) NOT NULL,
-> fecha_alta DATE DEFAULT '2000-01-01',
-> direccion VARCHAR(20),
-> codigo_postal INT(5));
Query OK, 0 rows affected (0.11 sec)

d) UNIQUE. La columna apellido será única en la tabla socios.

mysql> CREATE TABLE socios_1d


-> (socio_no INT(4) PRIMARY KEY,
-> apellidos VARCHAR(14) UNIQUE,
-> telefono CHAR(9) NOT NULL,
-> fecha_alta DATE DEFAULT '2000-01-01',
-> direccion VARCHAR(20),
-> codigo_postal INT(5) );
Query OK, 0 rows affected (0.06 sec)

e)CHECK. Se comprobará que la columna cdigo_postal corresponde a Madrid (valores entre


28000 y 28999)

mysql> CREATE TABLE socios_1e


-> (socio_no INT(4) PRIMARY KEY,
-> apellidos VARCHAR(14) UNIQUE,
-> telefono CHAR(9) NOT NULL,
-> fecha_alta DATE DEFAULT '2000-01-01',
-> direccion VARCHAR(20),
-> codigo_postal INT(5)

Página: 39
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

CHECK (codigo_postal BETWEEN 28000 AND 28999) );


Query OK, 0 rows affected (0.06 sec)

f) FOREIGN KEY. El campo socio_num de la tabla prestamos tendrá que tener valores existentes
en el campo num_socio de la tabla socios o valor nulo.

mysql> CREATE TABLE prestamos


-> (num_prestamo INT(2) PRIMARY KEY,
-> socio_no INT(4) REFERENCES socios_1e(socio_no));
Query OK, 0 rows affected (0.17 sec)

g) AUTO INCREMENTO. Crearemos una tabla con una columna AUTO_INCREMENT y


posteriormente (siguiente tema) insertaremos valores.

mysql> CREATE TABLE inventario


-> (num INT(2) AUTO_INCREMENT PRIMARY KEY,
-> descripcion VARCHAR(15));
Query OK, 0 rows affected (0.49 sec)

2.3.3 - Formato para la creación de tablas con restricciones definidas a


nivel de tabla
En este caso definimos todas las restricciones al final de la sentencia, una vez terminada la
definición de las columnas.

CREATE TABLE [IF NOT EXISTS NombreTabla


( NombreColumna TipoDato [ , NombreColumna TipoDato..... ]
[Restriccion2 [ , Restrccion2]….. );

donde Restriccion2....... es la definición de la restricción a nivel de tabla

Las restricciones siempre se pueden definir de esta forma tanto si afectan a una sola columna como
a varias columnas y puede darse un nombre a cada una de las restricciones.

Definición de los diferentes tipos de CONSTRAINTS a nivel de tabla (Restriccion2)

a) PRIMARY KEY
[CONSTRAINT [NombreConstraint]]
PRIMARY KEY (Nombrecolumna [,NombreColumna....] )
b) UNIQUE
[CONSTRAINT [NombreConstraint]] UNIQUE (NombreColumna
[,NombreColumna...] )
c) CHECK
[CONSTRAINT [NombreConstraint]] CHECK (Expresion)
d) FOREIGN KEY
[CONSTRAINT [NombreConstraint ]]

Página: 40
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

FOREIGN KEY (NombreColumna[, NombreColumna...])


REFERENCES ( NombreTabla [ NombreColumna [, NombreColumna.....]] )
Notación: los nombres de columna o columnas que siguen a la cláusula FOREIGN KEY es
aquella o aquellas que están formando la clave ajena. Si hay más de una se separan por
comas. El nombre de tabla referenciada es el nombre de la tabla a la que se va a acceder
con la clave ajena. Si la columna o columnas que forman la clave referenciada en dicha tabla
no tienen el mismo nombre que en la clave ajena, debe indicarse su nombre detrás del de la
tabla referenciada y dentro de paréntesis. Si son más de una columna se separan por comas.
Si los nombres de columnas coinciden en la clave ajena y en la primaria, no es necesario realizar
esta indicación.

2.3.4 - Ejemplos de definición de restricciones a nivel de tabla


Veremos un ejemplo de cada caso donde se van definiendo la columna con la correspondiente
restricción. Algunos ejemplos con nombre de constraint y otros sin él.
En un ejemplo, igual que el apartado anterior, de una biblioteca queremos guardar los datos de
los socios en una tabla socios y los préstamos que se realizan en una tabla prestamos

a)PRIMARY KEY. El numero de socio será la clave primaria en la tabla socios. Será
obligatoriamente no nulo y único.

mysql> CREATE TABLE socios_2a


-> (socio_no INT(4),
-> apellidos VARCHAR(14),
-> telefono CHAR(9),
-> fecha_alta DATE,
-> direccion VARCHAR(20),
-> codigo_postal INT(5),
-> CONSTRAINT PK2_DEPARTAMENTOS PRIMARY KEY (socio_no));
Query OK, 0 rows affected (0.08 sec)

b) UNIQUE. El campo apellido es único. Tendrá valores diferentes en cada fila o el valor nulo

mysql> CREATE TABLE socios_2b


-> (socio_no INT(4),
-> apellidos VARCHAR(14),
-> telefono CHAR(9),
-> fecha_alta DATE,
-> direccion VARCHAR(20),
-> codigo_postal INT(5),
-> CONSTRAINT PK_SOCIOS PRIMARY KEY(socio_no),
-> CONSTRAINT UQ_UNIQUE UNIQUE (apellidos));
Query OK, 0 rows affected (0.06 sec)

c)CHECK. La columna codigo_postal no admitirá como válidas aquellas filas en las que el código
postal no tenga valores entre 28.000 y 28.999 (correspondientes a Madrid)

mysql> CREATE TABLE socios_2c


-> (socio_no INT(4),
-> apellidos VARCHAR(14),
-> telefono CHAR(9),

Página: 41
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

-> fecha_alta DATE,


-> direccion VARCHAR(20),
-> codigo_postal INT(5),
-> CONSTRAINT PK_DEPARTAMENTOS PRIMARY KEY(socio_no),
-> CONSTRAINT UQ_UNIQUE UNIQUE(apellidos),
-> CONSTRAINT CK_CODIGO
-> CHECK (codigo_postal BETWEEN 28000 AND
28999) );
Query OK, 0 rows affected (0.17 sec)

d) FOREIGN KEY. El número de socio en una tabla prestamos será clave ajena referenciando a la
columna correspondiente de la tabla socios.

mysql> CREATE TABLE prestamos_2


-> (num_prestamo INT(2),
-> socio_no INT(4) ,
-> CONSTRAINT PK_PRESTAMOS PRIMARY KEY(num_prestamo),
-> CONSTRAINT FK_SOCIO_PRESTAMOS FOREIGN KEY (socio_no)
REFERENCES socios_2c(socio_no) );
Query OK, 0 rows affected (0.13 sec)

2.4 - Integridad referencial


La definición de claves ajenas nos permiten mantener la integridad referencial en una base de datos
relacional. Hemos dicho que la columna o columnas definidas como clave ajena deben tomar valores
que se correspondan con un valor existente de la clave referenciada. La pregunta es: ¿qué sucede si
queremos borrar o modificar un valor de la clave primaria refenciada? Pues que el sistema debe
impedirnos realizar estas acciones pues dejaría de existir la integridad referencial.

Por ejemplo si tenemos


CREATE TABLE departamentos
(dep_no INT(4)
CONSTRAINT pk_departamentos PRIMARY KEY.....);

CREATE TABLE empleados


(....dep_no INT(4) CONSTRAINT fk_empleados_departamentos
REFERENCES departamentos(dep_no).... );

En este caso empleados.dep_no solo puede tomar valores que existan en departamentos.dep_no
pero ¿que sucede si queremos borrar o modificar un valor de departamentos.dep_no.? El sistema no
nos lo permitirá si existen filas con ese valor en la tabla de la clave ajena.

Sin embargo, en ocasiones, será necesario hacer estas operaciones. Para mantener la integridad de
los datos, al borrar (DELETE), modificar (UPDATE)una fila de la tabla referenciada, el sistema no nos
permitirá llevarlo a cabo si existe una fila con el valor referenciado. También se conoce como RESTRICT.
Es la opción por defecto, pero existen las siguientes opciones en la definición de la clave ajena:

• CASCADE. El borrado o modificación de una fila de la tabla referenciada lleva consigo el


borrado o modificación en cascada de las filas de la tabla que contiene la clave ajena. Es la más
utilizada.
• SET NULL. El borrado o modificación de una fila de la tabla referenciada lleva consigo

Página: 42
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

poner a NULL los valores de las claves ajenas en las filas de la tabla que referencia.
• SET DEFAULT. El borrado o modificación de una fila de la tabla referenciada lleva consigo
poner un valor por defecto en las claves ajenas de la tabla que referencia.
• NO ACTION. El borrado o modificación de una fila de la tabla referenciada solo se produce
si no existe ese valor en la tabla que contiene la clave ajena. Tiene el mismo efecto que
RESTRICT.

Formato de la definición de clave ajena con opciones de referencia

REFERENCES NombreTabla [ ( NombreColumna [ , NombreColumna ] ) ]


[ON DELETE {CASCADE| SET NULL|NO ACTION | SET DEFAULT| RESTRICT}]
[ON UPDATE {CASCADE| SET NULL|NO ACTION | SET DEFAULT| RESTRICT}]

por ejemplo
CREATE TABLE empleados
(....
dep_no NUMBER(4) CONSTRAINT FK_EMPLEADOS_DEPARTAMENTOS
REFERNCES departamentos(dep_no)
ON DELETE SET NULL
ON UPDATE CASCADE .... );

Esto quiere decir que el sistema pondrá nulos en dep_no de la tabla empleados si se borra el
valor correspondiente en departamentos y modificará el valor de dep_no en la tabla
empleados con el nuevo valor si se modifica la columna dep_no en la tabla departamentos.

En el tema siguiente veremos con más detalle los borrados y modificaciones en los casos en los
que existan estas cláusulas en las definiciones de las tablas, realizando algún ejemplo.

2.5 - Formato completo de la creación de tablas

CREATE TABLE [IF NOT EXISTS] NombreTabla


( NombreColumna TipoDato [Restriccion1 ]
[ , NombreColumna TipoDato [Restriccion1..... ]
[Restriccion2 [ , Restrccion2....] );

Notación: los diferentes formatos de definición de restricciones, restricción1 y restricción2,


están entre corchetes porque son opcionales, pudiéndose elegir entre ambos sólo si la
restricción afecta a una sola columna.

Vamos a crear la tabla socios y prestamos con el formato completo. Algunas CONSTRAINTS
las creamos a nivle de columna y otras de tabla:

mysql> CREATE TABLE socios


-> (socio_no INT(4),
-> apellidos VARCHAR(14),
-> telefono CHAR(9) NOT NULL,
-> fecha_alta DATE DEFAULT '2000-01-01',
-> direccion VARCHAR(20),

Página: 43
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

-> codigo_postal INT(5),


-> CONSTRAINT PK_DEPARTAMENTOS PRIMARY KEY(socio_no),
-> CONSTRAINT UQ_UNIQUE UNIQUE(apellidos),
-> CONSTRAINT CK_CODIGO
-> CHECK (codigo_postal BETWEEN 28000 AND
28999) );
Query OK, 0 rows affected (0.53 sec)

mysql> CREATE TABLE prestamos


-> (num_prestamo INT(2) PRIMARY KEY,
-> socio_no INT(4) ,
-> CONSTRAINT FK_SOCIO_PRESTAMOS FOREIGN KEY (socio_no)
-> REFERENCES socios(socio_no) );
Query OK, 0 rows affected (0.17 sec)

Utilizaremos estas tablas en el tema siguiente para realizar inserciones, modificaciones y


borrados de filas.

Página: 44
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

3 - Modificación de la definición de una tabla.


Una vez que hemos creado una tabla, a menudo se presenta la necesidad de tener que modificarla.
La sentencia SQL que realiza esta función es ALTER TABLE.

3.1 - Formato general para la modificación de tablas


La especificación de la modificación es parecida a la de la sentencia CREATE pero varía según el
objeto SQL del que se trate.

ALTER TABLE NombreTabla


EspecificacionModificacion [ , EspecificacionModificacion..... ]

donde NombreTabla............................... nombre de la tabla se desea modificar.


EspecificacionModificacion...... las modificaciones que se quieren realizarse sobre la tabla

Las modificaciones que se pueden realizar sobre una tabla son:


• Añadir una nueva columna
• Añadir un nueva restricción
• Borrar una columna
• Borrar una restricción
• Modificar una columna sin cambiar su nombre
• Modificar una columna y cambiar su nombre
• Renombrar la tabla

a) AÑADIR UNA NUEVA COLUMNA

ADD [COLUMN] NombreColumna TipoDato [ Restriccion1 ]

Puede añadirse una nueva columna y todas las restricciones, salvo NOT NULL. La razón es que esta
nueva columna tendrá los valores NULL al ser creada.

b) AÑADIR UNA CONSTRAINT

ADD [CONSTRAINT [NombreConstraint] ]


PRIMARY KEY ( NombreColumna [, NombreColumna...] )
ADD [CONSTRAINT [NombreConstraint] ]
FOREIGN KEY ( NombreColumna [, NombreColumna...] )
REFERENCES NombreTabla[( NombreColumna[,NombreColumna...] )]
ADD [CONSTRAINT [NombreConstraint] ]
UNIQUE ( NombreColumna [, NombreColumna... ] )

c) BORRAR UNA COLUMNA


DROP [COLUMN] NombreColumna

d) BORRAR UNA CONSTRAINT


DROP PRIMARY KEY

Página: 45
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

DROP FOREIGN KEY NombreConstraint

e) MODIFICAR UNA COLUMNA SIN CAMBIAR SU NOMBRE


MODIFY [COLUMN] NombreColumna TipoDato [Restriccion1]

f) MODIFICAR LA DEFINCION DE UNA COLUMNA Y SU NOMBRE


CHANGE [COLUMN] NombreColumnaAntiguo
NombreColumnaNuevo TipoDatos [Restriccion1]

f) RENOMBRAR LA TABLA
RENAME [TO] NombreTablaNuevo

3.2 – Ejemplos de modificaciones de tablas


a) Ejemplo de añadir una columna
Añadir la columna para la dirección de correo electrónico, direccion_correo_2c, a la tabla de
socios_2c con un tipo de dato alfanumérico de 20 caracteres.

mysql> ALTER TABLE socios_2c ADD (direccion_correo_e varchar(9));


Query OK, 0 rows affected (0.23 sec)
Records: 0 Duplicates: 0 Warnings: 0

b) Ejemplo de añadir una restriccion


Añadir en la tabla socios_2c la restricción UNIQUE para la columna telefono.

mysql> ALTER TABLE socios_2c


-> ADD CONSTRAINT uq_socios_telefono UNIQUE(telefono);
Query OK, 0 rows affected (0.13 sec)
Records: 0 Duplicates: 0 Warnings: 0

c) Ejemplo de borrar una columna


Borrar la columna fecha_alta de la tabla socios_a

mysql> ALTER TABLE socios_1a


-> DROP COLUMN fecha_alta;
Query OK, 0 rows affected (0.32 sec)
Records: 0 Duplicates: 0 Warnings: 0

d) Ejemplos de borrado de restricciones


Borrar la clave primaria de la tabla socios_1a

mysql> ALTER TABLE socios_1a


-> DROP PRIMARY KEY;
Query OK, 0 rows affected (0.66 sec)
Records: 0 Duplicates: 0 Warnings: 0

Página: 46
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

e) Ejemplos de modificación de una columna


Modificar la tabla socios_1a para poner NOT NULL en la columna apellidos.

mysql> ALTER TABLE socios_1a


-> MODIFY apellidos VARCHAR(14) NOT NULL;
Query OK, 0 rows affected (0.59 sec)
Records: 0 Duplicates: 0 Warnings: 0

f) Ejemplo de cambio de definición de una columna


Modificar la tabla socios_1a cambiándole el nombre a la columna apellidos por apellidos_a e
incrementar de 14 a 20 caracteres el tamaño.

mysql> ALTER TABLE socios_1a


-> CHANGE apellidos apellidos_a VARCHAR(20);
Query OK, 0 rows affected (0.36 sec)
Records: 0 Duplicates: 0 Warnings: 0

f) Renombrar una tabla


Cambiar el nombre de la tabla socios_1a por socios1a

mysql> ALTER TABLE socios_1a


-> RENAME TO socios1a;
Query OK, 0 rows affected (0.09 sec)

mysql> SELECT * FROM socios_1a;


ERROR 1146 (42S02): Table 'test.socios_1a' doesn't exist

Página: 47
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

4 - Eliminación de una tabla.


Para borrar una tabla y su contenido de la base de datos se utiliza la sentencia DROP TABLE.

4.1 - Formato para eliminar una tabla.

DROP TABLE [ IF EXISTS ] NombreTabla


[CASCADE | RESTRICT] ;

La cláusula IF EXISTS previene los errores que puedan producirse si no existe la tabla que
queremos borrar.
Nota: las cláusulas CASCADE Y RESTRICT para borrado en cascada y borrado de las restricciones
están permitidas pero no implementadas en esta versión.

4.2 – Ejemplos de borrado de una tabla


1- Borraremos las tablas departamentos2 y empleados2 enlazadas con una clave ajena.
Hay que tener cuidado con el orden:

mysql> DROP TABLE departamentos2;


ERROR 1217 (23000): Cannot delete or update a parent row: a
foreign key constraint fails

Debemos borrar primero empleados2:

mysql> DROP TABLE empleados2;


Query OK, 0 rows affected (0.10 sec)
mysql> DROP TABLE departamentos2;
Query OK, 0 rows affected (0.06 sec)

2 - Borraremos una tabla empleados7, que no existe, con la cláusula IF EXISTS y vemos
que no nos da error.

mysql> DROP TABLE IF EXISTS empleados7;


Query OK, 0 rows affected, 1 warning (0.00 sec)

Página: 48
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

5 – Renombrado de una tabla


Permite cambiar de nombre una tabla, asignándole un nombre nuevo y el nombre antiguo
desaparece.

5.1 - Formato para renombrar una tabla

RENAME TABLE NombreTablaAntiguo TO NombreTablaNuevo


[, NombreTablaAntiguo TO NombreTablaNuevo .....]

Notación: se pueden renombrar varias tablas en una sentencia por eso van entre
corchetes las siguientes tablas a renombrar.

donde NombreTablaAntiguo ..... es el nombre antiguo de la tabla, que debe existir


NombreTablaNuevo......... es el nombre nuevo de la tabla, que no debe existir.

Permite renombrar en la misma instrucción una o varias tablas.

5.2 – Ejemplos de renombrado de una tabla


1- Renombrar la tabla socios para que su nuevo nombre sea socios2

mysql> RENAME TABLE socios TO socios2;


Query OK, 0 rows affected (0.05 sec)

mysql> select * from socios;


ERROR 1146 (42S02): Table 'test.socios' doesn't exist

Página: 49
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

TEMA 4. ACTUALIZACION DE TABLAS

Paulina Barthelemy

1 - Introducción
Como ya hemos explicado el lenguaje SQL incluye un conjunto de sentencias que permiten modificar,
borrar e insertar nuevas filas en una tabla. Este subconjunto de comandos del lenguaje SQL recibe la
denominación de Lenguaje de Manipulación de Datos (DML)

Las órdenes que no permiten actualizar los valores de las tablas son:
• INSERT para la inserción de filas
• UPDATE para la modificación de filas
• DELETE para el borrado de filas.

2 - Inserción de nuevas filas en la base de datos

Para añadir nuevas filas a una tabla utilizaremos la sentencia INSERT.

2.1 – Formato de la inserción una fila

La sentencia para inserción de filas es INSERT cuyo formato típico es:

INSERT INTO NombreTabla [( NombreColumna [,NombreColumna...] ) ]


VALUES (Expresion [, Expresión ...] );

Notación: la lista de columnas en las que insertamos va es opcional, por lo que va entre
corchetes. Si no se especifica se esperan valores para todas las columnas.

Donde NombreTabla................ es el nombre de la tabla en la que queremos insertar una fila.


NombreColumna......... incluye las columnas en las que queremos insertar.
Expresion..................... indica las expresiones cuyos valores resultado se insertarán,
existiendo una correspondencia con la lista de columnas anterior

Como se ve en el formato también se pueden insertar filas en una tabla sin especificar la lista de
columnas pero en este caso la lista de valores a insertar deberá coincidir en número y posición con las

Página: 50
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

columnas de la tabla. El orden establecido para las columnas será el indicado al crear la tabla (el
mismo que aparece al hacer una descripción de la tabla DESC NombreTabla).

2.2 – Ejemplos de inserción de filas


Por ejemplo, para insertar una nueva fila en la tabla departamentos introduciremos la siguiente
instrucción:

mysql> INSERT INTO departamentos(dep_no, dnombre, localidad)


-> VALUES (50, 'MARKETING','BILBAO');
Query OK, 1 row affected (0.08 sec)

mysql> select * from departamentos;


+--------+---------------+-----------+
| DEP_NO | DNOMBRE | LOCALIDAD |
+--------+---------------+-----------+
| 10 | CONTABILIDAD | BARCELONA |
| 20 | INVESTIGACION | VALENCIA |
| 30 | VENTAS | MADRID |
| 40 | PRODUCCION | SEVILLA |
| 50 | MARKETING | BILBAO |
+--------+---------------+-----------+
5 rows in set (0.00 sec)

Este formato de inserción tiene, además, las siguientes características:

• En la lista de columnas se pueden indicar todas o algunas de las columnas de la tabla.


En este último caso, aquellas columnas que no se incluyan en la lista quedarán sin ningún
valor en la fila insertada, es decir, se asumirá el valor NULL o el valor por defecto para las
columnas que no figuren en la lista. En aso de una columna definida como NOT NULL
tomará el valor 0 si es numérica o blancos sino.
• Los valores incluidos en la lista de valores deberán corresponderse posicionalmente con las
columnas indicadas en la lista de columnas, de forma que el primer valor de la lista de
valores se incluirá en la columna indicada en primer lugar, el segundo en la segunda
columna, y así sucesivamente.
• Se puede utilizar cualquier expresión para indicar un valor siempre que el resultado de la
expresión sea compatible con el tipo de dato de la columna correspondiente.

Algunos ejemplos de inserciones válidas son:


1- Inserción de un socio con socio_no=1000

mysql> INSERT INTO Socios


(socio_no,apellidos,telefono,fecha_alta,direccion,codigo_postal)
-> VALUES ( 1000,'LOPEZ SANTOS','916543267', '2005-01-08',
-> 'C. REAL 5',28400);
Query OK, 1 row affected (0.05 sec)

2 - Inserción de un socio con socio_no=1001

mysql> INSERT INTO Socios


(socio_no,apellidos,telefono,fecha_alta,direccion,codigo_postal)

Página: 51
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

-> VALUES ( 1001,'PEREZ CERRO','918451256', '2005-01-12',


-> 'C. MAYOR 31',28400);
Query OK, 1 row affected (0.06 sec)

3 - Inserción de un socio con socio_no=1002

mysql> INSERT INTO Socios


(socio_no,apellidos,telefono,fecha_alta,direccion,codigo_postal)
-> VALUES ( 1002,'LOPEZ PEREZ','916543267', '2005-01-18',
-> 'C. REAL 5',28400);
Query OK, 1 row affected (0.06 sec)

4 - Inserción de un socio con socio_no=1003 sin valor en teléfono (como es un campo NOT NULL
en lugar de nulos pondrá blancos)

mysql> INSERT INTO socios


-> (socio_no,apellidos,fecha_alta,direccion,codigo_postal)
-> VALUES ( 1003,'ROMA LEIVA', '2005-01-21',
-> 'C. PANADEROS 9 ',28431);
Query OK, 1 row affected (0.06 sec)

5- Inserción de un préstamo para el socio con socio_no=1000

mysql> INSERT INTO prestamos


-> (num_prestamo, socio_no)
-> VALUES ( 1,1000);
Query OK, 1 row affected (0.05 sec)

6 - Inserción de un préstamo para el socio con socio_no=1002

mysql> INSERT INTO prestamos


-> (num_prestamo, socio_no)
-> VALUES ( 2,1002);
Query OK, 1 row affected (0.07 sec)

7 - Inserción de un socio con socio_no=1004, con una instrucción INSERT sin lista de columnas:

mysql> INSERT INTO socios


-> VALUES ( 1004,'GOMEZ DURUELO','918654329', '2005-01-31',
-> 'C. REAL 15',28400);
Query OK, 1 row affected (0.43 sec)

8 - Inserción de un socio con socio_no=1005, con una instrucción INSERT sin valor en el campo
fecha que tiene un valor por defecto (pondrá ese valor 2000-01-01)

mysql> INSERT INTO socios


-> (socio_no,apellidos,telefono,direccion,codigo_postal)
-> VALUES ( 1005,'PEÑA MAYOR','918515256','C. LARGA 31',
-> 28431);
Query OK, 1 row affected (0.07 sec)

Página: 52
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

9 - Inserción de un socio con socio_no=1004, con una instrucción INSERT sin lista de columnas:

mysql> INSERT INTO prestamos


-> VALUES ( 4,1004);
Query OK, 1 row affected (0.40 sec)

Algunos intentos de inserciones erróneas:


1 – Inserción en la tabla socios en la que falta un valor para la columna dirección:

mysql> INSERT INTO Socios


-> (socio_no,apellidos,telefono,fecha_alta,direccion)
-> VALUES ( 1005,'LOPEZ SANTOS','916543267', '2005-01-08',
-> 'C. REAL 5',28400);
ERROR 1136(21S01):Column count doesn't match value count at row 1

2 – Inserción en la tabla socios de una columna con clave primaria duplicada:

mysql> INSERT INTO Socios


(socio_no,apellidos,telefono,fecha_alta,direccion,codigo_postal)
-> VALUES ( 1000,'LOPEZ SANTOS','916543267', '2005-01-08',
-> 'C. REAL 5',28400);
ERROR 1062 (23000): Duplicate entry '1000' for key 1

3 - Inserción en la tabla socios de una fila con valores duplicados en la columna apellidos:

mysql> INSERT INTO Socios


(socio_no,apellidos,telefono,fecha_alta,direccion,codigo_postal)
-> VALUES ( 1009,'LOPEZ SANTOS','916543267', '2005-01-18',
-> 'C. REAL 5',28400);
ERROR 1062 (23000): Duplicate entry 'LOPEZ SANTOS' for key 2

4 - Inserción de una fila en la tabla prestamos con un valor en la columna socios_no que no
existe en la tabla socios

mysql> INSERT INTO prestamos


-> (num_prestamo, socio_no)
-> VALUES ( 3,1009);
ERROR 1216 (23000): Cannot add or update a child row: a foreign key
constraint fails

Comprobación de los valores insertados:

mysql> SELECT *
-> FROM socios;
+----------+---------------+-----------+------------+----------------+---------------+
| socio_no | apellidos | telefono | fecha_alta | direccion | codigo_postal |
+----------+---------------+-----------+------------+----------------+---------------+
| 1000 | LOPEZ SANTOS | 916543267 | 2005-01-08 | C. REAL 5 | 28400 |
| 1001 | PEREZ CERRO | 918451256 | 2005-01-12 | C. MAYOR 31 | 28400 |
| 1002 | LOPEZ PEREZ | 916543267 | 2005-01-18 | C. REAL 5 | 28400 |
| 1003 | ROMA LEIVA | | 2005-01-21 | C. PANADEROS 9 | 28431 |
| 1004 | GOMEZ DURUELO | 918654329 | 2005-01-31 | C. REAL 15 | 28400 |
| 1005 | PEÑA MAYOR | 918515256 | 2000-01-01 | C. LARGA 31 | 28431 |
+----------+---------------+-----------+------------+----------------+---------------+

Página: 53
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

6 rows in set (0.00 sec)

SELECT *
FROM prestamos;

mysql> SELECT *
-> FROM prestamos;
+--------------+----------+
| num_prestamo | socio_no |
+--------------+----------+
| 1 | 1000 |
| 2 | 1002 |
| 4 | 1004 |
+--------------+----------+
3 rows in set (0.00 sec)

Ejemplo de inserción con un campo autonumérico, de paso creamos una tabla con una columna
autonumérica.

mysql> CREATE TABLE inventario


-> (num INT(2) AUTO_INCREMENT PRIMARY KEY,
-> descripcion VARCHAR(15));
Query OK, 0 rows affected (0.49 sec)

1 – Inserción sin enumerar la columna autonumérica

mysql> INSERT INTO inventario (descripcion)


-> VALUES ('ARMARIO BLANCO');
Query OK, 1 row affected (0.42 sec)

mysql> INSERT INTO inventario (descripcion)


-> VALUES ('MESA MADERA');
Query OK, 1 row affected (0.05 sec)

2 – Inserción de toda la fila ( en este caso debe ponerse NULL en la columna correspondiente)

mysql> INSERT INTO inventario


-> VALUES (NULL,'ORDENADOR');
Query OK, 1 row affected (0.07 sec)

mysql> INSERT INTO inventario


-> VALUES (NULL,'SILLA GIRATORIA');
Query OK, 1 row affected (0.06 sec)

Comprobación de los valores insertados:

mysql> SELECT *
-> FROM inventario;
+-----+-----------------+
| num | descripcion |

Página: 54
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

+-----+-----------------+
| 1 | ARMARIO BLANCO |
| 2 | MESA MADERA |
| 3 | ORDENADOR |
| 4 | SILLA GIRATORIA |
+-----+-----------------+
4 rows in set (0.00 sec)

Página: 55
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

3 - Modificación de filas.
En ocasiones necesitaremos modificar alguno de los datos de las filas existentes de una tabla. Por
ejemplo, cambiar el salario o el departamento de uno o varios empleados, etcétera. En estos casos
utilizaremos la sentencia UPDATE.

3.1 – Formato de la modificación de filas


La sentencia de modificación de filas es UPDATE cuyo formato genérico es el siguiente:

UPDATE NombreTabla
SET NombreColumna = Expresion [, NombreColumna = Expresion....]
[WHERE Condición];

Notación: puede actualizarse una o varias columnas, por lo que la segunda actualización va
entre corchetes La cláusula WHERE aparece entre corchetes porque es opcional. En el caso
de que no se utilice, la actualización afectará a toda la tabla.

Donde NombreTabla……..… indica la tabla destino donde se encuentran las filas que queremos
borrar.
NombreColumna……..... indica el nombre de la columna cuyo valor queremos modificar
Expresión……………… es una expresión cuyo valor resultado será el nuevo valor de la
columna
Condición……………… es la condición que deben cumplir las filas para que les afecte la
modificación.

Recordamos que una expresión es un conjunto de datos, constantes y variables, operadores y


funciones. Y una condición es una expresión cuyo resultado es verdadero/falso/nulo
Para aquellas filas en las que al evaluar la condición el resultado es verdadero se modificará el
valor de la columna poniendo como nuevo valor el resultado de evaluar la expresión.
Si se quiere modificar más de una columna de la misma tabla se indicarán separadas por comas.

3.2 – Ejemplos de modificación de filas


Partimos de la tabla socios

mysql> SELECT * FROM socios;


+----------+---------------+-----------+------------+----------------+---------------+
| socio_no | apellidos | telefono | fecha_alta | direccion | codigo_postal |
+----------+---------------+-----------+------------+----------------+---------------+
| 1000 | LOPEZ SANTOS | 916543267 | 2005-01-08 | C. REAL 5 | 28400 |
| 1001 | PEREZ CERRO | 918451256 | 2005-01-12 | C. MAYOR 31 | 28400 |
| 1002 | LOPEZ PEREZ | 916543267 | 2005-01-18 | C. REAL 5 | 28400 |
| 1003 | ROMA LEIVA | | 2005-01-21 | C. PANADEROS 9 | 28431 |
| 1004 | GOMEZ DURUELO | 918654329 | 2005-01-31 | C. REAL 15 | 28400 |
| 1005 | PEÑA MAYOR | 918515256 | 2000-01-01 | C. LARGA 31 | 28431 |
+----------+---------------+-----------+------------+----------------+---------------+
6 rows in set (0.01 sec)

1 - Supongamos que se desea cambiar la dirección del socio de número 1000 y la nueva dirección es :

Página: 56
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

'C.CUESTA 2'.

mysql> UPDATE socios


-> SET direccion = 'C.CUESTA 2'
-> WHERE socio_no = 1000;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1 Changed: 1 Warnings: 0

2 - Supongamos que se desea cambiar el teléfono del socio de número 1000 y el nuevo teléfono es
918455431

mysql> UPDATE socios


-> SET telefono = '918455431'
-> WHERE socio_no = 1000;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0

También podíamos haber modificado las dos columnas con una sola sentencia:

mysql> UPDATE socios


-> SET telefono = '918455431',direccion='C.CUESTA 2'
-> WHERE socio_no = 1000;
Query OK, 0 rows affected (0.08 sec)
Rows matched: 1 Changed: 1 Warnings: 0

Las actualizaciones anteriores afectan a una única fila pero podemos escribir comandos de
actualización que afecten a varias filas:

mysql> UPDATE socios


-> SET codigo_postal = 28401
-> WHERE codigo_postal = 28400;
Query OK, 4 rows affected (0.07 sec)
Rows matched: 4 Changed: 4 Warnings: 0

Si no se incluye la cláusula WHERE la actualización afectará a todas las filas. El siguiente ejemplo
modifica la fecha de alta de todos los empleados al valor 1 de enero de 2005.

mysql> UPDATE socios


-> SET fecha_alta = '2005-01-01';
Query OK, 6 rows affected (0.06 sec)
Rows matched: 6 Changed: 6 Warnings: 0

Podemos comprobar las modificaciones:


mysql> SELECT *
-> FROM socios;
+----------+---------------+-----------+------------+----------------+---------------+
| socio_no | apellidos | telefono | fecha_alta | direccion | codigo_postal |
+----------+---------------+-----------+------------+----------------+---------------+
| 1000 | LOPEZ SANTOS | 918455431 | 2005-01-01 | C.CUESTA 2 | 28401 |
| 1001 | PEREZ CERRO | 918451256 | 2005-01-01 | C. MAYOR 31 | 28401 |
| 1002 | LOPEZ PEREZ | 916543267 | 2005-01-01 | C. REAL 5 | 28401 |
| 1003 | ROMA LEIVA | | 2005-01-01 | C. PANADEROS 9 | 28431 |
| 1004 | GOMEZ DURUELO | 918654329 | 2005-01-01 | C. REAL 15 | 28401 |
| 1005 | PEÑA MAYOR | 918515256 | 2005-01-01 | C. LARGA 31 | 28431 |
+----------+---------------+-----------+------------+----------------+---------------+
6 rows in set (0.00 sec)

Página: 57
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
c

4 - Eliminación de filas.

La sentencia DELETE es la que nos permite eliminar una o más filas de una tabla.

4.1 – Formato de la eliminación de filas

Para eliminar o suprimir filas de una tabla utilizaremos la sentencia DELETE. Su formato genérico es el
siguiente:

DELETE FROM NombreTabla


[WHERE Condicion];

Notación: la cláusula WHERE es opcional por eso aparece entre corchetes. Si no se


especifica se borraran todas las filas de la tabla

donde NombreTabla............. indica la tabla destino donde se encuentran las filas que
queremos borrar
Condición................... es la condición que deben cumplir las filas a borrar

4.2 – Ejemplos de la eliminación de filas


A continuación se muestran algunos ejemplos de instrucciones DELETE

mysql> DELETE
-> FROM socios
-> WHERE socio_no = 1001;
Query OK, 1 row affected (0.08 sec)

Hay que tener cuidado con las claves ajenas. Como prestamos tiene una clave ajena que
referencia a socios si pretendemos borrar un socio que tiene préstamos nos encontraremos con
un error.

mysql> DELETE
-> FROM socios
-> WHERE socio_no = 1002;
ERROR 1217 (23000): Cannot delete or update a parent row: a
foreign key constraint fails

Podemos comprobar las modificaciones:

mysql> SELECT *
-> FROM socios;
+----------+---------------+-----------+------------+----------------+---------------+
| socio_no | apellidos | telefono | fecha_alta | direccion | codigo_postal |
+----------+---------------+-----------+------------+----------------+---------------+
| 1000 | LOPEZ SANTOS | 918455431 | 2005-01-01 | C.CUESTA 2 | 28401 |

Página: 58
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

| 1002 | LOPEZ PEREZ | 916543267 | 2005-01-01 | C. REAL 5 | 28401 |


| 1003 | ROMA LEIVA | | 2005-01-01 | C. PANADEROS 9 | 28431 |
| 1004 | GOMEZ DURUELO | 918654329 | 2005-01-01 | C. REAL 15 | 28401 |
| 1005 | PEÑA MAYOR | 918515256 | 2005-01-01 | C. LARGA 31 | 28431 |
+----------+---------------+-----------+------------+----------------+---------------+
6 rows in set (0.00 sec)

Página: 59
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

5 - Restricciones de integridad y actualizaciones.


Como ya hemos vistos los gestores de bases de datos relacionales permiten especificar ciertas
condiciones que deban cumplir los datos contenidos en las tablas, como por ejemplo:
• Restricción de clave primaria (PRIMARY KEY) : columnas que identifican cada fila
• Restricción de clave ajena (FOREIGN KEY): columnas que hacen referencia a otras de la
misma o de otras tablas
• Restricción de comprobación de valores (CHECK): conjunto de valores que puede o debe
tomar una columna.
• Restricción de no nulo (NOT NULL): columnas que tienen que tener necesariamente un valor
no nulo.
• Restricción de unicidad (UNIQUE): columnas que no pueden tener valores duplicados.

5.1 - Control de las restricciones de integridad referencial


Estas restricciones dan lugar a que no podamos hacer cualquier modificación en los datos de las tablas.
No nos estará permitido hacer inserciones ni modificaciones con valores no permitidos en las columnas
ni borrar filas a las que referencien otras filas de la misma o de otra tabla

En nuestras tablas de ejemplo están definidas las siguientes restricciones:


a) Claves primarias (PRIMARY KEY). Sirven para referirse a una fila de manera inequívoca. No se
permiten valores repetidos.
TABLA DEPARTAMENTOS: PRIMARY KEY (DEP_NO)
TABLA EMPLEADOS: PRIMARY KEY (EMP_NO)
TABLA CLIENTES: PRIMARY KEY(CLIENTE_NO)
TABLA PRODUCTOS: PRIMARY KEY (PRODUCTO_NO)
TABLA PEDIDOS: PRIMARY KEY (PEDIDO_NO)

Como ya hemos visto no podemos hacer inserciones con valores repetidos de las claves
primarias.

b) Claves ajenas (FOREIGN KEY): Se utilizan para hacer referencia a columnas de otras tablas.
Cualquier valor que se inserte en esas columnas tendrá su equivalente en la tabla referida.
Opcionalmente se pueden indicar las acciones a realizar en caso de borrado o cambio de las
columnas a las que hace referencia .

TABLA EMPLEADOS: FOREIGN KEY (DEP_NO)


REFERENCES DEPARTAMENTOS(DEP NO)
TABLA CLIENTES: FOREIGN KEY (VENDEDOR_NO)
REFERENCES EMPLEADOS(EMP_NO)
TABLA PEDIDOS: FOREIGN KEY (PRODUCTO_NO)
REFERENCES PRODUCTOS(PRODUCTO NO)
TABLA PEDIDOS: FOREIGN KEY (CLIENTE_NO)
REFERENCES CLIENTES(CLIENTE NO)

Las claves ajenas sirven para relacionar dos tablas entre sí y limitan los valores que puede tomar
esa columna a los valores existentes en ese momento en la columna a la que referencian,
pudiendo tomar valores existentes en esa columna o nulos.

Página: 60
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

• Esto nos limita los valores de las claves ajenas no podrán tomar valores que no
existan en las columnas referenciadas
• Los valores de las claves primarias no podrán actualizarse si existen filas que los
referencian.

Lo vemos con un ejemplo:


La tabla EMPLEADOS tiene una clave ajena DEP_NO que referencia la clave primaria DEP_NO
de la tabla DEPARTAMENTOS.
Si existe un departamento con dep_no = 20 y existen filas de empleados con este valor de
dep_no
1. No podremos borrar ni modificar el valor de dep_no = 20 de la tabla DEPARTAMENTOS
2. No podremos modificar el valor del campo dep_no de la tabla EMPLEADOS a un valor
que no exista en la tala DEPARTAMENTOS.

Estas condiciones se determinaron al diseñar la base de datos y se especificaron e implementaron


mediante el lenguaje de definición de datos (DDL). Por lo tanto, todos los comandos de manipulación
de datos deberán respetar estas restricciones de integridad ya que en caso contrario el comando fallará
y el sistema devolverá un error.

5.2 - Ejemplos de borrados y modificaciones en cascada


Vamos a ver con un ejemplo como funciona el borrado en cascada.
Creamos las tablas departamentos2 y empleados2 con una clave ajena con borrado en
cascada e insertamos los valores desde las tablas departamentos y empleados

mysql> CREATE TABLE departamentos2


-> (dep_no INT(4),
-> dnombre VARCHAR(14),
-> localidad VARCHAR(10),
-> CONSTRAINT PK2_DEP PRIMARY KEY (DEP_NO)
-> );
Query OK, 0 rows affected (0.09 sec)

mysql> INSERT INTO departamentos2


-> SELECT dep_no, dnombre, localidad
-> FROM departamentos;
Query OK, 4 rows affected (0.03 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> CREATE TABLE empleados2


-> (emp_no INT(4),
-> apellido VARCHAR(8),
-> oficio VARCHAR(15),
-> director INT(4),
-> fecha_alta DATE,
-> dep_no INT (2),
-> CONSTRAINT PK_EMPLEADOS_EMP_NO2 PRIMARY KEY (emp_no),
-> CONSTRAINT FK_EMP_DEP_NO2 FOREIGN KEY (dep_no)
-> REFERENCES departamentos2(dep_no) ON DELETE CASCADE
-> );
Query OK, 0 rows affected (0.06 sec)

mysql> INSERT INTO empleados2

Página: 61
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

-> SELECT emp_no, apellido, oficio, director,


-> fecha_alta, dep_no
-> FROM empleados;
Query OK, 9 rows affected (0.03 sec)
Records: 9 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM departamentos2;


+--------+---------------+-----------+
| dep_no | dnombre | localidad |
+--------+---------------+-----------+
| 10 | CONTABILIDAD | BARCELONA |
| 20 | INVESTIGACION | VALENCIA |
| 30 | VENTAS | MADRID |
| 40 | PRODUCCION | SEVILLA |
+--------+---------------+-----------+
4 rows in set (0.00 sec)

SELECT * FROM empleados2;

mysql> SELECT * FROM empleados2;


+--------+----------+------------+----------+------------+--------+
| emp_no | apellido | oficio | director | fecha_alta | dep_no |
+--------+----------+------------+----------+------------+--------+
| 7499 | ALONSO | VENDEDOR | 7698 | 1981-02-23 | 30 |
| 7521 | LOPEZ | EMPLEADO | 7782 | 1981-05-08 | 10 |
| 7654 | MARTIN | VENDEDOR | 7698 | 1981-09-28 | 30 |
| 7698 | GARRIDO | DIRECTOR | 7839 | 1981-05-01 | 30 |
| 7782 | MARTINEZ | DIRECTOR | 7839 | 1981-06-09 | 10 |
| 7839 | REY | PRESIDENTE | NULL | 1981-11-17 | 10 |
| 7844 | CALVO | VENDEDOR | 7698 | 1981-09-08 | 30 |
| 7876 | GIL | ANALISTA | 7782 | 1982-05-06 | 20 |
| 7900 | JIMENEZ | EMPLEADO | 7782 | 1983-03-24 | 20 |
+--------+----------+------------+----------+------------+--------+
9 rows in set (0.00 sec)

Ahora vamos a borrar una fila en la tabla departamentos. Si no existiese borrado en cascada,
debido a la integridad referencial, no podríamos borrar ningún departamento que tuviese
empleados. De esta forma al borrar un departamento se borrarán todos los empleados de ese
departamento.

mysql> DELETE FROM departamentos2


-> WHERE dep_no=10;
Query OK, 1 row affected (0.05 sec)

SELECT * FROM departamentos2;

mysql> SELECT * FROM departamentos2;


+--------+---------------+-----------+
| dep_no | dnombre | localidad |
+--------+---------------+-----------+
| 20 | INVESTIGACION | VALENCIA |
| 30 | VENTAS | MADRID |
| 40 | PRODUCCION | SEVILLA |
+--------+---------------+-----------+
3 rows in set (0.00 sec)

Página: 62
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

SELECT * FROM empleados2;

mysql> SELECT * FROM empleados2;


+--------+----------+----------+----------+------------+--------+
| emp_no | apellido | oficio | director | fecha_alta | dep_no |
+--------+----------+----------+----------+------------+--------+
| 7499 | ALONSO | VENDEDOR | 7698 | 1981-02-23 | 30 |
| 7654 | MARTIN | VENDEDOR | 7698 | 1981-09-28 | 30 |
| 7698 | GARRIDO | DIRECTOR | 7839 | 1981-05-01 | 30 |
| 7844 | CALVO | VENDEDOR | 7698 | 1981-09-08 | 30 |
| 7876 | GIL | ANALISTA | 7782 | 1982-05-06 | 20 |
| 7900 | JIMENEZ | EMPLEADO | 7782 | 1983-03-24 | 20 |
+--------+----------+----------+----------+------------+--------+
6 rows in set (0.00 sec)

Página: 63
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

6 - Control de transacciones: COMMIT y ROLLBACK.


Los gestores de bases de datos disponen de dos comandos que permiten confirmar o deshacer los
cambios realizados en la base de datos:
• COMMIT: confirma los cambios realizados haciéndolos permanentes .
• ROLLBACK: deshace los cambios realizados.

Cuando hacemos modificaciones en las tablas estas no se hacen efectivas (llevan a disco) hasta que
no ejecutamos la sentencia COMMIT. Cuando ejecutamos comandos DDL (definición de datos) se
ejecuta un COMMIT automático, o cuando cerramos la sesión.

El comando ROLLBACK no permite deshacer estos cambios sin que lleguen a validarse. Cuando
ejecutamos este comando se deshacen todos los cambios hasta el último COMMIT ejecutado.

Hay dos formas de trabajar con AUTO_COMMIT activado (validación automática de los cambios) o
desactivado. Si está activado se hace COMMIT automáticamente cada sentencia y no es posible
hacer ROLLBACK. Si no lo está, tenemos la posibilidad de hacer ROLLBACK después de las
sentencias DML (INSERT, UPDATE, DELETE) dejando sin validar los cambios. Es útil para hacer
pruebas.

Existe una variable, AUTO_COMMIT, que indica la forma de trabajo y tiene el valor 1 si está en modo
AUTO_COMMIT y 0 si no lo está. Por defecto el MySQL está en modo AUTO_COMMIT. Su valor se
puede cambia con la sentencia:

mysql> SET AUTOCOMMIT = 0;


Query OK, 0 rows affected (0.41 sec)

Vamos a verlo con un ejemplo:

mysql> SELECT *
-> FROM inventario;
+-----+----------------+
| num | descripcion |
+-----+----------------+
| 1 | ARMARIO BLANCO |
| 2 | MESA MADERA |
| 3 | ORDENADOR |
| 4 | SILLA GIRATORIA|
+-----+----------------+
4 rows in set (0.00 sec)

mysql> SET AUTOCOMMIT = 0;


Query OK, 0 rows affected (0.41 sec)

mysql> SELECT * FROM inventario;


+-----+----------------+
| num | descripcion |
+-----+----------------+
| 1 | ARMARIO BLANCO |
| 2 | MESA MADERA |
| 3 | ORDENADOR |
| 4 | SILLA GIRATORIA|
+-----+----------------+

Página: 64
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

4 rows in set (0.00 sec)

mysql> INSERT INTO inventario


-> VALUES (NULL,'IMPRESORA');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM inventario;


+-----+----------------+
| num | descripcion |
+-----+----------------+
| 1 | ARMARIO BLANCO |
| 2 | MESA MADERA |
| 3 | ORDENADOR |
| 4 | SILLA GIRATORIA|
| 5 | IMPRSORA |
+-----+----------------+
4 rows in set (0.00 sec)

mysql> ROLLBACK;
Query OK, 0 rows affected (0.09 sec)

mysql> SELECT * FROM inventario;


+-----+----------------+
| num | descripcion |
+-----+----------------+
| 1 | ARMARIO BLANCO |
| 2 | MESA MADERA |
| 3 | ORDENADOR |
| 4 | SILLA GIRATORIA|
+-----+----------------+
4 rows in set (0.00 sec)

Para hacer los ejercicios y los ejemplos puede ser interesante modificar esta variable y así disponer
de la posibilidad de hacer ROLLBACK. Cada vez que se inicie una sesión estará en modo
AUTO_COMMIT que es el valor por defecto y el ROLLBACk no será aplicable.

mysql> SET AUTOCOMMIT = 1;


Query OK, 0 rows affected (0.41 sec)

mysql> INSERT INTO inventario


-> VALUES (NULL,'ARCHIVADOR');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM inventario;


+-----+----------------+
| num | descripcion |
+-----+----------------+
| 1 | ARMARIO BLANCO |
| 2 | MESA MADERA |
| 3 | ORDENADOR |
| 4 | SILLA GIRATORIA|
| 6 | ARCHIVADOR |
+-----+----------------+

Página: 65
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos

5 rows in set (0.00 sec)

mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM inventario;


+-----+----------------+
| num | descripcion |
+-----+----------------+
| 1 | ARMARIO BLANCO |
| 2 | MESA MADERA |
| 3 | ORDENADOR |
| 4 | SILLA GIRATORIA|
| 6 | ARCHIVADOR |
+-----+----------------+
5 rows in set (0.00 sec)

Página: 66
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

PARTE II
LENGUAJE SQL. CONSULTA DE DATOS

TEMA 5. CONSULTAS SENCILLAS ......................................................................................... 3


1 - Consulta de los datos. ........................................................................................................ 3
2 – Consultas sencillas ........................................................................................................... 3
2.1 – Formato mínimo de selección..........................................................................................................................3
2.2 - Consultas de todas las filas...............................................................................................................................4
2.3 – Ejemplos de consultas sencillas.....................................................................................................................4
2.4 - Utilización de alias ...............................................................................................................................................5
2.5 – Ejemplos de utilización de alias ......................................................................................................................6
3 - Condiciones de selección. ................................................................................................. 9
3.1 – Formato de selección con consultas .............................................................................................................9
3.2 – Ejemplos de condiciones de selección .........................................................................................................9
4 – Funciones predefinidas en expresiones y condiciones................................................... 12
4.1 - Funciones numéricas o aritméticas............................................................................................................ 12
4.2 – Funciones de caracteres................................................................................................................................ 13
4.3 – Funciones de fechas........................................................................................................................................ 14
4.4 – Funciones de comparación............................................................................................................................ 16
4.5 – Otras funciones................................................................................................................................................. 17
5 - Ordenación....................................................................................................................... 18
5.1 – Formato de selección con ordenación ....................................................................................................... 18
5.2 – Ejemplos de ordenación................................................................................................................................. 18
6 - Selección con limitación de filas...................................................................................... 21
6.1 – Formato de selección con limitación de filas ........................................................................................... 21
6.2 – Ejemplos de limitación de filas ..................................................................................................................... 21
7 - Resumen (1) del formato de selección ............................................................................. 23

TEMA 6. CONSULTAS CON AGRUPAMIENTO Y FUNCIONES DE GRUPOS .......................... 24


1- Consultas de selección con agrupamientos ..................................................................... 24
1.1 – Formato de la consulta de selección con agrupamiento ................................................................ 24
1.2 – Consideraciones de consultas con cláusulas de agrupamiento......................................................... 25
2- Funciones de grupo .......................................................................................................... 26
2.1- Funciones de grupo........................................................................................................................................... 26
2. 2 – Ejemplos con funciones de grupo. ............................................................................................................. 27
3- Resumen (2) del formato de selección .............................................................................. 31

TEMA 7. SUBCONSULTAS ................................................................................................... 32


1 - ¿Qué es una subconsulta?............................................................................................... 32
1.1 - Formato de una subconsulta.......................................................................................................................... 33
2 – Subconsultas que devuelven una sola expresión ........................................................... 35
2.1 - Formato de las subconsultas que devuelven una sola expresión....................................................... 35
2.2 - Valores de retorno y condiciones de selección........................................................................................ 35
3 – Subconsultas que devuelven más de una expresión....................................................... 43
3.1 – Formato de consultas que devuelven más de una expresión.............................................................. 43
3.2 - Valores de retorno y condiciones de selección........................................................................................ 43
3.3 – Ejemplos de consultas que devuelven más de una expresión............................................................ 43
4 - Subconsultas en la selección de grupos. ......................................................................... 46
4.1 – Formato de subconsultas en la cláusula HAVING................................................................................... 46
4.2 – Ejemplos de subconsultas en la cláusula HAVING................................................................................. 46

Página: 1
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

5 - Subconsultas anidadas. ................................................................................................... 48


5.1 – Anidación de subconsultas ........................................................................................................................... 48
5.2 – Ejemplos de subconsultas anidadas .......................................................................................................... 48
6 – Subconsultas correlacionadas........................................................................................ 49
6.1 – Correlación entre consultas .......................................................................................................................... 49
6.2 – Ejemplos de subconsultas correlacionadas............................................................................................. 50

TEMA 8. CONSULTAS MULTITABLA..................................................................................... 52


1 - Multiplicaciones de tablas. ............................................................................................... 52
1.1 – Formato de la multiplicación de tablas....................................................................................................... 52
1.2 – Ejemplos de la multiplicación de tablas..................................................................................................... 53
2 - Composiciones o combinaciones simples (JOIN) ......................................................... 54
2.1 – Formato de la combinación de tablas......................................................................................................... 54
3- Composición o combinación natural................................................................................. 56
3.1 – Formato de la combinación natural de tablas .......................................................................................... 57
3.2 – Ejemplos de combinación natural de tablas............................................................................................. 57
4 - Composiciones o combinaciones basadas en desigualdad............................................. 58
4.1 – Formato de combinaciones basadas en desigualdad............................................................................ 58
4.2 – Ejemplos de combinaciones basadas en desigualdad ........................................................................... 58
5 - Composiciones o combinaciones de una tabla consigo misma...................................... 60
5.1 - Formato de una combinación de una tabla consigo misma.................................................................. 60
5.2 - Ejemplos de una combinación de una tabla consigo misma................................................................ 60
6 - Composiciones o combinaciones externas (OUTER JOIN) ..................................... 62
6.1 – Formato de combinaciones externas.......................................................................................................... 62
6.2 – Ejemplos de combinaciones externas........................................................................................................ 64
7 - Composiciones y subconsultas ....................................................................................... 66
8 - Formato completo de las consultas................................................................................. 68

TEMA 9. CONSULTAS DENTRO DE OTRAS INSTRUCCIONES .............................................. 69


1 - Creación de una tabla a partir de una selección de otra tabla.......................................... 69
1.1 – Formato para la creación de una tabla a partir de una selección de otra tabla.................................. 69
1.2 – Ejemplos de la creación de una tabla a partir de una selección de otra tabla.................................... 70
2 - Actualización de una tabla a partir de una subconsulta ................................................... 71
2.1- Inserciones con subconsultas........................................................................................................................ 71
2.2 – Modificaciones con subconsultas ............................................................................................................... 72
2.3 – Eliminaciones con subconsultas ................................................................................................................. 72
3 - Vistas ............................................................................................................................... 75
3.1 - ¿Qué son las vistas y para qué sirven?. ..................................................................................................... 75
3.2 - Creación y utilización de vistas..................................................................................................................... 75
3.3 - Eliminación de vistas........................................................................................................................................ 81

Página: 2
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

TEMA 5. CONSULTAS SENCILLAS

Paulina Barthelemy

1 - Consulta de los datos.


Realizar una consulta en SQL consiste en recuperar u obtener aquellos datos que, almacenados en filas y
columnas de una o varias tablas de una base de datos, cumplen unas determinadas especificaciones. Para
realizar cualquier consulta se utiliza la sentencia SELECT.

Las primeras consultas van a ser escritas con un formato inicial de la sentencia SELECT, que se irá
completando durante este tema y en temas siguientes.

Vamos a comenzar a utilizar las sentencias del lenguaje SQL. En cada apartado iremos escribiendo los
formatos de las sentencias con lo que hemos visto hasta ese momento.

2 – Consultas sencillas
Corresponden al formato mínimo de la instrucción de selección. Las cláusulas que aparecen en ellas,
SELECT y FROM, son obligatorias.

La consulta más sencilla consiste en recuperar una o varias columnas o expresiones relacionadas de una
tabla.

2.1 – Formato mínimo de selección


Formato inicial de la sentencia SELECT

SELECT [ALL/DISTINCT] ExpresionColumna [, ExpresionColumna....]


FROM NombreTabla;

Notación: ALL y DISTINCT aparecen entre corchetes porque son opcionales y separados por
la barra / porque hay que elegir entre ambos. La segunda Expresión de columna aparece
entre corchetes por es opcional y seguida de puntos suspensivos porque puede repetirse las
veces que se quiera.

donde ExpresionColumna... es un conjunto de nombres de columnas, literales o constantes,


operadores, funciones y paréntesis.
NombreTabla............ es el nombre de la tabla de la que queremos seleccionar filas.
ALL.......................... obtiene los valores de todos los elementos seleccionados en todas las
filas, aunque sean repetidos. Es la opción por defecto y no suele escribirse

DISTINCT................. obtiene los valores no repetidos de todos los elementos.

Página: 3
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

En caso de que queramos mostrar varias expresiones estas irán separadas por comas.

Este es el formato mínimo con las cláusulas SELECT y FROM que son siempre obligatorias. A este
formato mínimo le iremos añadiendo otras cláusulas opcionales en los siguientes apartados y
siguientes temas.

2.2 - Consultas de todas las filas


En lugar de las expresiones puede parecer el carácter * que indica que deben seleccionares todas las
columnas de la tabla. No se ha escrito para no complicar el formato inicial y hacerlo más fácil de
comprender. El formato sería:

SELECT { * | [ALL/DISTINCT] ExpresionColumna [,ExpresionColumna]....] }


FROM NombreTabla

Notación: hay que escoger obligatoriamente una de las opciones, entre las de expresiones de
columnas y el asterisco *. Por eso aparecen entre llaves y separadas por una barra vertical | las
posibles opciones.

2.3 – Ejemplos de consultas sencillas


1. Obtener todos los empleados de la tabla empleados con todos sus datos.

mysql> SELECT *
-> FROM empleados;
+--------+----------+------------+----------+------------+---------+----------+--------+
| EMP_NO | APELLIDO | OFICIO | DIRECTOR | FECHA_ALTA | SALARIO | COMISION |DEP_NO |
+--------+----------+------------+----------+------------+---------+----------+--------+
| 7499 | ALONSO | VENDEDOR | 7698 | 1981-02-23 | 1400.00 | 400.00 | 30 |
| 7521 | LOPEZ | EMPLEADO | 7782 | 1981-05-08 | 1350.50 | NULL | 10 |
| 7654 | MARTIN | VENDEDOR | 7698 | 1981-09-28 | 1500.00 | 1600.00 | 30 |
| 7698 | GARRIDO | DIRECTOR | 7839 | 1981-05-01 | 3850.12 | NULL | 30 |
| 7782 | MARTINEZ | DIRECTOR | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7839 | REY | PRESIDENTE | NULL | 1981-11-17 | 6000.00 | NULL | 10 |
| 7844 | CALVO | VENDEDOR | 7698 | 1981-09-08 | 1800.00 | 0.00 | 30 |
| 7876 | GIL | ANALISTA | 7782 | 1982-05-06 | 3350.00 | NULL | 20 |
| 7900 | JIMENEZ | EMPLEADO | 7782 | 1983-03-24 | 1400.00 | NULL | 20 |
+--------+----------+------------+----------+------------+---------+----------+--------+
9 rows in set (0.03 sec)

2. Obtener los números de empleados, los apellidos y el número de departamento de todos los empleados
de la tabla empleados.

mysql> SELECT emp_no, apellido, dep_no


-> FROM empleados;
+--------+----------+--------+
| emp_no | apellido | dep_no |
+--------+----------+--------+
| 7499 | ALONSO | 30 |
| 7521 | LOPEZ | 10 |
| 7654 | MARTIN | 30 |
| 7698 | GARRIDO | 30 |

Página: 4
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

| 7782 | MARTINEZ | 10 |
| 7839 | REY | 10 |
| 7844 | CALVO | 30 |
| 7876 | GIL | 20 |
| 7900 | JIMENEZ | 20 |
+--------+----------+--------+
9 rows in set (0.00 sec)

3. Obtener los departamentos diferentes que hay en la tabla empleados

mysql> SELECT DISTINCT dep_no


-> FROM empleados;

+--------+
| dep_no |
+--------+
| 10 |
| 20 |
| 30 |
+--------+
3 rows in set (0.00 sec)

4- Obtener los diferentes oficios que hay en cada departamento de la tabla empleados

mysql> SELECT DISTINCT oficio, dep_no


-> FROM empleados;

+------------+--------+
| oficio | dep_no |
+------------+--------+
| VENDEDOR | 30 |
| EMPLEADO | 10 |
| DIRECTOR | 30 |
| DIRECTOR | 10 |
| PRESIDENTE | 10 |
| ANALISTA | 20 |
| EMPLEADO | 20 |
+------------+--------+
7 rows in set (0.00 sec)

2.4 - Utilización de alias

SELECT [ALL/DISTINCT] ExpresionColumna [AS] AliasColumna]


[, ExpresionColumna [AS] AliasColumna].... ]
FROM NombreTabla [AliasTabla] ;

Notación: los alias de columna y de tabla aparecen entre corchetes porque son opcionales.

donde AliasTabla................ SQL permite asignar otro nombre a la misma tabla, dentro de la misma
consulta.
AliasColumna........ se escribe detrás de la expresión de columna, separado de ella al menos

Página: 5
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

por un espacio. Puede ir entre comillas dobles o sin comillas (sino lleva
espacios en blanco y sí solo es una palabra)
La cláusula AS que asigna el alias puede omitirse

Usar alias para una tabla es opcional cuando su finalidad consiste en simplificar su nombre original, y
obligatorio en consultas cuya sintaxis lo requiera (más adelante lo utilizaremos)

Usar alias para las columnas puede ser necesario porque los títulos o cabeceras que muestra la salida de
una consulta para las columnas seleccionadas, se corresponden con los nombres de las columnas de las
tablas o las expresiones y esto no siempre es muy visual. Para mejorar su legibilidad y estética se utilizan
los alias de columna. También puede ser utilizado, en algunos casos, para renombrar la columna y utilizar
este nombre posteriormente

2.5 – Ejemplos de utilización de alias


Ejemplos de alias de tabla
1 - Mostrar el apellido y la fecha de alta de todos los empleados.

mysql> SELECT apellido, fecha_alta


-> FROM empleados emp;

+----------+------------+
| apellido | fecha_alta |
+----------+------------+
| ALONSO | 1981-02-23 |
| LOPEZ | 1981-05-08 |
| MARTIN | 1981-09-28 |
| GARRIDO | 1981-05-01 |
| MARTINEZ | 1981-06-09 |
| REY | 1981-11-17 |
| CALVO | 1981-09-08 |
| GIL | 1982-05-06 |
| JIMENEZ | 1983-03-24 |
+----------+------------+
9 rows in set (0.02 sec)

Nota: de momento no podemos ver la utilidad del alias de tabla, pero más adelante veremos su necesidad.

Ejemplos de alias de columna.


1 - Obtener el salario total anual (14 pagas) de los empleados de la empresa mostrando el mensaje
Salario total
Vemos, en este ejemplo, las diferentes posibilidades para escribir el alias.
a) Con la cláusula AS

mysql> SELECT salario*14 AS Salario_total


FROM empleados;

+---------------+
| Salario_total |
+---------------+
| 18907.00 |
| 19600.00 |
| 19600.00 |
| 21000.00 |

Página: 6
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

| 25200.00 |
| 34300.00 |
| 46900.00 |
| 53901.68 |
| 84000.00 |
+---------------+
9 rows in set (0.00 sec)

b) Con comillas dobles (admite el carácter blanco en el alias)

mysql> SELECT salario*14 "Salario total"


-> FROM empleados;

+---------------+
| Salario total |
+---------------+
| 19600.00 |
| 18907.00 |
| 21000.00 |
| 53901.68 |
| 34300.00 |
| 84000.00 |
| 25200.00 |
| 46900.00 |
| 19600.00 |
+---------------+
9 rows in set (0.00 sec)

c) Con comillas simples (admite el carácter blanco en el alias )

mysql> SELECT salario*14 'Salario total'


-> FROM empleados;
+---------------+
| Salario total |
+---------------+
| 19600.00 |
| 18907.00 |
| 21000.00 |
| 53901.68 |
| 34300.00 |
| 84000.00 |
| 25200.00 |
| 46900.00 |
| 19600.00 |
+---------------+
9 rows in set (0.00 sec)

2 - Mostrar el número de empleado, el apellido y el departamento de los empleados de la empresa.

mysql> SELECT emp_no "Nº_Empleado", apellido "Apellido",


dep_no "Departamento"
-> FROM empleados;

+-------------+----------+--------------+
| Nº_Empleado | Apellido | Departamento |

Página: 7
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+-------------+----------+--------------+
| 7499 | ALONSO | 30 |
| 7521 | LOPEZ | 10 |
| 7654 | MARTIN | 30 |
| 7698 | GARRIDO | 30 |
| 7782 | MARTINEZ | 10 |
| 7839 | REY | 10 |
| 7844 | CALVO | 30 |
| 7876 | GIL | 20 |
| 7900 | JIMENEZ | 20 |
+-------------+----------+--------------+
9 rows in set (0.00 sec)

Página: 8
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

3 - Condiciones de selección.
Para seleccionar las filas de la tabla sobre las que realizar una consulta, la cláusula WHERE permite
incorporar una condición de selección a la sentencia SELECT.
Muestra todas aquellas filas para las que el resultado de evaluar la condición de selección es
VERDADERO

3.1 – Formato de selección con consultas


Formato de consulta con condición de selección

SELECT [ALL/DISTINCT] ExpresionColumna [,ExpresionColumna....]


FROM NombreTabla
[WHERE CondicionSeleccion];

Notación: la cláusula WHERE es opcional, por eso aparece toda ella entre corchetes

donde CondicionSeleccion..... es una expresión (conjunto de nombres de columnas, literales,


operadores, funciones y paréntesis) cuyo resultado es
VERDADERO/FALSO/NULO

El funcionamiento es el siguiente: para cada fila se evalúa la condición de selección y si el resultado es


VERDADERO se visualizan las expresiones indicadas.

3.2 – Ejemplos de condiciones de selección


1. Seleccionar aquellos empleados cuyo apellido empiece por 'M' y tengan un salario entre 1000 y 200
euros.

mysql> SELECT emp_no "Nº Empleado", apellido "Apellido", dep_no


“Departamento”
-> FROM empleados
-> WHERE apellido LIKE 'M%' AND salario BETWEEN 1000 AND 2000;

+-------------+----------+--------------+
| Nº Empleado | Apellido | Departamento |
+-------------+----------+--------------+
| 7654 | MARTIN | 30 |
+-------------+----------+--------------+
1 row in set (0.01 sec)

El operador LIKE usado con ‘%’ indica que puede sustituirse por cualquier grupo de caracteres

2. Seleccionar aquellos empleados cuyo apellido incluya una ‘A’ en el segundo carácter.

mysql> SELECT emp_no "Nº Empleado", apellido "Apellido", dep_no


"Departamento"

Página: 9
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

-> FROM empleados


-> WHERE (apellido LIKE '_A%') ;

+-------------+----------+--------------+
| Nº Empleado | Apellido | Departamento |
+-------------+----------+--------------+
| 7654 | MARTIN | 30 |
| 7698 | GARRIDO | 30 |
| 7782 | MARTINEZ | 10 |
| 7844 | CALVO | 30 |
+-------------+----------+--------------+
4 rows in set (0.00 sec)

El operador LIKE usado con ‘_’ indica que ocupa la posición de un carácter.

3. Seleccionar los empleados existentes en los departamentos 10 y 30.

mysql> SELECT emp_no "Nº Empleado", apellido "apellido", dep_no


"Departamento"
-> FROM empleados
-> WHERE dep_no=10 OR dep_no=30;
+-------------+----------+--------------+
| Nº Empleado | apellido | Departamento |
+-------------+----------+--------------+
| 7499 | ALONSO | 30 |
| 7521 | LOPEZ | 10 |
| 7654 | MARTIN | 30 |
| 7698 | GARRIDO | 30 |
| 7782 | MARTINEZ | 10 |
| 7839 | REY | 10 |
| 7844 | CALVO | 30 |
+-------------+----------+--------------+
7 rows in set (0.02 sec)

También puede hacerse utilizando el operador IN: El operador IN comprueba si una determinada
expresión toma alguno de los valores indicados entre paréntesis.

mysql> SELECT emp_no "Nº EMPLEADO", apellido, dep_no Departamento


-> FROM empleados
-> WHERE dep_no IN(10,30);

4. Seleccionar los empleados que tienen de oficio ANALISTA

mysql> SELECT emp_no, apellido, oficio


-> FROM empleados
-> WHERE oficio = 'ANALISTA';
+--------+----------+----------+
| emp_no | apellido | oficio |
+--------+----------+----------+
| 7876 | GIL | ANALISTA |
+--------+----------+----------+
1 row in set (0.00 sec)

Aunque el campo oficio está grabado en mayúsculas obtenemos el mismo resultado si lo escribimos
en minúsculas (MySQL no diferencia entre ambas)

Página: 10
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

mysql> SELECT emp_no, apellido, oficio


-> FROM empleados
-> WHERE oficio = 'analista';
+--------+----------+----------+
| emp_no | apellido | oficio |
+--------+----------+----------+
| 7876 | GIL | ANALISTA |
+--------+----------+----------+
1 row in set (0.00 sec)

NOTA: MySql no diferencia mayúsculas de minúsculas pero otros gestores de bases de datos sí. Por
lo que si se trabaja con otro gestor debe tenerse en cuenta esa posibilidad a la hora de escribir las
sentencias.

Página: 11
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

4 – Funciones predefinidas en expresiones y condiciones


Hemos dicho que una expresión es un conjunto de nombres de columnas, literales o constantes,
operadores, funciones y paréntesis, y una condición es una expresión cuyo resultado es
VERDADERO/FALSO/NULO. Estas expresiones y condiciones nos aparecen en diferentes cláusulas de
la sentencia select
Dentro de las expresiones y de las condiciones podemos utilizar las funciones predefinidas enumeradas
en el tema 2.
Estas funciones pueden ser utilizadas en todas las expresiones y condiciones con la única restricción
determinada por los tipos de datos con los que operan y que devuelven.

Vamos a ver algún ejemplo de cada uno de estos tipos de funciones dentro de las expresiones y las
condiciones.

4.1 - Funciones numéricas o aritméticas


Operan con datos numéricos y el resultado es un número.

1 – Visualizar los salarios de los empleados redondeados sin decimales

mysql> SELECT apellido, ROUND(salario,0) “SALARIO SIN


DECIMALES”
-> FROM empleados;

+----------+-----------------------+
| apellido | SALARIO SIN DECIMALES |
+----------+-----------------------+
| ALONSO | 1400 |
| LOPEZ | 1350 |
| MARTIN | 1500 |
| GARRIDO | 3850 |
| MARTINEZ | 2450 |
| REY | 6000 |
| CALVO | 1800 |
| GIL | 3350 |
| JIMENEZ | 1400 |
+----------+-----------------------+
9 rows in set (0.23 sec)

2 – Mostrar los datos de los empleados en los que su comisión se múltiplo de 100, y no sea cero.

mysql> SELECT *
-> FROM empleados
-> WHERE MOD(comision,100)=0 AND comision!=0;

+-------+----------+---------+--------+------------+---------+---------+------+
|EMP_NO | APELLIDO | OFICIO |DIRECTOR| FECHA_ALTA | SALARIO| COMISION |DEP_NO|
+-------+----------+---------+--------+------------+---------+---------+------+
| 7499 | ALONSO | VENDEDOR | 7698 | 1981-02-23 | 1400.00 | 400.00 | 30 |
| 7654 | MARTIN | VENDEDOR | 7698 | 1981-09-28 | 1500.00 | 1600.00 | 30 |
+------+----------+----------+--------+------------+---------+---------+------+
2 rows in set (0.00 sec)

Página: 12
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

4.2 – Funciones de caracteres


Operan con datos alfanuméricos y el resultado puede ser un dato alfanumérico o un valor numérico.

1 - Visualizar los tres primeros caracteres de los apellidos de los empleados seguidos de un punto

mysql> SELECT CONCAT(SUBSTR(apellido,1,3),'.') "INICIALES"


-> FROM empleados;

+-----------+
| INICIALES |
+-----------+
| ALO. |
| LOP. |
| MAR. |
| GAR. |
| MAR. |
| REY. |
| CAL. |
| GIL. |
| JIM. |
+-----------+
9 rows in set (0.01 sec)

2- Visualizar los nombres de los departamentos cuyo nombre tenga de más de 6 caracteres
reemplazando las letras ‘A’ por ‘*’

mysql> SELECT REPLACE(dnombre,'A','*')


-> FROM departamentos
-> WHERE LENGTH(dnombre)>6;

+--------------------------+
| REPLACE(dnombre,'A','*') |
+--------------------------+
| CONT*BILID*D |
| INVESTIG*CION |
| PRODUCCION |
+--------------------------+
3 rows in set (0.00 sec)

Página: 13
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

4.3 – Funciones de fechas


Son funciones que operan con datos de tipo fecha y pueden devolver diferentes tipos de datos. Son
las más complejas y que más diversidad presentan. Su manejo es muy importante dentro de los
procesos de gestión que se pueden realizar con las bases de datos.

Nota: estas funciones de fechas varían bastante de un sistema gestor a otro.

1 – Visualizar la fecha que será dentro de una semana

mysql> SELECT CURDATE() "HOY",


ADDDATE(CURDATE(),7) "DENTRO DE UNA SEMANA";

+------------+----------------------+
| HOY | DENTRO DE UNA SEMANA |
+------------+----------------------+
| 2005-04-02 | 2005-04-09 |
+------------+----------------------+
1 row in set (0.00 sec)

2 – Visualizar de alta de los empleados con el formato <día de la semana> - <dia> de <mes> de
<año>.

mysql> SELECT apellido,CONCAT(DAYNAME(fecha_alta),' - ',


DAYOFMONTH(fecha_alta),' de ',MONTH(fecha_alta),' de ',
YEAR(fecha_alta)) "fecha alta"
-> FROM empleados;

+----------+----------------------------+
| apellido | fecha alta |
+----------+----------------------------+
| ALONSO | Monday - 23 de 2 de 1981 |
| LOPEZ | Friday - 8 de 5 de 1981 |
| MARTIN | Monday - 28 de 9 de 1981 |
| GARRIDO | Friday - 1 de 5 de 1981 |
| MARTINEZ | Tuesday - 9 de 6 de 1981 |
| REY | Tuesday - 17 de 11 de 1981 |
| CALVO | Tuesday - 8 de 9 de 1981 |
| GIL | Thursday - 6 de 5 de 1982 |
| JIMENEZ | Thursday - 24 de 3 de 1983 |
+----------+----------------------------+
9 rows in set (0.00 sec)

3 - Mostrar los datos de los empleados que entraron en la empresa en lunes

mysql> SELECT *
-> FROM empleados
-> WHERE DAYOFWEEK(fecha_alta)=2;

+------+----------+----------+--------+------------+---------+---------+------+
|EMP_NO| APELLIDO | OFICIO |DIRECTOR| FECHA_ALTA | SALARIO | COMISION|DEP_NO|
+------+----------+----------+--------+------------+---------+---------+------+
| 7499 | ALONSO | VENDEDOR | 7698 | 1981-02-23 | 1400.00 | 400.00 | 30 |
| 7654 | MARTIN | VENDEDOR | 7698 | 1981-09-28 | 1500.00 | 1600.00 | 30 |
+------+----------+----------+--------+------------+---------+---------+-- ---+
2 rows in set (0.00 sec)

Página: 14
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

4 – Mostrar para cada empleado su apellido junto con el número de trienos que tiene (se tiene un
trienio por cada tres años en la empresa)
mysql> SELECT APELLIDO,
TRUNCATE(((DATEDIFF(CURDATE(),fecha_alta)/365)/3),0) "TRIENIOS"
-> FROM empleados;

+----------+----------+
| APELLIDO | TRIENIOS |
+----------+----------+
| ALONSO | 8 |
| LOPEZ | 7 |
| MARTIN | 7 |
| GARRIDO | 7 |
| MARTINEZ | 7 |
| REY | 7 |
| CALVO | 7 |
| GIL | 7 |
| JIMENEZ | 7 |
+----------+----------+
9 rows in set (0.00 sec)

5 – Mostrar los empleados que llevan más de 23 años en la empresa.

mysql> SELECT *
-> FROM empleados
-> WHERE fecha_alta<DATE_SUB(CURDATE(),INTERVAL 23 YEAR);

+------+----------+-----------+--------+------------+---------+----------+----+
|EMP_NO| APELLIDO | OFICIO |DIRECTOR| FECHA_ALTA | SALARIO | COMISION |DEP |
+------+----------+-----------+--------+------------+---------+----------+----+
| 7499 | ALONSO | VENDEDOR | 7698 | 1981-02-23 | 1400.00 | 400.00 | 30 |
| 7521 | LOPEZ | EMPLEADO | 7782 | 1981-05-08 | 1350.50 | NULL | 10 |
| 7654 | MARTIN | VENDEDOR | 7698 | 1981-09-28 | 1500.00 | 1600.00 | 30 |
| 7698 | GARRIDO | DIRECTOR | 7839 | 1981-05-01 | 3850.12 | NULL | 30 |
| 7782 | MARTINEZ | DIRECTOR | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7839 | REY | PRESIDENTE| NULL | 1981-11-17 | 6000.00 | NULL | 10 |
| 7844 | CALVO | VENDEDOR | 7698 | 1981-09-08 | 1800.00 | 0.00 | 30 |
+------+----------+-----------+--------+------------+---------+----------+----+
7 rows in set (0.00 sec)

6 - Visualizar la fecha de 4/10/1997 con el formato <día de la semana>, <número de día> de <nombre
del mes> de <año>

mysql> SELECT DATE_FORMAT('1997-10-04','%W, %e de %M de %Y') ;


+------------------------------------------------+
| DATE_FORMAT('1997-10-04','%W, %e de %M de %Y') |
+------------------------------------------------+
| Saturday, 4 de October de 1997 |
+------------------------------------------------+
1 row in set (0.00 sec)

Página: 15
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

4.4 – Funciones de comparación


Comparan un valor con otro dando y el resultado obtenido dependerá de la función concreta.

1 - Visualizar para cada empleado el valor que sea mayor entre su salario y su comisión

mysql> SELECT apellido, salario, comision,


GREATEST(salario,comision)
-> FROM empleados;

+----------+---------+----------+----------------------------+
| apellido | salario | comision | GREATEST(salario,comision) |
+----------+---------+----------+----------------------------+
| ALONSO | 1400.00 | 400.00 | 1400.00 |
| LOPEZ | 1350.50 | NULL | 1350.50 |
| MARTIN | 1500.00 | 1600.00 | 1600.00 |
| GARRIDO | 3850.12 | NULL | 3850.12 |
| MARTINEZ | 2450.00 | NULL | 2450.00 |
| REY | 6000.00 | NULL | 6000.00 |
| CALVO | 1800.00 | 0.00 | 1800.00 |
| GIL | 3350.00 | NULL | 3350.00 |
| JIMENEZ | 1400.00 | NULL | 1400.00 |
+----------+---------+----------+----------------------------+
9 rows in set (0.00 sec)

2 – Mostar los empleados en los que la suma de su salario más su comisión es menor de 2.000 euros

mysql> SELECT apellido, salario, comision


-> FROM empleados
-> WHERE salario+IFNULL(comision,0)<2000;

+----------+---------+----------+
| apellido | salario | comision |
+----------+---------+----------+
| ALONSO | 1400.00 | 400.00 |
| LOPEZ | 1350.50 | NULL |
| CALVO | 1800.00 | 0.00 |
| JIMENEZ | 1400.00 | NULL |
+----------+---------+----------+
4 rows in set (0.00 sec)

Página: 16
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

4.5 – Otras funciones


Son funciones que nos dan información sobre la base de datos o realizan algunas operaciones con
valores o listas de valores de las filas de la tabla.

1- Indicar la versión de MyQL que estamos utilizando

mysql> SELECT VERSION();

+--------------------+
| VERSION() |
+--------------------+
| 5.1.0-alpha-nt-max |
+--------------------+
1 row in set (0.00 sec)

2 – Indicar el usuario con el que estamos conectados

mysql> SELECT USER();

+----------------+
| USER() |
+----------------+
| ODBC@localhost |
+----------------+
1 row in set (0.00 sec)

Página: 17
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

5 - Ordenación.
Para obtener la salida de una consulta clasificada por algún criterio o especificación, la sentencia SELECT
dispone de la cláusula ORDER BY para ordenar.

5.1 – Formato de selección con ordenación


Formato de consulta con ordenación

SELECT [ALL/DISTINCT] ExpresionColumna [,ExpresionColumna....]


FROM NombreTabla
[WHERE CondicionSeleccion]
[ORDER BY {ExpresionColumna|Posicion} [ASC|DESC]
[,{ExpresionColumna|Posicion} [ASC|DESC]..... ] ] ;

Notación: la cláusula ORDER BY es opcional, por eso aparece toda ella entre corchetes.
Dentro de ella expresión de columna y posición van entre llaves porque hay que elegir una de
ellas y ASC y DESC entre corchetes porque son opcionales

donde ASC|DESC.................... ASC (ascendente) o DESC (descendente) indica la forma de ordenación


para esa expresión. Por omisión es ASC.
ExpresionColumna........ conjunto de nombres de columna con literales, operadores y/o
funciones. También admite alias.
Posicion......................... si queremos ordenar por expresiones que se muestran en el select la
ExpresionColumna puede ser sustituida por el número, Posicion, que
corresponde al número de orden que ocupa en la lista de expresiones
visualizadas en la select.

Si existe más de una expresión por la que ordenar estas aparecen separadas por comas y el orden en que
se realizan las clasificaciones es de izquierda a derecha, es decir, a igualdad de la expresión más a la
izquierda ordena por la siguiente expresión y así sucesivamente.

5.2 – Ejemplos de ordenación


1. Obtener relación alfabética de todos los empleados con todos sus datos.

mysql> SELECT dep_no, apellido, salario


-> FROM empleados
-> ORDER BY apellido;

+--------+----------+---------+
| dep_no | apellido | salario |
+--------+----------+---------+
| 30 | ALONSO | 1400.00 |
| 30 | CALVO | 1800.00 |
| 30 | GARRIDO | 3850.12 |
| 20 | GIL | 3350.00 |
| 20 | JIMENEZ | 1400.00 |

Página: 18
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

| 10 | LOPEZ | 1350.50 |
| 30 | MARTIN | 1500.00 |
| 10 | MARTINEZ | 2450.00 |
| 10 | REY | 6000.00 |
+--------+----------+---------+
9 rows in set (0.00 sec)

2. Obtener clasificación alfabética de empleados por departamentos.

mysql> SELECT dep_no, apellido, salario


-> FROM empleados
-> ORDER BY dep_no, apellido;
+--------+----------+---------+
| dep_no | apellido | salario |
+--------+----------+---------+
| 10 | LOPEZ | 1350.50 |
| 10 | MARTINEZ | 2450.00 |
| 10 | REY | 6000.00 |
| 20 | GIL | 3350.00 |
| 20 | JIMENEZ | 1400.00 |
| 30 | ALONSO | 1400.00 |
| 30 | CALVO | 1800.00 |
| 30 | GARRIDO | 3850.12 |
| 30 | MARTIN | 1500.00 |
+--------+----------+---------+
9 rows in set (0.00 sec)

O también podemos escribir:

mysql> SELECT dep_no, apellido, salario


-> FROM empleados
-> ORDER BY 1,2;

3. Obtener los datos de los empleados clasificados por oficios y en orden descendente de salarios.

mysql> SELECT emp_no, apellido, oficio, salario


-> FROM empleados
-> ORDER BY oficio, salario DESC;
+--------+----------+------------+---------+
| emp_no | apellido | oficio | salario |
+--------+----------+------------+---------+
| 7876 | GIL | ANALISTA | 3350.00 |
| 7698 | GARRIDO | DIRECTOR | 3850.12 |
| 7782 | MARTINEZ | DIRECTOR | 2450.00 |
| 7900 | JIMENEZ | EMPLEADO | 1400.00 |
| 7521 | LOPEZ | EMPLEADO | 1350.50 |
| 7839 | REY | PRESIDENTE | 6000.00 |
| 7844 | CALVO | VENDEDOR | 1800.00 |
| 7654 | MARTIN | VENDEDOR | 1500.00 |
| 7499 | ALONSO | VENDEDOR | 1400.00 |
+--------+----------+------------+---------+
9 rows in set (0.00 sec)
4 – Obtener los apellidos de los empleados junto con su salario anual (salario + comision en 14
pagas) ordenado de mayor a menor por este salario total.

Página: 19
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

mysql> SELECT apellido,


(salario+IFNULL(comision,0))*14 "Salario anual"
-> FROM empleados
-> ORDER BY (salario+IFNULL(comision,0))*14 DESC;
+----------+---------------+
| apellido | Salario anual |
+----------+---------------+
| REY | 84000.00 |
| GARRIDO | 53901.68 |
| GIL | 46900.00 |
| MARTIN | 43400.00 |
| MARTINEZ | 34300.00 |
| ALONSO | 25200.00 |
| CALVO | 25200.00 |
| JIMENEZ | 19600.00 |
| LOPEZ | 18907.00 |
+----------+---------------+
9 rows in set (0.19 sec)

Si no queremos volver a escribir la expresión podemos utilizar el alias o la posición de la expresión


por la que queremos ordenar

mysql> SELECT apellido,


(salario+IFNULL(comision,0))*14 "Salario anual"
-> FROM empleados
-> ORDER BY "salario anual" DESC;

mysql> SELECT apellido,


(salario+IFNULL(comision,0))*14 "Salario anual"
-> FROM empleados
-> ORDER BY 2 DESC;

Página: 20
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

6 - Selección con limitación de filas


Nos va a permitir limitar el número de filas que se visualicen como resultado de una sentencia select.

6.1 – Formato de selección con limitación de filas


Formato de consulta con limitación de las filas que se visualizan dentro de las filas seleccionadas con el
WHERE.

SELECT [ALL/DISTINCT] ExpresionColumna [,ExpresionColumna....]


FROM NombreTabla
[WHERE CondicionSeleccion]
[ORDER BY {ExpresionColumna|Posicion} [ASC|DESC]
[,{ExpresionColumna|Posicion} [ASC|DESC]..... ] ]
[ LIMIT [m, ] n ] ;

Notación: la cláusula LIMIT es opcional, por eso aparece toda ella entre corchetes. Dentro de
ella también lo es indicar el valor de m

donde m...................... es el número de fila por el que se comienza la visualización. Las filas se empiezan
a numerar por 0.
Es opcional y en caso de omitirse se supone el valor 0 (1ª fila)
n...................... indica el número de filas que se quieren visualizar.

6.2 – Ejemplos de limitación de filas


1. Obtener los datos de los 5 empleados con menos salario.

mysql> SELECT emp_no, apellido, salario, dep_no


-> FROM empleados
-> ORDER BY salario
-> LIMIT 5;
+--------+----------+---------+--------+
| emp_no | apellido | salario | dep_no |
+--------+----------+---------+--------+
| 7521 | LOPEZ | 1350.50 | 10 |
| 7499 | ALONSO | 1400.00 | 30 |
| 7900 | JIMENEZ | 1400.00 | 20 |
| 7654 | MARTIN | 1500.00 | 30 |
| 7844 | CALVO | 1800.00 | 30 |
+--------+----------+---------+--------+
5 rows in set (0.00 sec)

2. Obtener clasificación alfabética de empleados según su apellido y mostrar desde el 5º hasta el 7º de la


lista

mysql> SELECT emp_no, apellido, salario, dep_no


-> FROM empleados
-> ORDER BY apellido
-> LIMIT 4,3;

Página: 21
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+--------+----------+---------+--------+
| emp_no | apellido | salario | dep_no |
+--------+----------+---------+--------+
| 7900 | JIMENEZ | 1400.00 | 20 |
| 7521 | LOPEZ | 1350.50 | 10 |
| 7654 | MARTIN | 1500.00 | 30 |
+--------+----------+---------+--------+
5 rows in set (0.00 sec)

Si observamos la salida producida al ordenar por apellido comprobamos que se han visualizado 3 filas
desde la 5ª (Fila 4 empezando por 0)

mysql> SELECT emp_no, apellido, salario, dep_no


-> FROM empleados
-> ORDER BY apellido
-> ;
+--------+----------+---------+--------+
| emp_no | apellido | salario | dep_no |
+--------+----------+---------+--------+
| 7499 | ALONSO | 1400.00 | 30 |Fila 0
| 7844 | CALVO | 1800.00 | 30 |Fila 1
| 7698 | GARRIDO | 3850.12 | 30 |Fila 2
| 7876 | GIL | 3350.00 | 20 |Fila 3
| 7900 | JIMENEZ | 1400.00 | 20 |Fila 4
| 7521 | LOPEZ | 1350.50 | 10 |Fila 5
| 7654 | MARTIN | 1500.00 | 30 |Fila 6
| 7782 | MARTINEZ | 2450.00 | 10 |Fila 7
| 7839 | REY | 6000.00 | 10 |Fila 8
+--------+----------+---------+--------+
9 rows in set (0.00 sec)

Página: 22
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

7 - Resumen (1) del formato de selección


Formato de selección con todas las cláusulas vistas hasta el momento.

SELECT { * | [ALL/DISTINCT] ExpresionColumna [[AS] AliasColumna]


[, ExpresionColumna [[AS] AliasColumna]....] }
FROM NombreTabla [AliasTabla]
[WHERE CondicionSeleccion ]
[ORDER BY {ExpresionColumna|Posicion} [ASC|DESC]
[,{ExpresionColumna|Posicion} [ASC|DESC]..... ] ]
[LIMIT [m, ] n ] ;

Página: 23
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

TEMA 6. CONSULTAS CON AGRUPAMIENTO Y


FUNCIONES DE GRUPOS

Paulina Barthelemy

1- Consultas de selección con agrupamientos


SQL permite agrupar las filas de una tabla, seleccionadas en una consulta formando grupos según el
contenido de alguna o algunas expresiones, y obtener salidas, calculadas a partir de los grupos formados.

Las salidas obtenidas son los resultados de agrupar y aplicar las funciones a cada uno de los grupos de las filas
seleccionada en la tabla.

1.1 – Formato de la consulta de selección con agrupamiento


Añadimos a las cláusulas que ya conocemos las de agrupamiento y selección de grupos.

SELECT { ExpresionColumna [,ExpresionColumna .....] | * }


FROM NombreTabla

[WHERE CondicionSeleccion]
[GROUP BY ExpresionColumnaAgrupacion|Posición
[,ExpresionColumnaAgrupacion|Posicion... ]
[HAVING CondicionSeleccionGrupos ] ]
[ORDER BY {ExpresionColumna|Posicion| } [ASC|DESC]
[,{ExpresionColumna|Posicion| } [ASC|DESC].....] ]
[LIMIT [m, ] n ] ;

Notación: la cláusula GROUP BY es opcional, por eso aparece toda ella entre corchetes y en
caso de existir debe ir antes de la cláusula ORDER BY. En caso de existir la cláusula GROUP
BY dentro de ella puede estar la cláusula HAVING, que es a su vez opcional.

Donde ExpresionColumna.......................... es una expresión que contiene columnas de la tabla, literales,


operadores y/o funciones. Además admite alias.
Esta expresión solo puede contener columnas de agrupación
y/o funciones de grupo.
ExpresionColumnaAgrupacion.... es una expresión que contiene columnas de la tabla, literales,
operadores y/o funciones por la que se formarán los grupos.
No admite alias.
Posicion .......................................... posición que ocupa le expresión por la que queremos

Página: 24
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

agrupar en la lista de expresiones visualizadas.


CondicionSelecionGrupos……... es una condición, expresión que devuelve el valor verdadero
/falso/nulo, para seleccionar grupos

Si existe más de una expresión por la que agrupar, estas aparecen separadas por comas y el orden en que
se realizan las agrupaciones es de izquierda a derecha. Se forman grupos con la expresión más a la
izquierda y a igualdad de la expresión más a la izquierda se agrupa por la siguiente expresión y así
sucesivamente.

La cláusula HAVING se emplea para controlar qué grupos se seleccionan, una vez realizada la agrupación.
Esta asociada a la cláusula GROUP BY y no tiene sentido sin ella.

La salida después de utilizar la cláusula GROUP BY queda ordenada por las expresiones de
agrupación. Las cláusulas ORDER BY y LIMIT pueden utilizarse después de agrupar, si se quiere
agrupar por otro concepto y/o limitar el número de filas. Solo existe una limitación en la cláusula
ORDER BY, ya que no puede contener funciones de grupo. En caso de que quiera ordenarse por una
de estas funciones deberemos hacerlo referenciando la posición que ocupa en la select.

Ni en la expresión de la cláusula GROUP BY ni en condición de la cláusula HAVING pueden utilizarse los


alias.

1.2 – Consideraciones de consultas con cláusulas de agrupamiento


El funcionamiento de la sentencia SELECT con cláusulas de agrupamiento es el siguiente:
• primero realiza una selección de filas según la cláusula WHERE
• forma grupos según la cláusula GROUP BY
• hace una selección de grupos según la cláusula HAVING.

Es importante tener en cuenta que, en caso de selección con cláusula de agrupación, solo pueden
mostrarse expresiones que contengan columnas de agrupación y/o funciones de grupo. Así
mimo, si se utilizan funciones de agrupación sin la cláusula GROUP BY no pueden mostrarse el resto
de las filas de la tabla.

La cláusula HAVING actúa como un filtro sobre el resultado de agrupar las filas, a diferencia de la
cláusula WHERE que actúa sobre las filas antes de la agrupación.

Página: 25
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

2- Funciones de grupo
Estas funciones de grupo actúan sobre las filas previamente seleccionadas y los grupos que se hayan
formado en ellas. El criterio para agrupar suele ser una o varias de las columnas o expresiones de la tabla
llamadas columnas o expresiones de agrupación. Si no se especifica ningún criterio, las filas de la tabla
seleccionadas en la consulta, formarán un grupo único.

2.1- Funciones de grupo

AVG(expr) Valor medio de “expr” ignorando los valores nulos


COUNT( { * | expr } ) Número de veces que “expr” tiene un valor no nulo. La opción “*”
cuenta el número de filas seleccionadas.
MAX(expr) Valor máximo de “expr”
MIN(expr) Valor mínimo de “expr”
STDDEV(expr) Desviación típica de “expr” sin tener en cuenta los valores nulos
SUM(expr) Suma de “expr”
VARIANCE(expr) Varianza de “expr” sin tener en cuenta los valores nulos.

Descripción de las funciones de grupo

AVG(expr) Calcula el valor medio de la expresión de columna que se indique dentro del
paréntesis, teniendo en cuenta que los valores NULL no son incluidos.

COUNT( { * | expr } ) Tiene dos posibilidades, la primera con un * cuenta el número filas
seleccionadas y la segunda con una expresión de columna cuenta el número
de veces que la expresión tiene el valor diferente de NULL

MAX(expr) Devuelve el valor máximo de la expresión de columna que le acompaña.

MIN(expr) Devuelve el valor mínimo de la expresión de columna que le acompaña.

STDDEV(expr) Calcula la desviación típica para los valores de la expresión de columna que le
acompaña.

SUM(expr) Calcula la suma de valores de la expresión de columna indicada dentro del


paréntesis

VARIANCE(expr) Calcula la varianza para los valores de la expresión de columna que se


indique dentro del paréntesis, teniendo en cuenta que los valores NULL no son
incluidos.

Por lo general, las funciones de grupos se utilizan sobre más de un grupo de filas. La cláusula GROUP BY
establece el criterio o columnas de agrupación y se calculará el valor de la función para cada grupo. Pero
también pueden utilizarse sin la cláusula GROUP BY y en ese caso estas funciones actúan sobre un único
grupo formado por todas las filas seleccionadas.

Estas funciones pueden ser utilizadas con la cláusula DISTICT.


Por ejemplo COUNT(DISTICT(NombreColumna) cuenta cuantos valores diferentes para esa columna

Página: 26
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

hay entre las filas seleccionadas o agrupadas.

2. 2 – Ejemplos con funciones de grupo.


a) Ejemplos de consulta con funciones de grupo sin criterio de agrupación
1. Obtener la masa salarial mensual de todos los empleados.

mysql> SELECT SUM(salario)


-> FROM empleados;

+--------------+
| SUM(salario) |
+--------------+
| 23100.62 |
+--------------+
1 row in set (0.00 sec)

2. Obtener los salarios máximo, mínimo y la diferencia existente entre ambos.

mysql> SELECT MAX(salario)"Salario mas alto" ,


-> MIN(salario) "Salario mas bajo",
-> MAX(salario)- MIN(salario) "Diferencia"
-> FROM empleados;

+------------------+------------------+------------+
| Salario mas alto | Salario mas bajo | Diferencia |
+------------------+------------------+------------+
| 6000.00 | 1350.50 | 4649.50 |
+------------------+------------------+------------+
1 row in set (0.00 sec)

3. Obtener la fecha de alta más reciente.

mysql> SELECT MAX(fecha_alta)"Fecha alta"


-> FROM empleados;

+------------+
| Fecha alta |
+------------+
| 1983-03-24 |
+------------+
1 row in set (0.00 sec)

4. Calcular el salario medio de los empleados.

mysql> SELECT AVG(salario) "Salario medio"


-> FROM empleados;

+---------------+
| Salario medio |
+---------------+
| 2566.735569 |
+---------------+
1 row in set (0.00 sec)

Página: 27
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

A veces hacer la media con la función AVG no da el mismo resultado que hacer la suma y dividirla por el
número de filas, SUM/CONT. Esto es porque COUNT cuenta el número de valores de datos que hay en
una columna, sin incluir los valores NULL, y por el contrario, COUNT(*) cuenta todas las filas de la tabla,
sin considerar que en algunas columnas existan valores NULL. Sin embargo la función AVG si tiene en
cuenta las filas con valores NULL.
Veamos un ejemplo:

mysql> SELECT AVG(comision)


-> FROM empleados;
+---------------+
| AVG(comision) |
+---------------+
| 666.666667 |
+---------------+
1 row in set (0.00 sec)

mysql> SELECT SUM(comision)/COUNT(*)


-> FROM empleados;
+------------------------+
| SUM(comision)/COUNT(*) |
+------------------------+
| 222.2222 |
+------------------------+
1 row in set (0.00 sec)

mysql> SELECT SUM(comision)/COUNT(comision)


-> FROM empleados;

+-------------------------------+
| SUM(comision)/COUNT(comision) |
+-------------------------------+
| 666.6667 |
+-------------------------------+
1 row in set (0.00 sec)

5. Calcular el salario medio de los empleados que sean ANALISTAS

mysql> SELECT AVG(salario) "Salario medio"


-> FROM empleados
-> WHERE oficio = 'ANALISTA';

+---------------+
| Salario medio |
+---------------+
| 3350.000000 |
+---------------+
1 row in set (0.00 sec)

b) Ejemplos de consulta con funciones de grupo con criterio de agrupación GROUP BY


1. Obtener los salarios medios por departamento.

mysql> SELECT dep_no "Departamento" , AVG(salario) "Salario medio"


-> FROM empleados
-> GROUP BY dep_no;

Página: 28
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+--------------+---------------+
| Departamento | Salario medio |
+--------------+---------------+
| 10 | 3266.833333 |
| 20 | 2375.000000 |
| 30 | 2137.530029 |
+--------------+---------------+
3 rows in set (0.00 sec)

2. Obtener cuántos empleados hay en cada oficio

mysql> SELECT oficio "Oficio", COUNT(*) "Nº de Empleados"


-> FROM empleados
-> GROUP BY oficio;

+------------+-----------------+
| Oficio | Nº de Empleados |
+------------+-----------------+
| ANALISTA | 1 |
| DIRECTOR | 2 |
| EMPLEADO | 2 |
| PRESIDENTE | 1 |
| VENDEDOR | 3 |
+------------+-----------------+
5 rows in set (0.00 sec)

c) Ejemplos de consulta con funciones de grupo con criterio de agrupación GROUP BY y cláusula
HAVING
SQL realiza la selección de grupos en el proceso siguiente:
- A partir de la tabla sobre la que se realiza la consulta, la cláusula WHERE actúa como un primer filtro que
da como resultado una tabla interna cuyas filas cumplen la condición especificada en el WHERE .
- La cláusula GROUP BY produce la agrupación de las filas de la segunda tabla, dando como resultado
una tercera tabla.
- La cláusula HAVING actúa filtrando las filas de la tercera tabla, según la condición de selección
especificada, dando como resultado la salida de la consulta.

1. Seleccionar los oficios que tengan dos o más empleados:

mysql> SELECT oficio, COUNT(*)


-> FROM empleados
-> GROUP BY oficio
-> HAVING COUNT(*)>= 2;

+----------+----------+
| oficio | COUNT(*) |
+----------+----------+
| DIRECTOR | 2 |
| EMPLEADO | 2 |
| VENDEDOR | 3 |
+----------+----------+
3 rows in set (0.00 sec)

2. Seleccionar los oficios que tengan dos o más empleados, cuyo salario supere los 1400 euros.

mysql> SELECT oficio, COUNT(*)

Página: 29
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

-> FROM empleados


-> WHERE salario > 1400
-> GROUP BY oficio
-> HAVING COUNT(*) >= 2;

+----------+----------+
| oficio | COUNT(*) |
+----------+----------+
| DIRECTOR | 2 |
| VENDEDOR | 2 |
+----------+----------+
2 rows in set (0.00 sec)

d) Ejemplos de consulta con funciones de grupo con criterio de agrupación GROUP BY,
incluyendo las cláusulas ORDER BY y LIMIT
1- Seleccionar los datos del departamento con menor salario medio

mysql> SELECT dep_no, AVG (salario)


-> FROM empleados
-> GROUP BY dep_no
-> ORDER BY 2
-> LIMIT 1;
+--------+---------------+
| dep_no | AVG (salario) |
+--------+---------------+
| 30 | 2137.530029 |
+--------+---------------+
1 row in set (0.23 sec)

2- Seleccionar los datos del departamento con mayor número de empleados.

mysql> SELECT dep_no, COUNT(*)


-> FROM empleados
-> GROUP BY dep_no
-> ORDER BY 2 DESC
-> LIMIT 1;

+--------+----------+
| dep_no | COUNT(*) |
+--------+----------+
| 30 | 4 |
+--------+----------+
1 row in set (0.39 sec)

Página: 30
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

3- Resumen (2) del formato de selección


Formato de selección con todas las cláusulas vistas hasta el momento.

SELECT { * | [ALL/DISTINCT] ExpresionColumna [AliasColumna]


[,ExpresionColumna [AliasColumna]....] }
FROM NombreTabla [AliasTabla]
[WHERE CondicionSeleccion ]
[GROUP BY ExpresionColumna|Posicion [,ExpresionColumna|Posicion ... ]
[HAVING CondicionSeleciónGrupos ] ]
[ORDER BY {ExpresionColumna|Posicion } [ASC|DESC]
[,{ExpresionColumna|Posicion } [ASC|DESC].....] ]
[LIMIT [m, ] n ] ;

Página: 31
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

TEMA 7. SUBCONSULTAS

Paulina Barthelemy

1 - ¿Qué es una subconsulta?.


Una subconsulta en SQL consiste en utilizar los resultados de una consulta dentro de otra, que se
considera la principal. Esta posibilidad fue la razón original para la palabra “estructurada” que da el nombre
al SQL de Lenguaje de Consultas Estructuradas (Structured Query Language).

Anteriormente hemos utilizado la cláusula WHERE para seleccionar los datos que deseábamos
comparando un valor de una columna con una constante, o un grupo de ellas. Si los valores de dichas
constantes son desconocidos, normalmente por proceder de la aplicación de funciones a determinadas
columnas de la tabla, tendremos que utilizar subconsultas. Por ejemplo, queremos saber la lista de
empleados cuyo salario supere el salario medio. En primer lugar, tendríamos que averiguar el importe del
salario medio:

mysql> SELECT AVG(salario)"Salario Medio"


-> FROM empleados;

+---------------+
| Salario Medio |
+---------------+
| 2566.735569 |
+---------------+
1 row in set (0.00 sec)

A continuación, anotarlo en un papel o recordarlo para la siguiente sentencia:

mysql> SELECT dep_no "Nº Empleado", apellido, salario


-> FROM empleados
-> WHERE salario> 2566.73;
+-------------+----------+---------+
| Nº Empleado | apellido | salario |
+-------------+----------+---------+
| 30 | GARRIDO | 3850.12 |
| 10 | REY | 6000.00 |
| 20 | GIL | 3350.00 |
+-------------+----------+---------+
3 rows in set (0.00 sec)

Pero además de tener que anotar el resultado de otra consulta para ser utilizado en esta, tiene el problema
de que si el número de empleados o el salario de estos cambiase, cambiaría el valor del salario medio y
habría que modificar esta segunda consulta reemplazando el valor antiguo por el nuevo valor.

Sería mucho más eficiente utilizar una subconsulta:

Página: 32
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

mysql> SELECT dep_no "Nº Empleado", apellido, salario


-> FROM empleados
-> WHERE salario > (SELECT AVG(salario)
-> FROM empleados);

+-------------+----------+---------+
| Nº Empleado | apellido | salario |
+-------------+----------+---------+
| 30 | GARRIDO | 3850.12 |
| 10 | REY | 6000.00 |
| 20 | GIL | 3350.00 |
+-------------+----------+---------+
3 rows in set (0.00 sec)

La subconsulta (comando SELECT entre paréntesis) se ejecuta primero y, posteriormente, el valor


extraído es utilizado en la consulta principal, obteniéndose el resultado deseado.

1.1 - Formato de una subconsulta

( SELECT[ALL/DISTINCT] ExpresionColumna [,ExpresionColumna .....]


FROM NombreTabla [ , NombreTabla ]
[WHERE CondicionSeleccion]
[GROUP BY ExpresionColumnaAgrupacion [, ExpresionColumnaAgrupacion ... ]
[HAVING CondicionSeleciónGrupos ] ] )

donde el formato de la sentencia SELECT entre paréntesis tiene las siguientes diferencias con la sentencia
SELECT de las consultas:
• No tiene sentido la cláusula ORDER BY ya que los resultados de una subconsulta se utilizan
internamente y no son visibles al usuario.
• Los nombres de columna que aparecen las expresiones en una subconsulta pueden referirse a
columnas de la tabla de la consulta principal y se conocen como referencias externas.

Una subconsulta siempre forma parte de la condición de selección en las cláusulas WHERE o HAVING.
Cuando incluimos una subconsulta en una sentencia select el funcionamiento es el siguiente: para cada fila de la
consulta ejecuta la subconsulta y con ese resultado se evalúa la fila correspondiente de la consulta, mostrándose
si el resultado de la evaluación es VERDADERO.

Las subconsultas habitualmente devuelven una sola expresión pero también pueden devolver más de una. La
sentencia select que conecta con la subconsulta deberá recoger estos valores en una o varias columnas, según
sea la subconsulta, para poder después compararlos.

Vamos a verlo con unos ejemplos


a) Subconsulta que devuelve una sola expresión
Obtener el nombre del departamento donde trabaja GARRIDO

mysql> SELECT dnombre

Página: 33
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

-> FROM departamentos


-> WHERE dep_no = (SELECT dep_no
-> FROM empleados
-> WHERE apellido = 'GARRIDO');

+---------+
| dnombre |
+---------+
| VENTAS |
+---------+
1 row in set (0.02 sec)

La subconsulta devuelve una sola expresión dep_no, que en este caso el valor del departamento de
GARRIDO que la consulta compara con el correspondiente en la tabla departamentos.

b)Subconsulta que devuelven más de una expresión


Obtener los empleados que tengan el mismo oficio y departamento que ALONSO

mysql> SELECT emp_no, apellido, oficio, dep_no


-> FROM empleados
-> WHERE (dep_no, oficio) = (SELECT dep_no, oficio
-> FROM empleados
-> WHERE apellido = 'ALONSO');

+--------+----------+----------+--------+
| emp_no | apellido | oficio | dep_no |
+--------+----------+----------+--------+
| 7499 | ALONSO | VENDEDOR | 30 |
| 7654 | MARTIN | VENDEDOR | 30 |
| 7844 | CALVO | VENDEDOR | 30 |
+--------+----------+----------+--------+
3 rows in set (0.02 sec)

La subconsulta devuelve dos expresiones, dep_no y oficio (en este caso formadas por una columna cada una)
correspondientes al departamento y oficio de ALONSO y la consulta lo compara con dos columnas dep_no y
oficio, de cada una de las filas de la tabla.

Lo más habitual es el primer caso por ello comenzaremos con las subconsultas que devuelven una sola expresión
y posteriormente, en el apartado siguiente, trataremos las que devuelven más de una expresión.

Página: 34
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

2 – Subconsultas que devuelven una sola expresión

2.1 - Formato de las subconsultas que devuelven una sola


expresión
Es un formato habitual de una sentencia SELECT con la particularidad de que solo debe seleccionarse
una expresión de columna.

( SELECT [ALL/DISTINCT] ExpresionColumna


FROM NombreTabla [ , NombreTabla ]
[WHERE CondicionSeleccion]
[GROUP BY ExpresionColumnaAgrupacion [,ExpresionColumnaAgrupacion ... ]
[HAVING CondicionSeleciónGrupos ] ] )

2.2 - Valores de retorno y condiciones de selección


Como hemos dicho comenzaremos con la subconsultas que devuelven una sola expresión. El resultado de
ejecutar la subconsulta puede devolvernos, en esta expresión, un valor simple o más de un valor. Según el
retorno de la subconsulta, el operador de comparación que se utilice en la condición de selección del
WHERE o HAVING deberá ser del tipo apropiado según la tabla siguiente:

Retorno de la subconsulta Operador comparativo

Valor simple De tipo aritmético


Más de un valor De tipo lógico

2.2.1 - Condición de selección con operadores aritméticos de comparación

Se utiliza cuando la subconsulta devuelve un único valor a comparar con una expresión, por lo general
formada a partir de la fila obtenida en la consulta principal. Si la comparación resulta cierta (TRUE), la
condición de selección también lo es. Si la subconsulta no devuelve ninguna fila (NULL), la comparación
devuelve también el valor NULL. Si la condición de comparación resulta falsa (FALSE), la condición de
selección también lo será.

Formato para la condición de selección con operadores aritméticos de comparación

ExpresionColumna OperadorComparacion (Subconsulta)

Página: 35
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

donde OperadorComparacion puede ser =,<>,<,>,<=,<=

Ejemplos de subconsultas con operadores de comparación


1. Obtener todos los empleados que tienen el mismo oficio que GARRIDO

mysql> SELECT emp_no "Nº Empleado", apellido, oficio


-> FROM empleados
-> WHERE oficio = (SELECT oficio
-> FROM empleados
-> WHERE apellido = 'GARRIDO');

+-------------+----------+----------+
| Nº Empleado | apellido | oficio |
+-------------+----------+----------+
| 7698 | GARRIDO | DIRECTOR |
| 7782 | MARTINEZ | DIRECTOR |
+-------------+----------+----------+
2 rows in set (0.00 sec)

La subconsulta devuelve el oficio de GARRIDO que es DIRECTOR y se visualizan los trabajadores de


oficio DIRECTOR, entre ellos GARRIDO. Más adelante haremos un ejemplo donde no se visualizará el
empleado de la subconsulta.

2. Obtener información de los empleados que ganan más que cualquier empleado del departamento 30.

mysql> SELECT emp_no "Nº Empleado", apellido, salario,


dep_no "Nº Departamento"
-> FROM empleados
-> WHERE salario > (SELECT MAX(salario)
-> FROM empleados
-> WHERE dep_no=30);

+-------------+----------+---------+-----------------+
| Nº Empleado | apellido | salario | Nº Departamento |
+-------------+----------+---------+-----------------+
| 7839 | REY | 6000.00 | 10 |
+-------------+----------+---------+-----------------+
1 row in set (0.00 sec)

3. Visualizar el número de VENDEDORES del departamento VENTAS.

mysql> SELECT COUNT(*) "Total Empleados"


-> FROM empleados
-> WHERE oficio = 'VENDEDOR'
-> AND dep_no = (SELECT dep_no
-> FROM departamentos
-> WHERE dnombre = 'VENTAS')
-> GROUP BY oficio;
+-----------------+
| Total Empleados |
+-----------------+
| 3 |
+-----------------+

Página: 36
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

1 row in set (0.00 sec)

4. Visualizar la suma de los salarios para cada oficio de los empleados del departamento VENTAS.

mysql> SELECT oficio, sum(salario)"Suma salarios"


-> FROM empleados
-> WHERE dep_no = (SELECT dep_no
-> FROM departamentos
-> WHERE dnombre='VENTAS')
-> GROUP BY oficio;
+----------+---------------+
| oficio | Suma salarios |
+----------+---------------+
| DIRECTOR | 3850.12 |
| VENDEDOR | 4700.00 |
+----------+---------------+
2 rows in set (0.01 sec)

2.2.3 - Condición de selección con operadores lógicos.

Se utiliza cuando la subconsulta puede devolver más de una fila a comparar con la fila actual de la
consulta principal. En ese caso los operadores aritméticos dan error.

Formato para la condición de selección con operadores lógicos

ExpresionColumna OperadorLogico (Subconsulta)

Donde OperadorLogico puede ser IN, ANY, ALL Y EXISTS

a) Operador lógico IN

Comprueba si valores de la fila actual de la consulta principal coincide con alguno de la lista de valores
devueltos por la subconsulta. Si el resultado es afirmativo la comparación resulta cierta (TRUE).

Formato para la condición de selección con el operador lógico IN

ExpresionColumna [NOT] IN (Subconsulta)

Ejemplos del operador lógico IN

1. Listar, en orden alfabético, aquellos empleados que no trabajen ni en Madrid ni en Barcelona.

mysql> SELECT emp_no, apellido, dep_no


-> FROM empleados
-> WHERE dep_no IN (SELECT dep_no

Página: 37
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

-> FROM departamentos


-> WHERE localidad NOT LIKE 'MADRID'
-> AND localidad NOT LIKE 'BARCELONA');

+--------+----------+--------+
| emp_no | apellido | dep_no |
+--------+----------+--------+
| 7876 | GIL | 20 |
| 7900 | JIMENEZ | 20 |
+--------+----------+--------+
2 rows in set (0.00 sec)

La subconsulta selecciona todos los departamentos que no están en Madrid ni en Barcelona, y la consulta
principal comprueba, empleado a empleado, si su departamento es uno de los seleccionados en la
subconsulta, visualizando sus datos caso de ser cierto.

También podemos resolverla utilizando NOT IN

mysql> SELECT emp_no, apellido, dep_no


-> FROM empleados
-> WHERE dep_no NOT IN (SELECT dep_no
-> FROM departamentos
-> WHERE localidad LIKE 'MADRID'
-> OR localidad LIKE 'BARCELONA');

2. Listar los nombres de los departamentos que tengan algún empleado con fecha de alta anterior a 1982.

mysql> SELECT dep_no "NºDepartamento", dnombre "Departamento"


-> FROM departamentos
-> WHERE dep_no IN (SELECT DISTINCT(dep_no)
-> FROM empleados
-> WHERE fecha_alta < '1982-01-01');

+----------------+--------------+
| NºDepartamento | Departamento |
+----------------+--------------+
| 10 | CONTABILIDAD |
| 30 | VENTAS |
+----------------+--------------+
2 rows in set (0.00 sec)

En este ejemplo, la subconsulta selecciona todos los empleados cuya fecha de alta sea anterior al año
1982, y la consulta principal compara, departamento a departamento, si coincide con el de alguno de los
que hayan sido seleccionados en la subconsulta.

3. Obtener los departamentos y sus nombres, siempre que haya más de dos empleados trabajando en
ellos.

mysql> SELECT dep_no "NºDepartamento", dnombre "Departamento"


-> FROM departamentos
-> WHERE dep_no IN (SELECT dep_no
-> FROM empleados
-> GROUP BY dep_no
-> HAVING COUNT(*)>2 );

Página: 38
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+----------------+--------------+
| NºDepartamento | Departamento |
+----------------+--------------+
| 10 | CONTABILIDAD |
| 30 | VENTAS |
+----------------+--------------+
2 rows in set (0.00 sec)

La subconsulta selecciona todos los departamentos que tienen más de un empleado trabajando, y la
consulta principal comprueba, departamento a departamento, si es uno de los seleccionados en la
subconsulta, visualizando sus datos caso de ser cierto.

b) Operadores lógicos ANY y ALL

Se utilizan junto a los operadores aritméticos de comparación para ampliar las posibles comprobaciones
de valores obtenidos a partir de la fila seleccionada en la consulta principal con valores obtenidos en la
subconsulta.
Su uso a menudo es sustituido por el del operador IN.

Formato para los operadores ANY/ALL

ExpresionColumna OperadorComparacion {ANY|ALL} (Subconsulta)

donde OperadorComparacion puede ser =,<>,<,>,<=,<

El operador ANY con uno de los seis operadores aritméticos compara el valor de la expresión formada a
partir de la consulta principal con valores producidos por la subconsulta. Si alguna de las comparaciones
individuales produce un resultado verdadero (TRUE), el operador ANY devuelve un resultado verdadero
(TRUE).

El operador ALL también se utiliza con los operadores aritméticos para comparar un valor de la
expresión formada a partir de la consulta principal con cada uno de los valores de datos producidos por
la subconsulta. Si todos los resultados de las comparaciones son ciertos (TRUE), el operador ALL
devuelve un valor cierto (TRUE).

Ejemplos de ANY
1. Visualizar los nombres de los departamentos que tengan empleados trabajando en ellos..

mysql> SELECT dep_no "Nº Departamento", dnombre Departamento


-> FROM departamentos
-> WHERE dep_no = ANY (SELECT dep_no
-> FROM empleados);

+-----------------+---------------+
| Nº Departamento | Departamento |
+-----------------+---------------+
| 10 | CONTABILIDAD |
| 20 | INVESTIGACION |
| 30 | VENTAS |
+-----------------+---------------+
3 rows in set (0.00 sec)

Página: 39
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

Lo mismo con el operador IN:

mysql> SELECT dep_no "Nº Departamento", dnombre Departamento


-> FROM departamentos
-> WHERE dep_no IN (SELECT dep_no
-> FROM empleados);

+-----------------+---------------+
| Nº Departamento | Departamento |
+-----------------+---------------+
| 10 | CONTABILIDAD |
| 20 | INVESTIGACION |
| 30 | VENTAS |
+-----------------+---------------+
3 rows in set (0.00 sec)

2. Seleccionar aquellos departamentos en los que al menos exista un empleado con comisión nula.

mysql> SELECT dep_no "Nº Departamento", dnombre Departamento


-> FROM departamentos
-> WHERE dep_no = ANY (SELECT DISTINCT dep_no
-> FROM empleados WHERE comision IS NULL);

+-----------------+--------------+
| Nº Departamento | Departamento |
+-----------------+--------------+
| 30 | VENTAS |
+-----------------+--------------+
1 row in set (0.00 sec)

Ejemplos del operador ALL


1. Listar los empleados con mayor salario que todos los del departamento 20

mysql> SELECT dep_no "Nº Departamento", apellido, salario


-> FROM empleados
-> WHERE salario > ALL (SELECT salario
-> FROM empleados
-> WHERE dep_no = 20);

+-----------------+----------+---------+
| Nº Departamento | apellido | salario |
+-----------------+----------+---------+
| 30 | GARRIDO | 3850.12 |
| 10 | REY | 6000.00 |
+-----------------+----------+---------+
2 rows in set (0.00 sec)

2. Listar los departamentos que no tienen empleados

mysql> SELECT dep_no "Nº Departamento",


dnombre "Nombre departamento"
-> FROM departamentos
-> WHERE dep_no <> ALL (SELECT DISTINCT(dep_no)
-> FROM empleados);

Página: 40
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+-----------------+---------------------+
| Nº Departamento | Nombre departamento |
+-----------------+---------------------+
| 40 | PRODUCCION |
+-----------------+---------------------+
1 row in set (0.00 sec)

Como vemos <> ALL es equivalente a NOT IN

c) Operador lógico EXISTS

Se utiliza cuando la condición de selección consiste exclusivamente en comprobar que la subconsulta


devuelve alguna fila seleccionada según la condición incluida en la propia subconsulta. El operador
EXISTS no necesita que la subconsulta devuelva alguna columna porque no utiliza ninguna expresión de
comparación, justificando así la aceptación del * en el formato de la misma.

Formato para la condición de selección con el operador lógico EXISTS

ExpresiónColumna [NOT] EXISTS (Subconsulta)

Una subconsulta expresada con el operador EXISTS también podrá expresarse con el operador IN.
Se utiliza ,sobre todo, con consultas correlacionadas que veremos más adelante.

Ejemplos con el operador lógico EXISTS


1 - Visualizar los departamentos en los que hay más de un trabajador.

mysql> SELECT dep_no, dnombre


-> FROM departamentos e
-> WHERE EXISTS ( SELECT *
-> FROM empleados d
-> WHERE e.dep_no = d.dep_no
-> GROUP BY dep_no
-> HAVING COUNT(*) > 1);

+--------+--------------+
| dep_no | dnombre |
+--------+--------------+
| 10 | CONTABILIDAD |
| 30 | VENTAS |
+--------+--------------+
2 rows in set (0.00 sec)

2. Listar las localidades donde existan departamentos con empleados cuya comisión supere el 10% del
salario.

mysql> SELECT localidad


-> FROM departamentos d
-> WHERE EXISTS (SELECT *
-> FROM empleados e
-> WHERE comision>10*salario/100
AND e.dep_no=d.dep_no);

Página: 41
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+-----------+
| localidad |
+-----------+
| MADRID |
+-----------+
1 row in set (0.00 sec)

Nota: las tablas de departamentos y de empleados necesitan llevar alias para poder realizar parte de la
condición de selección en la subconsulta ya que en ambas existe una columna con el mismo nombre
(dep_no). Esto se verá en el apartado posterior de consultas correlacionadas.

La misma subconsulta podemos expresarla con el operador IN de la siguiente manera:

mysql> SELECT localidad


-> FROM departamentos
-> WHERE dep_no IN (SELECT dep_no
-> FROM empleados
-> WHERE comision>10*salario/100);

+-----------+
| localidad |
+-----------+
| MADRID |
+-----------+
1 row in set (0.00 sec)

Página: 42
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

3 – Subconsultas que devuelven más de una expresión.


Hemos dicho que las subconsultas habitualmente de devuelven una sola expresión pero también pueden devolver
más de una.

Son útiles, sobre todo, cuando la clave ajena de la tabla de la consulta, que se corresponde con una clave primaria
de la tabla de la subconsulta, es compuesta.

3.1 – Formato de consultas que devuelven más de una expresión


Es un formato equivalente, pero la select de la subconsulta devuelve más de una expresión.

( SELECT [ALL/DISTINCT] ExpresionColumna [,ExpresionColumna .....]


FROM NombreTabla [ , NombreTabla ]
[WHERE CondicionSeleccion]
[GROUP BY ExpresionColumnaAgrupacion [,ExpresionColumnaAgrupacion ... ]
[HAVING CondicionSelecionGrupos ] ] )

3.2 - Valores de retorno y condiciones de selección


La condición de selección debe tener en cuenta el número de valores de retorno de la subconsulta y
compararlos con el mismo número de expresiones.

( ExpresionColumna [,ExpresionColumna .... ] ) OperadorComparacion (Subconsulta )

donde OperadorComparacion tiene que ser el operador = o bien el operador IN dependiendo de si


devuelve un valor simple o puede devolver varios valores.

El número de ExpresionColumna en la consulta será igual al número de ExpresionColumna que nos


proporcione el select de la subconsulta

3.3 – Ejemplos de consultas que devuelven más de una expresión


1- Obtener los empleados que pertenecen al mismo departamento y entraron en la empresa el mismo día que
GARRIDO

mysql> SELECT emp_no, apellido


-> FROM empleados
-> WHERE (dep_no,fecha_alta) = (SELECT dep_no, fecha_alta
-> FROM empleados

Página: 43
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

-> WHERE apellido='GARRIDO');

+--------+----------+
| emp_no | apellido |
+--------+----------+
| 7698 | GARRIDO |
+--------+----------+
1 row in set (0.00 sec)

2 - Obtener el empleado que pertenece al mismo departamento que JIMENEZ y tiene el máximo salario

mysql> SELECT emp_no, apellido


-> FROM empleados
-> WHERE (dep_no,salario)=(SELECT dep_no, MAX(salario)
-> FROM empleados
-> WHERE dep_no= (SELECT dep_no
-> FROM empleados
-> WHERE apellido='JIMENEZ')
-> GROUP BY dep_no);

+--------+----------+
| emp_no | apellido |
+--------+----------+
| 7876 | GIL |
+--------+----------+
1 row in set (0.00 sec)

3 - Listar el empleado que tiene el mayor salario de cada departamento

mysql> SELECT dep_no, emp_no, apellido


-> FROM empleados
-> WHERE (dep_no, salario) IN (SELECT dep_no, MAX(salario)
-> FROM empleados
-> GROUP BY dep_no)
-> ORDER BY dep_no;
+--------+--------+----------+
| dep_no | emp_no | apellido |
+--------+--------+----------+
| 10 | 7839 | REY |
| 20 | 7876 | GIL |
| 30 | 7698 | GARRIDO |
+--------+--------+----------+
3 rows in set (0.00 sec)

4 - Visualizar los empleados que tienen el mismo jefe y departamento que ALONSO excluido el
mismo.

mysql> SELECT emp_no, apellido, director, dep_no


-> FROM empleados
-> WHERE (director, dep_no) = (SELECT director, dep_no
-> FROM empleados
-> WHERE apellido = 'ALONSO')
-> AND apellido != 'ALONSO';

+--------+----------+----------+--------+
| emp_no | apellido | director | dep_no |

Página: 44
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+--------+----------+----------+--------+
| 7654 | MARTIN | 7698 | 30 |
| 7844 | CALVO | 7698 | 30 |
+--------+----------+----------+--------+
2 rows in set (0.00 sec)

Ahora para que no suceda lo que en el ejemplo anterior y no se visualice ALONSO, que tiene igual
jefe y departamento que el mismo, hemos añadido en la consulta la condición de que el apellido no
sea ALONSO

Página: 45
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

4 - Subconsultas en la selección de grupos.


Aunque las subconsultas suelen encontrarse sobre todo en la cláusula WHERE, también pueden usarse
en la HAVING formando parte de la selección del grupo de filas efectuada por dicha cláusula.

4.1 – Formato de subconsultas en la cláusula HAVING


Todos los formatos son exactamente iguales a cuando son utilizados en la cláusula WHERE

4.2 – Ejemplos de subconsultas en la cláusula HAVING


1. Visualizar los departamentos en los que el salario medio de sus empleados sea mayor o igual que la
media de todos los salarios de la empresa.

mysql> SELECT dep_no "Nº Departamento",AVG(salario)"Salario Medio"


-> FROM empleados
-> GROUP BY dep_no
-> HAVING AVG(salario)>=(SELECT AVG(salario)
-> FROM empleados);

+-----------------+---------------+
| Nº Departamento | Salario Medio |
+-----------------+---------------+
| 10 | 3266.833333 |
+-----------------+---------------+
1 row in set (0.00 sec)

2. Visualizar los departamentos que tengan mayor media salarial total (salario + comision) que la
mitad de la media salarial total de la empresa.

mysql> SELECT dep_no, AVG(salario+IFNULL(comision,0))


-> FROM empleados
-> GROUP BY dep_no
-> HAVING AVG(salario+IFNULL(comision,0)) >
-> (SELECT AVG(salario+IFNULL(comision,0))/2
-> FROM empleados);

+--------+---------------------------------+
| dep_no | AVG(salario+IFNULL(comision,0)) |
+--------+---------------------------------+
| 10 | 3266.833333 |
| 20 | 2375.000000 |
| 30 | 2637.530029 |
+--------+---------------------------------+
3 rows in set (0.03 sec)

3. Visualizar el departamento con menos presupuesto asignado para pagar el salario de sus
empleados

mysql> SELECT dep_no "Departamento",


SUM(salario) "Mayor Presupuesto"
-> FROM empleados

Página: 46
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

-> GROUP BY dep_no


-> HAVING SUM(salario) = (SELECT SUM(salario)
-> FROM empleados
-> GROUP BY dep_no
-> ORDER BY 1
-> LIMIT 1);

+--------------+-------------------+
| Departamento | Mayor Presupuesto |
+--------------+-------------------+
| 20 | 4750.00 |
+--------------+-------------------+
1 row in set (0.00 sec)

Página: 47
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

5 - Subconsultas anidadas.

5.1 – Anidación de subconsultas


Cuando una subconsulta forma parte de una condición de selección en una cláusula WHERE o HAVING
de otra subconsulta se dice que es una subconsulta anidada.

Las subconsultas se pueden anidar en varias cláusulas a la vez y en varios niveles. Esta posibilidad de
anidamiento es lo que le da potencia a la instrucción select.

5.2 – Ejemplos de subconsultas anidadas


1- Visualizar el número y el nombre del departamento con más personal de oficio VENDEDOR.

mysql> SELECT dep_no "Nº Departamento", dnombre Departamento


-> FROM departamentos
-> WHERE dep_no=(SELECT dep_no
-> FROM empleados
-> WHERE oficio = 'VENDEDOR'
-> GROUP BY dep_no
-> HAVING COUNT(*)=(SELECT COUNT(*)
-> FROM empleados
-> WHERE oficio = 'VENDEDOR'
-> GROUP BY dep_no
-> ORDER BY 1 DESC
-> LIMIT 1));
+-----------------+--------------+
| Nº Departamento | Departamento |
+-----------------+--------------+
| 30 | VENTAS |
+-----------------+--------------+
1 row in set (0.03 sec)

2 - Visualizar los datos, número, nombre y localidad, del departamento donde trabaja el empleado
más antiguo con el mismo oficio que GIL

mysql> SELECT dep_no, dnombre, localidad


-> FROM departamentos
-> WHERE dep_no=(SELECT dep_no
-> FROM empleados
-> WHERE (oficio,fecha_alta)=
-> (SELECT oficio, MIN(fecha_alta)
-> FROM empleados
-> WHERE oficio=(SELECT oficio
-> FROM empleados
-> WHERE apellido='GIL')
-> GROUP BY oficio));
+--------+---------------+-----------+
| dep_no | dnombre | localidad |
+--------+---------------+-----------+
| 20 | INVESTIGACION | VALENCIA |
+--------+---------------+-----------+
1 row in set (0.00 sec)

Página: 48
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

6 – Subconsultas correlacionadas
En una subconsulta podemos hacer referencias a las columnas de la tabla de la consulta. Cuando los
nombres de columnas que aparecen en una subconsulta son nombres de columnas de la consulta principal
o de otra subconsulta más externa, caso de las anidadas, se dice que son referencias externas y la
subconsulta que es correlacionada.

6.1 – Correlación entre consultas


Las subconsultas correlacionadas funcionan de la siguiente forma: cada vez que se procesa una nueva fila
en la consulta principal para decir si esa fila se selecciona o no, se ejecuta la subconsulta. En esa
subconsulta podemos hacer referencia a las columnas de la consulta y los valores serán los de la fila con
la que estamos trabajando en ese momento

Por ejemplo:
Visualizar los empleados que ganan más salario que la media de la empresa

SELECT dep_no "Nº Departamento", oficio, salario


FROM empleados
WHERE salario>(SELECT AVG(salario)
FROM empleados);

La tabla empleados se utiliza en la subconsulta para hallar el salario medio de la empresa y en la consulta
para comprobar las filas que cumplen que el salario de ese empleado sea mayor que el salario medio
calculado en la subconsulta.

Ahora supongamos que lo queremos modificar para que se visualicen los empleados que ganan más que
la media de su departamento. En la subconsulta queremos hallar la media del departamento de cada
empleado, es decir del departamento correspondiente al valor del campo dep_no en esa fila en la
consulta. Por ejemplo si el primer empleado es del departamento 20 debemos calcular la media del del
dep_no=20 para saber si el empleado gana mas que esa media, y si el siguiente empleado es del
departamento 10 ahora deberemos calcular la media del dep_no=10.
Debemos referirnos a los valores de las columnas de la consulta dentro de la subconsulta y como son
sobre la misma tabla tenemos que poner un alias para diferenciarlas.

En una subconsulta correlacionada si coincide el nombre de una columna de una referencia externa con el
nombre de alguna columna de la tabla que está siendo seleccionada en la subconsulta, se deberá
anteponer el nombre de la tabla externa para diferenciarlas. Si las tablas son la misma se deberá asignar
un alias para diferenciarlas.

Hay dos posibilidades:

a) Poner un alias en ambas

SELECT e1.dep_no "Nº Departamento", e1.oficio, salario


FROM empleados e1
WHERE e1.salario>(SELECT AVG(e2.salario)
FROM empleados e2
WHERE e2.dep_no = e1.dep_no);

b) Poner un alias en la tabla de la consulta

SELECT dep_no "Nº Departamento", oficio, salario


FROM empleados e1
WHERE salario>(SELECT AVG(salario)

Página: 49
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

FROM empleados
WHERE dep_no = e1.dep_no);

Esta segunda opción es posible porque dentro de una subconsulta, si no se le indica nada, supone que los
nombres de las columnas corresponden a esa subconsulta. Para referenciar nombre externos es
necesario anteponer el nombre de la tabla de la consulta y si ambas, la consulta y la subconsulta son
sobre la misma tabla, es imprescindible el alias.

6.2 – Ejemplos de subconsultas correlacionadas


1. Visualizar el número de departamento, el oficio y el salario de los empleados con mayor salario de cada
departamento.

mysql> SELECT dep_no "Nº Departamento", oficio, salario


-> FROM empleados e1
-> WHERE salario = (SELECT MAX(salario)
-> FROM empleados e2
-> WHERE e1.dep_no=e2.dep_no);

+-----------------+------------+---------+
| Nº Departamento | oficio | salario |
+-----------------+------------+---------+
| 30 | DIRECTOR | 3850.12 |
| 10 | PRESIDENTE | 6000.00 |
| 20 | ANALISTA | 3350.00 |
+-----------------+------------+---------+
3 rows in set (0.00 sec)

2 - Visualizar el empleado más antiguo de cada oficio


mysql> SELECT oficio, emp_no, apellido, fecha_alta
-> FROM empleados e1
-> WHERE fecha_alta = (SELECT MAX(fecha_alta)
-> FROM empleados
-> WHERE oficio=e1.oficio);

+------------+--------+----------+------------+
| oficio | emp_no | apellido | fecha_alta |
+------------+--------+----------+------------+
| VENDEDOR | 7654 | MARTIN | 1981-09-28 |
| DIRECTOR | 7782 | MARTINEZ | 1981-06-09 |
| PRESIDENTE | 7839 | REY | 1981-11-17 |
| ANALISTA | 7876 | GIL | 1982-05-06 |
| EMPLEADO | 7900 | JIMENEZ | 1983-03-24 |
+------------+--------+----------+------------+
5 rows in set (0.02 sec)

3 - Visualizar los empleados que tienen el menor salario de cada departamento


mysql> SELECT oficio, emp_no, apellido, salario
-> FROM empleados e1
-> WHERE salario = (SELECT MIN(salario)
-> FROM empleados
-> WHERE dep_no=e1.dep_no);

+----------+--------+----------+---------+

Página: 50
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

| oficio | emp_no | apellido | salario |


+----------+--------+----------+---------+
| VENDEDOR | 7499 | ALONSO | 1400.00 |
| EMPLEADO | 7521 | LOPEZ | 1350.50 |
| EMPLEADO | 7900 | JIMENEZ | 1400.00 |
+----------+--------+----------+---------+
3 rows in set (0.00 sec)

Página: 51
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

TEMA 8. CONSULTAS MULTITABLA

Paulina Barthelemy

1 - Multiplicaciones de tablas.
Hasta ahora, las órdenes SQL que hemos utilizado están basadas en una única tabla, pero a menudo es
necesario utilizar datos procedentes de dos o más tablas de la base de datos.

Para poder acceder a dos o más tablas de una base de datos, SQL genera internamente una tabla en la que
cada fila de una tabla se combina con todas y cada una de las filas de las demás tablas indicadas. Esta
operación es el producto cartesiano de las tablas que se están accediendo y la tabla resultante contiene
todas las columnas de todas las tablas que se han multiplicado.

Pueden unirse tantas tablas como se desee (aunque la experiencia aconseja que no sean muchas por
optimización).

Comenzaremos con el formato más sencillo de multiplicación de tablas, reseñando solo las cláusulas
significativas para realizar el producto.
Pueden ser utilizadas todas las cláusulas de selección vistas anteriormente y al final indicaremos el
formato completo.

1.1 – Formato de la multiplicación de tablas


El formato más senillo para realizar un producto de tablas es:

SELECT [ALL/DISTINCT] ExpresionColumna [,ExpresionColumna .....]


FROM NombreTabla [AliasTabla] [ , NombreTabla [AliasTabla] ....]

Notación: el nombre de tabla puede aparecer una o varias veces, separados por comas.

En la SELECT pueden seleccionarse columnas de ambas tablas. Si hay columnas con el mismo nombre en
las distintas tablas de la FROM, deben identificarse como NombreTabla.NombreColumna o
AliasTabla.NombreColumna. Para no tener que escribir siempre el nombre de la tabla, por comodidad,
se suele utilizar un alias para cada tabla eligiendo un nombre corto (1 o 2 caracteres) que identifique a
cada tabla. En algún caso, que veremos más adelante, este alias será imprescindible.

Página: 52
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

1.2 – Ejemplos de la multiplicación de tablas


Veremos la salida que produce la multiplicación, o producto cartesiano, de dos tablas con un ejemplo para
obtener todos los empleados, indicando su número de empleado, su apellido, el nombre de su departamento y
su localidad de este.

mysql> SELECT emp_no "Nº EMPLEADO", apellido "APELLIDO",


-> dnombre "DEPARTAMENTO" , localidad "LOCALIDAD"
-> FROM empleados, departamentos;

+-------------+----------+---------------+-----------+
| Nº EMPLEADO | APELLIDO | DEPARTAMENTO | LOCALIDAD |
+-------------+----------+---------------+-----------+
| 7499 | ALONSO | CONTABILIDAD | BARCELONA |
| 7499 | ALONSO | INVESTIGACION | VALENCIA |
| 7499 | ALONSO | VENTAS | MADRID |
| 7499 | ALONSO | PRODUCCION | SEVILLA |
| 7521 | LOPEZ | CONTABILIDAD | BARCELONA |
| 7521 | LOPEZ | INVESTIGACION | VALENCIA |
| 7521 | LOPEZ | VENTAS | MADRID |
| 7521 | LOPEZ | PRODUCCION | SEVILLA |
| 7654 | MARTIN | CONTABILIDAD | BARCELONA |
| 7654 | MARTIN | INVESTIGACION | VALENCIA |
| 7654 | MARTIN | VENTAS | MADRID |
| 7654 | MARTIN | PRODUCCION | SEVILLA |
| 7698 | GARRIDO | CONTABILIDAD | BARCELONA |
| 7698 | GARRIDO | INVESTIGACION | VALENCIA |
| 7698 | GARRIDO | VENTAS | MADRID |
| 7698 | GARRIDO | PRODUCCION | SEVILLA |
| 7782 | MARTINEZ | CONTABILIDAD | BARCELONA |
| 7782 | MARTINEZ | INVESTIGACION | VALENCIA |
| 7782 | MARTINEZ | VENTAS | MADRID |
| 7782 | MARTINEZ | PRODUCCION | SEVILLA |
| 7839 | REY | CONTABILIDAD | BARCELONA |
| 7839 | REY | INVESTIGACION | VALENCIA |
| 7839 | REY | VENTAS | MADRID |
| 7839 | REY | PRODUCCION | SEVILLA |
| 7844 | CALVO | CONTABILIDAD | BARCELONA |
| 7844 | CALVO | INVESTIGACION | VALENCIA |
| 7844 | CALVO | VENTAS | MADRID |
| 7844 | CALVO | PRODUCCION | SEVILLA |
| 7876 | GIL | CONTABILIDAD | BARCELONA |
| 7876 | GIL | INVESTIGACION | VALENCIA |
| 7876 | GIL | VENTAS | MADRID |
| 7876 | GIL | PRODUCCION | SEVILLA |
| 7900 | JIMENEZ | CONTABILIDAD | BARCELONA |
| 7900 | JIMENEZ | INVESTIGACION | VALENCIA |
| 7900 | JIMENEZ | VENTAS | MADRID |
| 7900 | JIMENEZ | PRODUCCION | SEVILLA |
+-------------+----------+---------------+-----------+
36 rows in set (0.00 sec)

Cada empleado de la tabla de empleados aparece tantas veces como departamentos hay en la tabla de
departamentos, con los correspondientes valores de cada de las filas de la tabla departamentos.
Se obtienen, por tanto, 9 x 4= 36 filas.

Página: 53
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

2 - Composiciones o combinaciones simples (JOIN)


Acabamos de ver, en el ejemplo anterior, que la salida producida por la multiplicación de las tablas de
empleados y de departamentos no tiene mucho sentido y poca aplicación.

La solución más adecuada del ejemplo sería enlazar la tabla empleados con la tabla departamentos
de forma que para cada empleado de la tabla empleados solo tengamos de la tabla departamentos la
fila correspondiente a su departamento.
Es decir:

mysql> SELECT emp_no "Nº EMPLEADO", apellido "APELLIDO",


dnombre DEPARTAMENTO, localidad "LOCALIDAD"
-> FROM empleados, departamentos
-> WHERE empleados.dep_no = departamentos.dep_no;

+-------------+----------+---------------+-----------+
| Nº EMPLEADO | APELLIDO | DEPARTAMENTO | LOCALIDAD |
+-------------+----------+---------------+-----------+
| 7521 | LOPEZ | CONTABILIDAD | BARCELONA |
| 7782 | MARTINEZ | CONTABILIDAD | BARCELONA |
| 7839 | REY | CONTABILIDAD | BARCELONA |
| 7876 | GIL | INVESTIGACION | VALENCIA |
| 7900 | JIMENEZ | INVESTIGACION | VALENCIA |
| 7499 | ALONSO | VENTAS | MADRID |
| 7654 | MARTIN | VENTAS | MADRID |
| 7698 | GARRIDO | VENTAS | MADRID |
| 7844 | CALVO | VENTAS | MADRID |
+-------------+----------+---------------+-----------+
9 rows in set (0.00 sec)

Hemos visto que la salida que produce el producto de las tablas es cada fila de una tabla combinadas con
todas las de otra tabla. Esta información no suele ser la deseada. Aparecen las composiciones o
combinaciones de tablas que nos proporcionan la misma información pero filtrada. Una composición o
combinación (join) consiste en aplicar una condición de selección a las filas obtenidas de la multiplicación
de las tablas sobre las que se está realizando una consulta.

2.1 – Formato de la combinación de tablas

SELECT [ALL/DISTINCT] ExpresionColumna [,ExpresionColumna .....]

FROM NombreTabla [AliasTabla] [ , NombreTabla [AliasTabla].....]


[WHERE CondicionComposicion ]

Notación: la cláusula WHERE es opcional y por eso aparece entre corchetes.

donde CondicionComposicion ......es una condición que selecciona las filas de la composición de las
tablas.

Página: 54
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

La condición de selección o criterio de emparejamiento para las tablas también se denomina condición o
criterio de composición.

Dependiendo de la condición de composición tendremos las combinaciones naturales, basadas en la


igualdad, o las combinaciones basadas en la desigualdad.

Existen varios tipos según sea esta condición de composición


• Composición natural: es la más sencilla y natural y es aquella en que la condición de selección se
establece con el operador de igualdad entre las columnas que deban coincidir exactamente en tablas
diferentes.
• Composición basada en desigualdad: es menos utilizada y consiste en que la condición de
selección no sea una igualdad.

Página: 55
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

3- Composición o combinación natural


Como hemos dicho la composición o combinación natural es la más sencilla y natural. Es aquella en que
la condición de selección se establece con el operador de igualdad entre las columnas que deben coincidir
exactamente en tablas diferentes.

Suele utilizarse para unir tablas en las que hay una relación a través de las claves ajenas, uniendo una
tabla con su referenciada.

Veamos con el ejemplo porqué es la forma más natural:

mysql> SELECT emp_no "Nº EMPLEADO", apellido "APELLIDO",


dnombre DEPARTAMENTO, localidad "LOCALIDAD"
-> FROM empleados, departamentos
-> WHERE empleados.dep_no = departamentos.dep_no;

+-------------+----------+---------------+-----------+
| Nº EMPLEADO | APELLIDO | DEPARTAMENTO | LOCALIDAD |
+-------------+----------+---------------+-----------+
| 7521 | LOPEZ | CONTABILIDAD | BARCELONA |
| 7782 | MARTINEZ | CONTABILIDAD | BARCELONA |
| 7839 | REY | CONTABILIDAD | BARCELONA |
| 7876 | GIL | INVESTIGACION | VALENCIA |
| 7900 | JIMENEZ | INVESTIGACION | VALENCIA |
| 7499 | ALONSO | VENTAS | MADRID |
| 7654 | MARTIN | VENTAS | MADRID |
| 7698 | GARRIDO | VENTAS | MADRID |
| 7844 | CALVO | VENTAS | MADRID |
+-------------+----------+---------------+-----------+
9 rows in set (0.00 sec)

Si obtenemos el producto cartesiano de las tablas empleados por departamentos para cada empleado
obtenemos la combinación con todas las filas de departamento. Pero la única que nos interesará será la
del departamento al que pertenezca el empleado, es decir la que cumpla la condición:
departamento.dep_no = empleado.dep_no

SQL resuelve el anterior ejercicio con el siguiente proceso:

• La cláusula FROM genera todas las combinaciones posibles de filas de la tabla de empleados (9 filas)
por las de la tabla de departamentos (4 filas), resultando una tabla producto de 4x9=36 filas.
• La cláusula WHERE selecciona únicamente aquellas filas de la tabla producto donde coinciden los
números de departamento, que necesitan el nombre de la tabla o el alias por tener el mismo nombre
en ambas tablas. En total se han seleccionado 9 filas y las 27 restantes se eliminan.
• La sentencia SELECT visualiza las columnas especificadas de las tablas producto para las filas
seleccionadas.

SQL no exige que las columnas de emparejamiento estén relacionadas como clave primaria y clave ajena,
aunque suele ser lo habitual. Pueden servir cualquier par de columnas de dos tablas, siempre que tengan
tipos de datos comparables.

Página: 56
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

3.1 – Formato de la combinación natural de tablas


Es el mismo de la combinación o composición pero donde la condición de composición es una
igualdad entre campos de diferentes tablas:

[NombreTabla1.] NombreColumna1 = [NombreTabla2.] NombreColumna2

Los nombres de las columnas necesitarán anteponer el nombre de la tabla o el alias si el nombre es el
mismo en ambas tablas.

3.2 – Ejemplos de combinación natural de tablas


1. Obtener los distintos departamentos existentes en la tabla de empleados.

mysql> SELECT DISTINCT d.dep_no "Nº Departamento",


d.dnombre Departamento
-> FROM empleados e, departamentos d
-> WHERE e.dep_no = d.dep_no;

+-----------------+---------------+
| Nº Departamento | Departamento |
+-----------------+---------------+
| 10 | CONTABILIDAD |
| 20 | INVESTIGACION |
| 30 | VENTAS |
+-----------------+---------------+
3 rows in set (0.02 sec)

2. Mostrar los siguientes datos relativos a empleados: número, apellido, nombre de departamento y
localidad.

mysql> SELECT emp_no "Nº Empleado", apellido, dnombre, localidad


-> FROM empleados e, departamentos d
-> WHERE e.dep_no = d.dep_no;

+-------------+----------+---------------+-----------+
| Nº Empleado | apellido | dnombre | localidad |
+-------------+----------+---------------+-----------+
| 7521 | LOPEZ | CONTABILIDAD | BARCELONA |
| 7782 | MARTINEZ | CONTABILIDAD | BARCELONA |
| 7839 | REY | CONTABILIDAD | BARCELONA |
| 7876 | GIL | INVESTIGACION | VALENCIA |
| 7900 | JIMENEZ | INVESTIGACION | VALENCIA |
| 7499 | ALONSO | VENTAS | MADRID |
| 7654 | MARTIN | VENTAS | MADRID |
| 7698 | GARRIDO | VENTAS | MADRID |
| 7844 | CALVO | VENTAS | MADRID |
+-------------+----------+---------------+-----------+
9 rows in set (0.02 sec)

Página: 57
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

4 - Composiciones o combinaciones basadas en


desigualdad
La condición de selección que establezcamos para componer o combinar tablas no tiene porqué ser siempre
mediante el operador aritmético de igualdad, aunque su uso sea el más frecuente. SQL permite utilizar
cualquier operador aritmético de comparación.
Estas composiciones son aquellas en las que el operador de la condición de selección NO es la igualdad.

4.1 – Formato de combinaciones basadas en desigualdad


Es el mismo de la combinación o composición pero la condición de composición es diferente de la
igualdad entre campos de diferentes tablas.

4.2 – Ejemplos de combinaciones basadas en desigualdad


1. Listar los empleados de los departamentos diferentes al de VENTAS.

mysql> SELECT e.emp_no "NºEmpleado",e.apellido "Apellido"


-> FROM empleados e,departamentos d
-> WHERE d.dnombre = 'VENTAS' AND e.dep_no != d.dep_no;

+------------+----------+
| NºEmpleado | Apellido |
+------------+----------+
| 7521 | LOPEZ |
| 7782 | MARTINEZ |
| 7839 | REY |
| 7876 | GIL |
| 7900 | JIMENEZ |
+------------+----------+
5 rows in set (0.00 sec)

2. Listar los empleados de departamentos con códigos mayores que el código del departamento de
contabilidad.

mysql> SELECT e.emp_no "NºEmpleado",e.apellido


-> FROM empleados e,departamentos d
-> WHERE d.dnombre = 'CONTABILIDAD' AND e.dep_no>d.dep_no;

+------------+----------+
| NºEmpleado | apellido |
+------------+----------+
| 7499 | ALONSO |
| 7654 | MARTIN |
| 7698 | GARRIDO |
| 7844 | CALVO |
| 7876 | GIL |
| 7900 | JIMENEZ |
+------------+----------+
6 rows in set (0.00 sec)

3. Listar los empleados de departamentos con códigos menores que el código del departamento de

Página: 58
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

Barcelona

mysql> SELECT e.emp_no "NºEmpleado",e.apellido


-> FROM empleados e,departamentos d
-> WHERE d.localidad = 'BARCELONA'
AND e.dep_no > d.dep_no;

+------------+----------+
| NºEmpleado | apellido |
+------------+----------+
| 7499 | ALONSO |
| 7654 | MARTIN |
| 7698 | GARRIDO |
| 7844 | CALVO |
| 7876 | GIL |
| 7900 | JIMENEZ |
+------------+----------+
6 rows in set (0.00 sec)

Página: 59
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

5 - Composiciones o combinaciones de una tabla consigo


misma
Si desde una fila de una tabla podemos acceder a otra fila de la misma tabla, duplicando la tabla, estamos
realizando una composición o combinación de una tabla consigo misma.

5.1 - Formato de una combinación de una tabla consigo misma.


Es el mismo de la combinación o composición pero las tablas del producto son las mismas tablas.

En este caso, como ambas tablas se llaman igual, es necesario obligatoriamente un alias para
diferenciar las columnas de cada tabla.

5.2 - Ejemplos de una combinación de una tabla consigo misma


1. Obtener la lista de los empleados con los nombres de sus directores.

mysql> SELECT e1.emp_no "NºEmpleado",


e1.apellido "Nombre Empleado",
e1.director "NºDirector",
e2.apellido "Nombre Director"
-> FROM empleados e1,empleados e2
-> WHERE e1.director=e2.emp_no;

+------------+-----------------+------------+-----------------+
| NºEmpleado | Nombre Empleado | NºDirector | Nombre Director |
+------------+-----------------+------------+-----------------+
| 7499 | ALONSO | 7698 | GARRIDO |
| 7521 | LOPEZ | 7782 | MARTINEZ |
| 7654 | MARTIN | 7698 | GARRIDO |
| 7698 | GARRIDO | 7839 | REY |
| 7782 | MARTINEZ | 7839 | REY |
| 7844 | CALVO | 7698 | GARRIDO |
| 7876 | GIL | 7782 | MARTINEZ |
| 7900 | JIMENEZ | 7782 | MARTINEZ |
+------------+-----------------+------------+-----------------+
8 rows in set (0.00 sec)

Cada empleado de la tabla tiene una columna para su número de empleado (emp_no) y otra para el
número de empleado de su director (director). A partir del dato de la columna director de un empleado se
puede acceder a otro empleado que contenga el mismo dato en su columna emp_no. Las dos filas de la
tabla se están relacionando a través de las columnas director y emp_no.
El uso de alias es obligado por tratarse de la misma tabla y coincidir los nombres de las columnas.

Página: 60
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

2. Obtener los jefes de los empleados cuyo oficio sea el de VENDEDOR.

mysql> SELECT e1.emp_no "NºEmpleado", e1.apellido, e1.oficio,


-> e1.director "NºDirector", e2.apellido "Nombre Director"
-> FROM empleados e1, empleados e2
-> WHERE e1.director = e2.emp_no AND e1.oficio = 'VENDEDOR';

+------------+----------+----------+-------------+-----------------+
| NºEmpleado | apellido | oficio | NºDirector | Nombre Director |
+------------+----------+----------+-------------+-----------------+
| 7499 | ALONSO | VENDEDOR | 7698 | GARRIDO |
| 7654 | MARTIN | VENDEDOR | 7698 | GARRIDO |
| 7844 | CALVO | VENDEDOR | 7698 | GARRIDO |
+------------+----------+----------+-------------+-----------------+
3 rows in set (0.00 sec)

Página: 61
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

6 - Composiciones o combinaciones externas (OUTER JOIN)


Cuando se realiza una composición o combinación de tablas estableciendo una determinada relación entre
sus columnas, puede ocurrir que no se emparejen todas las filas que debieran por faltar correspondencia
entre algunas de ellas. Esto se debe a que existen filas en alguna tabla que no tienen correspondencia en
la otra tabla y al aplicar la condición de selección de la composición no se seleccionarán.

Por ejemplo
mysql> SELECT dnombre Departamento, localidad, emp_no, apellido
-> FROM empleados e,departamentos d
-> WHERE e.dep_no=d.dep_no;
+---------------+-----------+--------+----------+
| Departamento | localidad | emp_no | apellido |
+---------------+-----------+--------+----------+
| CONTABILIDAD | BARCELONA | 7521 | LOPEZ |
| CONTABILIDAD | BARCELONA | 7782 | MARTINEZ |
| CONTABILIDAD | BARCELONA | 7839 | REY |
| INVESTIGACION | VALENCIA | 7876 | GIL |
| INVESTIGACION | VALENCIA | 7900 | JIMENEZ |
| VENTAS | MADRID | 7499 | ALONSO |
| VENTAS | MADRID | 7654 | MARTIN |
| VENTAS | MADRID | 7698 | GARRIDO |
| VENTAS | MADRID | 7844 | CALVO |
+---------------+-----------+--------+----------+
9 rows in set (0.00 sec)

Aquellos departamentos que no tengan empleados no aparecerán porque para esos departamentos no se
cumplirá la igualdad empleados.dep_no = departamentos.dep_no

Es aconsejable que la salida, obtenida por una consulta en la que se pudiera presentar esta posibilidad,
muestre todas las filas, aunque algunas con falta de información. Para conseguir este resultado se utiliza
la composición o combinación externa (OUTER JOIN).

6.1 – Formato de combinaciones externas


SELECT [ALL/DISTINCT] ExpresionColumna [,ExpresionColumna .....]
FROM NombreTabla [AliasTabla]

{LEFT|RIGHT [OUTER] JOIN NombreTabla [AliasTabla].....]

ON CondicionComposicion

donde LEFT|RIGHT [OUTER] JOIN………........ indica que es un join externo y si la extensión del
producto de las tablas se quiere realizar por la
izquierda o por la derecha
CondicionComposicion ……………….. es la misma condición de composición anterior, pero
escrita aquí en lugar de en la cláusula WHERE

El funcionamiento de un join externo es el siguiente:


• LEFT JOIN: join donde se obtienen todas las filas de la tabla de la izquierda, aunque no

Página: 62
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

tenga correspondencia en la tabla de la derecha.


Realiza el producto cartesiano de las tablas que se le indican, aplica la condición de
composición (expresada en la cláusula ON) al resultado de este producto cartesiano y añade,
por cada fila de la tabla de la izquierda que no tenga correspondencia en la tabla de la
derecha, una fila con los valores de la tabla de la izquierda y en la tabla de la derecha valores
NULL en todas las columnas.
• RIGHT JOIN: join donde se obtienen todas las filas de la tabla de la derecha, aunque no
tengan correspondencia en la tabla de la izquierda.
Realiza el producto cartesiano de las tablas que se le indican, aplica la condición de
composición (expresada en la cláusula ON) al resultado de este producto cartesiano y añade,
por cada fila de la tabla de la derecha que no tenga correspondencia en la tabla de la
izquierda, una fila con los valores de la tabla de la derecha y en la tabla de la izquierda
valores NULL en todas las columnas.

Por ejemplo si queremos visualizar los datos de los departamentos y de sus empleados, visualizando
también los departamentos que no tengan empleados.

mysql> SELECT dnombre Departamento, localidad,


emp_no "Nº empleado", apellido
-> FROM departamentos d LEFT JOIN empleados e
-> ON d.dep_no=e.dep_no;

+---------------+-----------+------------+----------+
| Departamento | localidad | Nºempleado | apellido |
+---------------+-----------+------------+----------+
| CONTABILIDAD | BARCELONA | 7521 | LOPEZ |
| CONTABILIDAD | BARCELONA | 7782 | MARTINEZ |
| CONTABILIDAD | BARCELONA | 7839 | REY |
| INVESTIGACION | VALENCIA | 7876 | GIL |
| INVESTIGACION | VALENCIA | 7900 | JIMENEZ |
| VENTAS | MADRID | 7499 | ALONSO |
| VENTAS | MADRID | 7654 | MARTIN |
| VENTAS | MADRID | 7698 | GARRIDO |
| VENTAS | MADRID | 7844 | CALVO |
| PRODUCCION | SEVILLA | NULL | NULL |
+---------------+-----------+------------+----------+
10 rows in set (0.00 sec)

Aparecerán todas las filas de la tabla DEPARTAMENTOS, tanto si tienen correspondencia en la tabla
EMPLEADOS como si no la tienen. Los departamentos que no tengan empleados también aparecerían. El
departamento de PRODUCCIÓN no tiene ningún empleado asignado y se añade una fila en la tabla
empleados con todos los campo con valor NULL en correspondencia.

Obtendremos el mismo resultado si cambiamos LEFT por RIGHT el orden de las tablas

mysql> SELECT dnombre Departamento, localidad,


-> emp_no "Nº empleado", apellido
-> FROM empleados e RIGHT JOIN departamentos d
-> ON d.dep_no=e.dep_no;

+---------------+-----------+-------------+----------+
| Departamento | localidad | Nº empleado | apellido |
+---------------+-----------+-------------+----------+
| CONTABILIDAD | BARCELONA | 7521 | LOPEZ |

Página: 63
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

| CONTABILIDAD | BARCELONA | 7782 | MARTINEZ |


| CONTABILIDAD | BARCELONA | 7839 | REY |
| INVESTIGACION | VALENCIA | 7876 | GIL |
| INVESTIGACION | VALENCIA | 7900 | JIMENEZ |
| VENTAS | MADRID | 7499 | ALONSO |
| VENTAS | MADRID | 7654 | MARTIN |
| VENTAS | MADRID | 7698 | GARRIDO |
| VENTAS | MADRID | 7844 | CALVO |
| PRODUCCION | SEVILLA | NULL | NULL |
+---------------+-----------+-------------+----------+
10 rows in set (0.00 sec)

Hay casos en los que hacer el OUTER JOIN obtendremos el mismo resultado con una combinación
natural, ya que no hay filas sin correspondencia en la tabla de la correspondencia.

mysql> SELECT emp_no "Nºempleado", apellido,


dnombre "Departamento", localidad
-> FROM departamentos d RIGHT JOIN empleados e
-> ON d.dep_no=e.dep_no;

+------------+----------+---------------+-----------+
| Nºempleado | apellido | Departamento | localidad |
+------------+----------+---------------+-----------+
| 7499 | ALONSO | VENTAS | MADRID |
| 7521 | LOPEZ | CONTABILIDAD | BARCELONA |
| 7654 | MARTIN | VENTAS | MADRID |
| 7698 | GARRIDO | VENTAS | MADRID |
| 7782 | MARTINEZ | CONTABILIDAD | BARCELONA |
| 7839 | REY | CONTABILIDAD | BARCELONA |
| 7844 | CALVO | VENTAS | MADRID |
| 7876 | GIL | INVESTIGACION | VALENCIA |
| 7900 | JIMENEZ | INVESTIGACION | VALENCIA |
+------------+----------+---------------+-----------+
9 rows in set (0.00 sec)

Aparecerán todas las filas de la tabla EMPLEADOS, tanto si tienen correspondencia en la tabla
DEPARTAMENTOS como si no. Los empleados que no tuviesen departamento asignado también
aparecerían. En este ejemplo como todos los empleados tienen departamento asignado el resultado es el
mismo.

6.2 – Ejemplos de combinaciones externas


1. Obtener los departamentos con su nombre y localidad y el número de empleados trabajando en ellos,
incluyendo los que no tienen empleados.

mysql> SELECT dnombre Departamento, localidad, COUNT(emp_no)


-> FROM departamentos d LEFT JOIN empleados e
-> ON d.dep_no=e.dep_no
-> GROUP BY dnombre, localidad;

+---------------+-----------+---------------+
| Departamento | localidad | COUNT(emp_no) |
+---------------+-----------+---------------+
| CONTABILIDAD | BARCELONA | 3 |

Página: 64
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

| INVESTIGACION | VALENCIA | 2 |
| PRODUCCION | SEVILLA | 0 |
| VENTAS | MADRID | 4 |
+---------------+-----------+---------------+
4 rows in set (0.00 sec)

2. Obtener la lista de empleados con los nombres de sus directores, incluyendo al PRESIDENTE. (Ejemplo
en autocomposiciones) .

mysql> SELECT e1.apellido "Nombre Empleado",


e2.apellido "Nombre Director"
-> FROM empleados e1 LEFT JOIN empleados e2
-> ON e1.director = e2.emp_no;

+----------+-----------------+
| apellido | Nombre Director |
+----------+-----------------+
| ALONSO | GARRIDO |
| LOPEZ | MARTINEZ |
| MARTIN | GARRIDO |
| GARRIDO | REY |
| MARTINEZ | REY |
| REY | NULL |
| CALVO | GARRIDO |
| GIL | MARTINEZ |
| JIMENEZ | MARTINEZ |
+----------+-----------------+
9 rows in set (0.00 sec)

Página: 65
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

7 - Composiciones y subconsultas
Hay ocasiones en que una consulta puede resolverse con una composición o combinación (join) de tablas o
con una subconsulta.

Si puede solucionarse de ambas formas será preferible hacerlo con una subconsulta. El producto
cartesiano es muy costoso pues hay que multiplicar todas las filas de una tabla por todas las de la otra
tabla para después seleccionar solo algunas. Con tablas con miles o millones de registros esto es un
trabajo muy costoso en tiempo y memoria, que puede resolver con una subconsulta.

En general, si no se necesita visualizar columnas de más de una tabla, se debe utilizar una subconsulta.
Solamente si se necesita visualizar columnas de más de una tabla, se usará una composición o
combinación.

Vamos a verlo con unos ejemplos:

1- Con subconsulta:
Obtener apellido y oficio de los empleados que tienen el mismo oficio y mismo número de departamento
que el de INVESTIGACIÓN.

mysql> SELECT apellido, oficio


-> FROM empleados
-> WHERE oficio IN (SELECT oficio
-> FROM empleados
-> WHERE dep_no IN (SELECT dep_no
-> FROM departamentos
-> WHERE dnombre='INVESTIGACION'));

+----------+----------+
| apellido | oficio |
+----------+----------+
| LOPEZ | EMPLEADO |
| GIL | ANALISTA |
| JIMENEZ | EMPLEADO |
+----------+----------+
3 rows in set (0.00 sec)

Puede solucionarse con una subconsulta porque solo nos piden visualizar campos de la tabla
empleados. Debe solucionarse, por tanto, utilizarse una subconsulta.

2- Con composición de las tablas:


Obtener apellido, el oficio y la localidad del departamento de los empleados que tienen el mismo oficio y
mismo número de departamento que el de INVESTIGACIÓN.

mysql> SELECT apellido, oficio, localidad


-> FROM empleados e, departamentos d
-> WHERE oficio IN (SELECT oficio
-> FROM empleados
-> WHERE e.dep_no = d.dep_no
AND d.dnombre = 'INVESTIGACION');

Página: 66
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+----------+----------+-----------+
| apellido | oficio | localidad |
+----------+----------+-----------+
| GIL | ANALISTA | VALENCIA |
| JIMENEZ | EMPLEADO | VALENCIA |
+----------+----------+-----------+
2 rows in set (0.00 sec)

Es el mismo ejercicio pero, en este ejemplo, nos piden visualizar campos de la tabla empleados
y de la tabla departamentos. No puede solucionarse con una subconsulta y debe, por tanto,
solucionarse con un producto de ambas tablas.

Página: 67
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

8 - Formato completo de las consultas


Aunque hasta ahora no hemos utilizado todas las cláusulas estudiadas, en la composición de tablas
está permitidas todas ellas. Podemos hacer selección de filas, agrupamientos, selección de grupo,
ordenación y limitar el número de filas de igual forma que lo hacíamos para consultas con una sola
tabla

SELECT { * | [ALL/DISTINCT] ExpresionColumna [AliasColumna]


[, ExpresionColumna [AliasColumna]....] }
FROM NombreTabla [AliasTabla] [,NombreTabla [AliasTabla]....]
[WHERE { CondicionSeleccion | CondicionComposicion }]
[GROUP BY ExpresionColumna|Posicion [, ExpresionColumna|Posicion ... ]
[HAVING CondicionSelecionGrupos ] ]
[ORDER BY {ExpresionColumna|Posicion } [ASC|DESC]
[,{ExpresionColumna|Posicion } [ASC|DESC].....] ]
[LIMIT [m, ] n ] ;

Página: 68
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

TEMA 9. CONSULTAS DENTRO DE OTRAS


INSTRUCCIONES

Paulina Barthelemy

1 - Creación de una tabla a partir de una selección de otra


tabla.
En el momento de crear una tabla podemos utilizar la definición de otra ya creada, utilizando toda la
definición o aquella parte que no interese.

1.1 – Formato para la creación de una tabla a partir de una selección


de otra tabla.

CREATE TABLE [IF NOT EXISTS] NombreTabla


[( DefinicionColumna [, DefinicionColumna ...] )] [ IGNORE|REPLACE ]
SentenciaSelect

Notación: las definiciones de las columnas son opcionales, por lo que están entre corchetes.

donde NombreTabla ..................... es el identificador de la nueva tabla que se crea


SentenciaSelect ..................... es cualquier sentencia select
IGNORE|REPLACE ................ opciones de duplicados en campos únicos

Los nombres de las columnas de la nueva tabla son opcionales. En caso de que no se especifique
tomarán los valores de la otra tabla o de los alias correspondientes. Pero debe tenerse cuidado con
ello pues si hay expresiones o funciones en la lista del select y no tienen alias ni nuevo nombre, luego
estas columnas no pueden referenciarse.

Las opciones de duplicados en campos únicos (claves primarias o unique) permiten indicar que hacer
si hay un valor repetido en ese campo. Si no se indica nada se producirá un error. Para evitar esto
errores podemos especificar una de las dos opciones IGNORE que ignora la fila y no la graba y
REPLACE que reemplaza la fila por la anterior.

La nueva tabla creada no hereda las CONSTRAINTS que tenga asignada la tabla origen. Esto es para dar
más flexibilidad al sistema. Si se desea que la nueva tabla tenga constraints deben indicarse en la
creación o añadirse posteriormente con ALTER TABLE. Es importante recordarlo para que la nueva tabla
quede con la definición completa.

Página: 69
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

Al crear la nueva tabla además se insertan las filas correspondientes de la tabla resultado de la sentencia
select en la instrucción de creación.

1.2 – Ejemplos de la creación de una tabla a partir de una selección


de otra tabla.
1. Crear una tabla de vendedores seleccionando éstos de la tabla de empleados.

mysql> CREATE TABLE vendedores


-> SELECT *
-> FROM empleados
-> WHERE oficio = 'VENDEDOR';
Query OK, 3 rows affected (0.13 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM vendedores;


+--------+----------+---------+---------+------------+---------+---------+--------+
| EMP_NO | APELLIDO | OFICIO |DIRECTOR | FECHA_ALTA | SALARIO | COMISION | DEP_NO|
+--------+----------+---------+---------+------------+---------+----------+-------+
| 7499 | ALONSO | VENDEDOR| 7698 | 1981-02-23 | 1400.00 | 650.00 | 30 |
| 7654 | MARTIN | VENDEDOR| 7698 | 1981-09-28 | 1500.00 | 1850.00 | 30 |
| 7844 | CALVO | VENDEDOR| 7698 | 1981-09-08 | 1800.00 | 250.00 | 30 |
+--------+----------+---------+---------+------------+---------+---------+--------+
3 rows in set (0.00 sec)

2. Crear una nueva tabla sólo con los nombres y números de los departamentos a partir de la tabla ya
creada con los mismos.

mysql> CREATE TABLE nombres_dep (depart_no INT(4),


nombre VArchar(10))
-> SELECT dep_no, dnombre
-> FROM departamentos;
Query OK, 4 rows affected (0.23 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM nombres_dep;


+--------+---------------+
| dep_no | dnombre |
+--------+---------------+
| 10 | CONTABILIDAD |
| 20 | INVESTIGACION |
| 30 | VENTAS |
| 40 | PRODUCCION |
+--------+---------------+
4 rows in set (0.00 sec)

Página: 70
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

2 - Actualización de una tabla a partir de una subconsulta


Todas las instrucciones de actualización de datos que hemos visto pueden ampliarse con la
utilización de subconsultas dentro de ellas.

2.1- Inserciones con subconsultas


Podemos insertar en una tabla el resultado de una consulta sobre otra tabla. En este caso normalmente se
insertarán varias filas con una sola sentencia. Utilizaremos el siguiente formato:

INSERT INTO NombreTabla [( NombreColumna [,NombreColumna...] ) ]


SELECT FormatoSelect

Notación: la lista de columnas en las que insertamos va es opcional, por lo que va entre
corchetes.

En el formato anterior podemos destacar:


• La lista de columnas es opcional pero deberá especificarse cuando las columnas que devuelve la
consulta no coinciden en número o en orden con las columnas de la tabla destino.
• La consulta puede ser cualquier comando de selección válido siempre que exista una
correspondencia entre las columnas devueltas y las columnas de la tabla destino, o la lista de columnas.

En este caso existe correspondencia en número y en orden entre las columnas de la tabla destino y las
columnas de la selección; por tanto, no hace falta especificar la lista de columnas y el comando requerido
será:

mysql> INSERT INTO departamentos2


-> SELECT * FROM departamentos
-> WHERE LENGTH(dnombre)> 8;
Query OK, 3 rows affected (0.05 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> SELECT *
-> FROM departamentos2;
+--------+---------------+-----------+
| DEP_NO | DNOMBRE | LOCALIDAD |
+--------+---------------+-----------+
| 10 | CONTABILIDAD | BARCELONA |
| 20 | INVESTIGACION | VALENCIA |
| 40 | PRODUCCION | SEVILLA |
+--------+---------------+-----------+
3 rows in set (0.00 sec)

Si la tabla destino tuviese una estructura diferente deberemos forzar la correspondencia, bien al
especificar la lista de selección, bien especificando la lista de columnas, o bien utilizando ambos recursos.

Por ejemplo, supongamos que la tabla destino es n2dep

mysql> CREATE TABLE n2dept

Página: 71
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

-> ( DEP_NO INT(2),


-> NOMBRE VARCHAR(14),
-> CONSTRAINT PK_DEPARTAMENTOS_DEP_NO PRIMARY KEY (DEP_NO)
-> );
Query OK, 0 rows affected (0.52 sec)

En este caso procederemos:

mysql> INSERT INTO n2dept


-> SELECT dep_no, dnombre FROM departamentos
-> WHERE LENGTH(dnombre)> 8;
Query OK, 3 rows affected (0.40 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> SELECT *
-> FROM n2dept;

+--------+---------------+
| DEP_NO | NOMBRE |
+--------+---------------+
| 10 | CONTABILIDAD |
| 20 | INVESTIGACION |
| 40 | PRODUCCION |
+--------+---------------+
3 rows in set (0.00 sec)

2.2 – Modificaciones con subconsultas


En ocasiones la condición que deben cumplir las filas que deseamos modificar implica realizar una
subconsulta a otras tablas. En estos casos se incluirá la subconsulta en la condición y los operadores
necesarios tal como estudiamos en el apartado correspondiente del tema SUBCONSULTAS. La
subconsulta estará en la cláusula WHERE.
Esta subconsulta tiene las siguientes limitaciones:
• La tabla destino no puede aparecer en la consulta.
• No se puede incluir una cláusula ORDER BY en la consulta.

Por ejemplo, supongamos que se desea elevar en 500 Euros. el salario de todos los empleados cuyo
departamento no esté en MADRID

mysql> UPDATE empleados


-> SET salario = salario + 500
-> WHERE dep_no NOT IN (SELECT dep_no
-> FROM departamentos
-> WHERE localidad <> 'MADRID');

Query OK, 4 rows affected (0.05 sec)


Rows matched: 4 Changed: 4 Warnings: 0

2.3 – Eliminaciones con subconsultas


En ocasiones la condición que deben cumplir las filas que deseamos eliminar implica realizar una
subconsulta a otras tablas. En estos casos se incluirá la subconsulta en la condición y los operadores
necesarios tal como estudiamos en el apartado correspondiente del tema subconsultas. Ésta aparecerá en

Página: 72
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

la cláusula WHERE con las mismas restricciones que en las modificaciones:


• La tabla destino no puede aparecer en la consulta.
• No se puede incluir una cláusula ORDER BY en la consulta.
Supongamos que queremos eliminar de la tabla departamentos aquellos que no tienen ningún
empleado.

mysql> DELETE FROM departamentos


-> WHERE dep_no NOT IN
(SELECT DISTINCT dep_no FROM empleados);
Query OK, 1 row affected (0.02 sec)

mysql> SELECT *
-> FROM departamentos;
+--------+---------------+-----------+
| DEP_NO | DNOMBRE | LOCALIDAD |
+--------+---------------+-----------+
| 10 | CONTABILIDAD | BARCELONA |
| 20 | INVESTIGACION | VALENCIA |
| 30 | VENTAS | MADRID |
+--------+---------------+-----------+
3 rows in set (0.00 sec)

El siguiente ejemplo eliminará los departamentos que tienen menos de tres empleados.
Nota: esta orden la ejecutamos con las tablas departamentos2 y empleados2 que tiene borrado en
cascada (con empleados y departamentos no sería posible por la restricción de integridad)

mysql> DELETE FROM departamentos2


-> WHERE dep_no IN (SELECT dep_no
-> FROM empleados2
-> GROUP BY dep_no
-> HAVING count(*) < 3);
Query OK, 1 row affected (0.39 sec)

mysql> SELECT *
-> FROM departamentos2;
+--------+--------------+-----------+
| DEP_NO | DNOMBRE | LOCALIDAD |
+--------+--------------+-----------+
| 10 | CONTABILIDAD | BARCELONA |
| 30 | VENTAS | MADRID |
| 40 | PRODUCCION | SEVILLA |
+--------+--------------+-----------+
3 rows in set (0.00 sec)

El ejemplo anterior borrará los departamentos que tengan menos de tres empleados pero, para que
entre en la lista de selección, el departamento deberá tener al menos un empleado. Por tanto, los
empleados que no tengan ningún empleado no se borrarán. Para evitar esto podemos cambiar la
condición indicando que se borren aquellos departamentos que no están en la lista de departamentos
con tres o más empleados.

mysql> DELETE FROM departamentos2


-> WHERE dep_no NOT IN (SELECT dep_no
-> FROM empleados2

Página: 73
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

-> GROUP BY dep_no


-> HAVING count(*) >= 3);
Query OK, 2 rows affected (0.12 sec)

mysql> SELECT *
-> FROM departamentos2;
+--------+--------------+-----------+
| DEP_NO | DNOMBRE | LOCALIDAD |
+--------+--------------+-----------+
| 10 | CONTABILIDAD | BARCELONA |
| 30 | VENTAS | MADRID |
+--------+--------------+-----------+
2 rows in set (0.00 sec)

Esta última orden borrará todos los departamentos que tienen: ninguno, uno o dos empleados.

Se pueden utilizar subconsultas anidadas a varios niveles, pero respetando la siguiente restricción: la
tabla destino no puede aparecer en la cláusula FROM de ninguna de las subconsultas que
intervienen en la selección. Si se permiten referencias externas, como en el siguiente ejemplo:

mysql> DELETE FROM departamentos


-> WHERE NOT EXISTS (SELECT *
-> FROM empleados
-> WHERE empleados.dep_no=departamentos.dep_no);
Query OK, 0 rows affected (0.00 sec)

En estos casos la subconsulta con la referencia externa realiza la selección sobre la tabla destino
antes de que se elimine ninguna fila.

Nota: debe tenerse en cuenta que algunos productos comerciales permiten saltar esta restricción pero
otros no.

Página: 74
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

3 - Vistas
Podemos definir una vista como una consulta almacenada en la base de datos que se utiliza como una
tabla virtual. Se define asociadas a una o varias tablas y no almacena los datos sino que trabaja sobre los
datos de las tablas sobre las que está definida, estando así en todo momento actualizada.

3.1 - ¿Qué son las vistas y para qué sirven?.


Se trata de una perspectiva de la base de datos o ventana que permite a uno o varios usuarios ver
solamente las filas y columnas necesarias para su trabajo.

Entre las ventajas que ofrece la utilización de vistas cabe destacar:


• Seguridad y confidencialidad: ya que la vista ocultará los datos confidenciales o aquellos para los que
el usuario no tenga permiso.
• Comodidad: ya que solamente muestra los datos relevantes, permitiendo, incluso trabajar con
agrupaciones de filas como si se tratase de una única fila o con composiciones de varias tablas como si
se tratase de una única tabla.
• Independencia respecto a posibles cambios en los nombres de las columnas, de las tablas, etcétera.

Por ejemplo, la siguiente consulta permite al departamento de VENTAS realizar la gestión de sus
empleados ocultando la información relativa a los empleados de otros departamentos.

SELECT *
FROM EMPLEADOS
WHERE dep_no=30;

La siguiente consulta permite a cualquier empleado de la empresa obtener información no confidencial de


cualquier otro empleado ocultando las columnas SALARIO y COMISION:

SELECT emp_no, apellido, oficio, director, fecha_alta, dep_no FROM


empleados;

Para ello crearemos vistas y permitiremos a los usuarios tener acceso a las vistas sin tenerlo de la tabla
completa.

3.2 - Creación y utilización de vistas


Como hemos dicho son tablas virtuales resultado de una consulta realizadas sobre tablas ya existentes.
Las vistas no ocupan espacio en la base de datos ya que lo único que se almacena es la definición de la
vista. El gestor de la base de datos se encargará de comprobar los comandos SQL que hagan referencia a
la vista, transformándolos en los comandos correspondientes referidos a las tablas originales, todo ello de
forma transparente para el usuario.

3.2.1 – Formato de la creación de vistas.


Para crear una vista se utiliza el comando CREATE VIEW según el siguiente formato genérico:

CREATE VIEW NombreVista


[(DefiniciónColumna [,DefiniciónColumna….] )]
AS Consulta;

Página: 75
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

Notación: la lista de columnas que define las columnas de la vista es opcional.

donde NombreVista…………….….. es el nombre que tendrá la vista que se va a crear.


DefinicionColumnas…….... permite especificar un nombre y su correspondiente tipo para
cada columna de la vista.
Si no se especifica, cada columna quedará con el nombre o el
alias correspondiente y el tipo asignado por la consulta.
Consulta……………………….. en una consulta cuy o resultado formará la vista.

El siguiente ejemplo crea la vista emple_dep30 para la gestión de los empleados del departamento 30
mencionada en el apartado anterior.

mysql> CREATE VIEW emple_dep30 AS


-> SELECT * FROM EMPLEADOS
-> WHERE DEP_NO = 30;
Query OK, 0 rows affected (0.55 sec)

CREATE VIEW emple_dep30 AS


SELECT * FROM EMPLEADOS
WHERE DEP_NO = 30;

A continuación se muestra la sentencia que crea la vista datos_emple que contiene información de
todos los empleados ocultando la información confidencial.

mysql> CREATE VIEW datos_emple AS


-> SELECT emp_no, apellido, oficio, director,
fecha_alta, dep_no
-> FROM empleados;

Query OK, 0 rows affected (0.00 sec)

Las vistas pueden a su vez definirse sobre otras vistas. Si ya tenemos creada las vista datos_emple,
podríamos crear otra vista sobre ella:

mysql> CREATE VIEW datos_emple_10 AS


-> SELECT *
-> FROM datos_emple
-> WHERE dep_no=10;
Query OK, 0 rows affected (0.00 sec)

3.2.2 – Utilización de vistas


Una vez definida puede ser utilizada para consultas de igual forma que una tabla.
Con algunas restricciones, todos los formatos de selección vistos para las tablas son aplicables para la
selección de filas en las vistas.

Por ejemplo:

mysql> SELECT * FROM datos_emple;

+--------+----------+-----------+----------+------------+--------+
| emp_no | apellido | oficio | director | fecha_alta | dep_no |

Página: 76
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

+--------+----------+-----------+----------+------------+--------+
| 7499 | ALONSO | VENDEDOR | 7698 | 1981-02-23 | 30 |
| 7521 | LOPEZ | EMPLEADO | 7782 | 1981-05-08 | 10 |
| 7654 | MARTIN | VENDEDOR | 7698 | 1981-09-28 | 30 |
| 7698 | GARRIDO | DIRECTOR | 7839 | 1981-05-01 | 30 |
| 7782 | MARTINEZ | DIRECTOR | 7839 | 1981-06-09 | 10 |
| 7839 | REY | PRESIDENTE| NULL | 1981-11-17 | 10 |
| 7844 | CALVO | VENDEDOR | 7698 | 1981-09-08 | 30 |
| 7876 | GIL | ANALISTA | 7782 | 1982-05-06 | 20 |
| 7900 | JIMENEZ | EMPLEADO | 7782 | 1983-03-24 | 20 |
+--------+----------+-----------+----------+------------+--------+
9 rows in set (0.01 sec)

También podemos seleccionar solo algunas columnas y poner una condición

mysql> SELECT apellido, director


-> FROM datos_emple
-> WHERE oficio = 'VENDEDOR';

+----------+----------+
| apellido | director |
+----------+----------+
| ALONSO | 7698 |
| MARTIN | 7698 |
| CALVO | 7698 |
+----------+----------+
3 rows in set (0.00 sec)

Pero debe tenerse en cuenta que si al definir la vista hemos indicado nuevos nombres para columnas
y expresiones si podremos hacer referencia a ellos en las sentencias de selección, pero si hemos
omitido la definición de las columnas y en la sentencia de creación hemos realizado la selección de
todas las columnas (creada con select *) solo puede hacerse una selección de todas las columnas de
la vista (con *)

La vista emple_dep30 la creamos sin especificar nuevo nombre para las columnas de la vista y con
una sentencia select *. Podemos obtener los datos de la vista si escribimos:

mysql> SELECT * FROM emple_dep30;

+-------+----------+---------+---------+------------+---------+--------+--------+
|EMP_NO | APELLIDO | OFICIO |DIRECTOR | FECHA_ALTA | SALARIO |COMISION| DEP_NO |
+-------+----------+---------+---------+------------+---------+--------+--------+
| 7499 | ALONSO | VENDEDOR| 7698 | 1981-02-23 | 1400.00 | 400.00 | 30 |
| 7654 | MARTIN | VENDEDOR| 7698 | 1981-09-28 | 1500.00 |1600.00 | 30 |
| 7698 | GARRIDO | DIRECTOR| 7839 | 1981-05-01 | 3850.12 | NULL | 30 |
| 7844 | CALVO | VENDEDOR| 7698 | 1981-09-08 | 1800.00 | 0.00 | 30 |
+-------+----------+---------+---------+------------+---------+--------+--------+
4 rows in set (0.06 sec)

Pero no podemos referenciar las columnas en la selección al recuperar datos de la vista:

mysql> SELECT apellido FROM emple_dep30;


ERROR 1054 (42S22): Unknown column 'apellido' in 'field list'

Página: 77
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

3.2.3 - Restricciones para la creación y utilización de vistas


No se puede usar la cláusula ORDER BY en la creación de una vista ya que las filas de una tabla no están
ordenadas (la vista es una tabla virtual). No obstante, si se puede utilizar dicha cláusula a la hora de
recuperar datos de la vista.

Es obligatorio especificar la lista de nombres de columnas de la vista o un alias cuando la consulta


devuelve funciones de agrupamiento como SUM, COUNT, etcétera y posteriormente quiere hacerse
referencia a ellas.

Pueden utilizarse funciones de agrupación sobre columnas de vistas que se basan a su vez en funciones de
agrupación lo que permite resolver los casos en los que un doble agrupamiento que no está permitido por el
estándar. Así creamos una vista con una primera función de agrupación y sobre ella aplicamos la segunda
función de agrupación, obteniendo el resultado deseado.

3.2.4 - Ejemplos creación y utilización de vistas

Como hemos dicho una vez creada la vista se puede utilizar como si se tratase de una tabla (observando
las restricciones anteriores). Veamos lo que podemos hacer con las vistas con los ejemplos.

1- El siguiente ejemplo crea la vista datos_vendedores que muestra solamente las columnas emp_no,
apellido, director, fecha_alta, dep_no, de aquellos empleados cuyo oficio es VENDEDOR.

mysql> CREATE VIEW datos_vendedores


-> (num_vendedor, apellido, director, fecha_alta, dep_no) AS
-> SELECT emp_no, apellido, director, fecha_alta, dep_no
-> FROM empleados
-> WHERE oficio = 'VENDEDOR';
Query OK, 0 rows affected (0.00 sec)

Los datos accesibles mediante la vista creada serán:

mysql> SELECT *
-> FROM datos_vendedores;
+--------------+----------+----------+------------+--------+
| num_vendedor | apellido | director | fecha_alta | dep_no |
+--------------+----------+----------+------------+--------+
| 7499 | ALONSO | 7698 | 1981-02-23 | 30 |
| 7654 | MARTIN | 7698 | 1981-09-28 | 30 |
| 7844 | CALVO | 7698 | 1981-09-08 | 30 |
+--------------+----------+----------+------------+--------+
3 rows in set (0.02 sec)

2- También se pueden crear vistas a partir de consultas que incluyen agrupaciones, como en el siguiente
ejemplo:

mysql> CREATE VIEW resumen_dep1


-> (dep_no, num_empleados, suma_salario, suma_comision) AS
-> SELECT dep_no, COUNT(emp_no), SUM(salario),
SUM(IFNULL(comision,0))
-> FROM empleados
-> GROUP BY dep_no;
Query OK, 0 rows affected (0.01 sec)

Página: 78
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

En estos casos, cada fila de la vista corresponderá a varias filas en la tabla original tal como se puede
comprobar en la siguiente consulta:

mysql> SELECT *
-> FROM resumen_dep1;
+--------+---------------+--------------+---------------+
| dep_no | num_empleados | suma_salario | suma_comision |
+--------+---------------+--------------+---------------+
| 10 | 3 | 9800.50 | 0.00 |
| 20 | 2 | 4750.00 | 0.00 |
| 30 | 4 | 8550.12 | 2000.00 |
+--------+---------------+--------------+---------------+
3 rows in set (0.02 sec)

Normalmente la mayoría de las columnas de este tipo de vistas corresponden a funciones de columna
tales como SUM, AVERAGE, MAX, MIN, etcétera. Por ello el estándar SQL establece en estos casos la
obligatoriedad de especificar la lista de columnas o de alias si posteriormente quiere hacerse referencia a
ellas. Aunque algunos gestores de bases de datos permiten saltar esta restricción. No es aconsejable ya
que las columnas correspondientes de la vista quedarán con nombres como COUNT(EMP_NO),
SUM(SALARIO), SUM(COMISION) lo cual no resulta operativo para su posterior utilización.

mysql> SELECT dep_no, num_empleados, suma_salario


-> FROM resumen_dep1;
+--------+---------------+--------------+
| dep_no | num_empleados | suma_salario |
+--------+---------------+--------------+
| 10 | 3 | 9800.50 |
| 20 | 2 | 4750.00 |
| 30 | 4 | 8550.12 |
+--------+---------------+--------------+
3 rows in set (0.14 sec)

3- Sobre esta vista, con una función de agrupación, podemos hacer otra función de agrupación, por
ejemplo obtener el departamento con mayor suma de salarios para sus empleados:

Creamos la vista resumen_dep2 con dos totales resultado e aplicar funciones de grupo

mysql> CREATE VIEW resumen_dep2


-> AS SELECT dep_no, COUNT(emp_no) "num_empleados",
SUM(salario) "suma_salario",
-> FROM empleados
-> GROUP BY dep_no;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT dep_no, num_empleados, suma_salario


-> FROM resumen_dep2;
+--------+---------------+--------------+
| dep_no | num_empleados | suma_salario |
+--------+---------------+--------------+
| 10 | 3 | 9800.50 |

Página: 79
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

| 20 | 2 | 4750.00 |
| 30 | 4 | 8550.12 |
+--------+---------------+--------------+
3 rows in set (0.00 sec)

Y sobre ella volvemos a aplicar una función de grupo para hallar el máximo de las sumas de los
salarios

mysql> SELECT MAX(suma_salario)


-> FROM resumen_dep2;
+-------------------+
| MAX(suma_salario) |
+-------------------+
| 9800.50 |
+-------------------+
1 row in set (0.00 sec)

Y también podemos obtener el departamento el que pertenece este salario máximo

mysql> SELECT dep_no, dnombre


-> FROM departamentos
-> WHERE dep_no = (SELECT dep_no
-> FROM resumen_dep2
-> WHERE suma_salario=(SELECT MAX(suma_salario)
-> FROM resumen_dep2));

+--------+--------------+
| dep_no | dnombre |
+--------+--------------+
| 10 | CONTABILIDAD |
+--------+--------------+
1 row in set (0.00 sec)

4 –Así mismo, se pueden crear vistas que incluyan todas o varias de las posibilidades estudiadas. Por
ejemplo la siguiente vista permite trabajar con datos de dos tablas, agrupados y seleccionando las filas
que interesan (en este caso todos los departamentos que tengan más de dos empleados):

mysql> CREATE VIEW resumen_emp_dep


-> (departamento, num_empleados, suma_salario) AS
-> SELECT dnombre, COUNT(emp_no), SUM(salario)
-> FROM empleados, departamentos
-> WHERE empleados.dep_no = departamentos.dep_no
-> GROUP BY empleados.dep_no,dnombre
-> HAVING COUNT(*) > 2;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT departamento, num_empleados


-> FROM resumen_emp_dep;
+--------------+---------------+
| departamento | num_empleados |
+--------------+---------------+
| CONTABILIDAD | 3 |
| VENTAS | 4 |
+--------------+---------------+
2 rows in set (0.02 sec)

Página: 80
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos

3.3 - Eliminación de vistas

3.3.1 - Formato de borrado de vistas


La sentencia DROP VIEW permite eliminar la definición de una vista.

DROP VIEW [IF EXISTS] NombreVista


[RESTRICT | CASCADE ]

La cláusula IF EXISTS previene los errores que puedan producirse si no existe la tabla que queremos
borrar
La cláusula CASCADE Y RESTRICT están permitidas pero no implementada en la versión 5.

3.3.2 - Ejemplos de borrado de vistas

mysql> DROP VIEW IF EXISTS resumen_emp_dep;


Query OK, 0 rows affected, 1 warning (0.00 sec)

3.3.3 - Borrado de las tablas o vistas asociadas a una vista


Si se borran las tablas a las vistas sobre las que están definidas las vistas la vista se queda invalida
(no se borra su definición pero no está utilizable).

mysql> SELECT *
-> FROM datos_emple_10;

+--------+----------+------------+----------+------------+--------+
| emp_no | apellido | oficio | director | fecha_alta | dep_no |
+--------+----------+------------+----------+------------+--------+
| 7521 | LOPEZ | EMPLEADO | 7782 | 1981-05-08 | 10 |
| 7782 | MARTINEZ | DIRECTOR | 7839 | 1981-06-09 | 10 |
| 7839 | REY | PRESIDENTE | NULL | 1981-11-17 | 10 |
+--------+----------+------------+----------+------------+--------+
3 rows in set (0.05 sec)

Si borramos datos_emple sobre la que está definida datos_emple_10 esta pasará a estar
inválida.

mysql> DROP VIEW IF EXISTS datos_emple;


Query OK, 0 rows affected (0.00 sec)

mysql> SELECT *
-> FROM datos_emple_10;
ERROR 1356 (HY000): View 'test.datos_emple_10' references invalid
table(s) or column(s)

Página: 81
Lenguaje SQL con MySQL Parte III. Administración de MySQL

PARTE III
ADMINISTRACIÓN DE MySQL

Tema 10. Instalación y primeros pasos con MySQL


10.1. Introducción

10.2. Instalación

10.2.1. Instalación de MySQL para Windows versión 4.1


10.2.2. Instalación de MySQL para Windows versión 5.0
10.2.3. Instalación de MySQL para Linux

10.3. Tutorial básico

10.3.1. Conectarse al servidor mediante el programa cliente en modo consola mysql


10.3.2. Algunas consultas básicas de interés para el administrador
10.3.3. Añadir password al usuario root
10.3.4. Crear y usar bases de datos en MySQL
10.3.5. Los comandos SHOW y DESC
10.3.6. Editar las sentencias desde el cliente en modo consola mysql
10.3.7. Lanzar scripts desde el cliente en modo consola mysql
10.3.8. Verificar el estado, arrancar y detener el proceso servidor.

Tema 11. Administración de MySQL (I)


11.1. Estructura interna

11.1.1. Localización del directorio de datos


11.1.2. Estructura del directorio de datos
11.1.3. Arquitecturas de almacenamiento de las tablas

11.2. Configuración

11.2.1. Usar opciones de configuración a través de la línea de comandos


11.2.2. Usar ficheros de opciones (ficheros de configuración)

11.3. Administración de cuentas de usuario y seguridad

11.3.1. Introducción a las sentencias GRANT y REVOKE


11.3.2. Sintaxis de la sentencia GRANT
11.3.3. Sintaxis de la sentencia REVOKE
11.3.4. Algunos ejemplos de la sentencia GRANT
11.3.5. Eliminar una cuenta de usuario.

11.4. Índices

11.4.1. Tipos de índices y su creación


11.4.2. Eliminar o cambiar un índice
11.4.3. Uso eficiente de los índices

11.5. Backup

11.5.1. mysqldump
11.5.2. mysqlhotcopy
11.5.3. Importar tablas desde ficheros de texto delimitados
11.5.4. Exportar tablas a ficheros de texto delimitados
MySQL Documento de Administración 2

Tema 12. Administración de MySQL (II)

12.1. Ficheros Log

12.1.1. El log de error (error log)


12.1.2. El fichero log general (query log file)
12.1.3. El fichero log de modificaciones (update log )
12.1.4. El fichero de log binario (binary log)

12.2. Ejecutar varios servidores MySQL en la misma máquina

12.2.1. Ejecutar varios servidores MySQL en Windows


12.2.2. Ejecutar varios servidores MySQL en Linux

12.3. Replicación

12.3.1. Ventajas de la replicación


12.3.2. Implantación del servicio de replicación
12.3.3. Otros datos útiles en el proceso de replicación
12.3.4. Posibles arquitecturas de replicación
MySQL Documento de Administración 3

Tema 10.
Instalación y primeros pasos con
MySQL
Javier Robles Cascallar

10.1. Introducción
Comparado con otros sistemas corporativos de bases de datos el sistema de gestión de
bases de datos MySQL es relativamente fácil de administrar, utilizar e instalar. Gran
parte de la popularidad de MySQL es su simplicidad (además de su velocidad).

Componentes esenciales de la base de datos MySQL con los que un administrador debe
estar familiarizado:

• El servidor MySQL. Normalmente asociado al proceso mysqld (aunque ya


veremos que existen otros procesos servidor). El servidor es el que realiza todos
los accesos y manipulaciones a las tablas de la base de datos.

• Los clientes MySQL que acceden al servidor. Existen numerosos programas


de la propia distribución de MySQL y de otros fabricantes que ayudan a
establecer la comunicación con el servidor y realizar las tareas administrativas.
Los más importantes y que vienen en la propia distribución de MySQL son los
siguientes:
o mysql, programa interactivo en modo línea de comandos para lanzar
sentencias SQL en modo interactivo o batch (por lotes).
o mysqladmin, es un cliente de administración en modo línea de
comandos.
o mysqldump, es una herramienta para hacer copias de seguridad o copiar
bases de datos a otro servidor.
o mysqlimport, es una herramienta para importar ficheros de datos.
o mysqlshow, muestra información sobre las bases de datos y las tablas.

• Otras utilidades que pueden operar independientemente del servidor.


o Myisamchk, permite realizar tareas de mantenimiento sobre las tablas.
o myisampack, permite generar tablas comprimidas de solo-lectura.
o mysqlbinlog, es una herramienta para procesar los ficheros log en modo
binario que genera el servidor
MySQL Documento de Administración 4

A continuación listamos las tareas más importantes de administración que en un


momento u otro tendrían que ser asumidas por la persona o personas responsables de la
base de datos:
• Inicio y desconexión del servidor.
• Mantenimiento de cuentas de usuario.
• Mantenimiento del archivo de registro.
• Backup de la base de datos y recuperación de caídas.
• Optimizar el servidor
• Trabajar con múltiples servidores a la ve z
• Estar al tanto de las actualizaciones
• Garantizar la seguridad del sistema de archivos y la seguridad de los accesos
• Mantenimiento preventivo

En este documento de administración se intentará dar una aproximación detallada a la


resolución de todas estas tareas.
MySQL Documento de Administración 5

10.2. Instalación
10.2.1 Instalación de MySQL versión 4.1 para entorno Windows con
soporte InnoDB.

Nota importante: Esta versión es la que recomienda MySQL para trabajar


en un entorno de producción real. Está mucho más probada y depurada
que la versión 5. Como consejo, debéis instalar esta versión
preferentemente al principio del curso y solamente instalar la versión 5
para probar las nuevas características. Ambas distribuciones pueden ser
instaladas en el mismo equipo y convivir operando simultáneamente sin
interferirse.

Obtención del fichero donde se encuentra el programa de instalación del servidor


MySQL. (mysql-4.1.10-win32.zip tamaño 34Mb). Este fichero lo podéis obtener en el
CD que se distribuye para este curso o también lo podéis encontrar en la Web oficial de
MySQL entre otros muchos sitios.

Una vez descargado se descomprime el fichero zip en una carpeta y se ejecuta el


programa setup.exe que inicia el asistente que va guiando al usuario en el proceso de
instalación y posteriormente en el proceso de configuración del servidor de base de
datos MySQL.

Una vez descargado se ejecuta el programa de instalación y se inicia el asistente que va


guiando al usuario en el proceso de instalación y posteriormente en el proceso de
configuración del servidor de base de datos MySQL.

Las ventanas del asistente que van apareciendo a lo largo de la instalación se describen
a continuación, así como las opciones que conviene que se seleccionen para lograr la
instalación que mejor se adapta al contenido del curso.
MySQL Documento de Administración 6

1. Ventana de inicio y presentación del asistente. Pulsamos Next para continuar

2. Tipo de Instalación. Seleccionamos la instalación personalizada Custom


MySQL Documento de Administración 7

3. Seleccionamos los programas (servidores y clientes) que queremos que se


instalen. Lo más conveniente en esta ventana es dejar las opciones que vienen
por defecto. Si acaso podemos cambiar (pulsando Change…) la carpeta donde
se va instalar por defecto la versión.

4. Ventana que avisa que ya esta preparado para instalar el producto. Pulsamos
Install
MySQL Documento de Administración 8

5. Ventana para registrarse en la Web MySQL.com. Podemos dejar este paso si lo


deseamos para más adelante. Lo más cómodo y rápido es pulsar por lo tanto Skip Sign-
Up para saltarse este paso y seguir con la configuración.

6. Ventana que avisa del final del asistente de instalación. Marcamos la casilla que pone
Configure de MySQL Server now para iniciar el asistente de configuración.
MySQL Documento de Administración 9

7. Seleccionamos la opción de Configuración Detallada (Detailed Configuration). Esta


opción permite acceder con más detalle a las opciones de configuración del servidor.

8. Seleccionamos a continuación la opción Developer Machine. Esto permite que la


instalación de MySQL no le de demasiados recursos de memoria al servidor de MySQL
en detrimento de otras aplicaciones que pueden estar funcionando en nuestra estación de
trabajo
MySQL Documento de Administración 10

9. Como queremos que la instalación tenga soporte para tablas InnoDB (lo que permite
trabajar con integridad referencial entre tablas y control transaccional) seleccionamos en
esta ventana la opción Transactional Database Only

10. Esta ventana selecciona la carpeta donde va a quedar alojado el Tablespace para las
tablas InnoDB. Lo más cómodo es dejar la opción que viene por defecto y pulsar Next.
MySQL Documento de Administración 11

11. Seleccionamos el nº aproximado de conexiones concurrentes. Seleccionamos


Manual Setting dejando el valor de 15 que viene por defecto. (Podemos incluso reducir
el número ya que nuestro servidor de BD va a ser un servidor de prueba y es poco
probable que tenga que optimizar el acceso concurrente a los datos).

12. Establecer el puerto TCP/IP. Lo más cómodo es dejar el puerto que viene por
defecto con el número 3306
MySQL Documento de Administración 12

13. Establecer el juego de caracteres por defecto. Debemos seleccionar, si no lo


estuviera ya, la opción Standard Carácter Set

14. Instalar el arranque del servidor MySQL como un servicio de Windows. Lo más
cómodo es que MySQL se configure como un servicio de Windows y que arranque
automáticamente cuando arrancamos el equipo. Para ello seleccionamos los dos check
box de la ventana.
MySQL Documento de Administración 13

15. Esta ventana permite configurar las opciones de seguridad iniciales de MySQL. Por
defecto MySQL viene con un usuario administrador sin password. Si se desea en esta
ventana se puede crear la password de administrador y también la posibilidad de crear
un usuario invitado. Lo más sencillo es no modificar las opciones por defecto, por lo
tanto si esta marcado el check box de Modify Security Settings se desmarca. más
adelante ya avanzado el curso se verá como se añade la password al usuario
administrador.
MySQL Documento de Administración 14

16. Ultima ventana del asistente donde nos indica que todo esta preparado para generar
el fichero de configuración (my.ini) y arrancar el servicio de Windows que inicia el
servidor MySQL. Pulsamos Execute para finalizar el proceso.
MySQL Documento de Administración 15

10.2.2 Instalación de MySQL versión 5.0 para entorno Windows con


soporte InnoDB.

Nota importante: Esta versión es la última release de MySQL y es útil para


ver las últimas características y novedades que aporta este servidor de
bases de datos. La versión que remienda MySQL para trabajar en un
entorno de producción real es la versión 4.1.

Obtención del fichero donde se encuentra el programa de instalación del servidor


MySQL. (mysql-5.0.2-alpha-win.msi tamaño 37Mb). Este fichero lo podéis obtener en
el CD que se distribuye para este curso o también lo podéis encontrar en la Web oficial
de MySQL entre otros muchos sitios

Las principales características de la versión 5 que no están soportadas en la versión 4.1.

• Implementación de vistas (VIEWS).


• Procedimientos almacenados (STORED PROCEDURES).
• Soporte para cursores.
• Mejor soporte para las tablas tipo MEMORY
• Mejoras de velocidad.

Una vez descargado se ejecuta el programa de instalación y se inicia el asistente que va


guiando al usuario en el proceso de instalación y posteriormente en el proceso de
configuración del servidor de base de datos MySQL.

Las ventanas del asistente que van apareciendo a lo largo de la instalación son muy
similares a las ya descritas en el apartado 10.2.1 para la instalación de la versión 4.1 y
las opciones que conviene seleccionar son las mismas que las ya comentadas en el
punto anterior y permiten lograr la instalación que mejor se adapta al contenido del
curso.
MySQL Documento de Administración 16

10.2.3 Instalación de MySQL para Linux.

MySQL viene integrado en la mayor parte de las distribuciones de Linux, lo más


probable, por lo tanto, si estamos trabajando en Linux, es que ya esté instalado.

El caso más frecuente con el que nos podemos encontrar es que queramos actualizar a la
última versión de MySQL que no viene incluida en nuestra distribución de Linux (por
ejemplo si queremos pasar de la 4.1 a la 5.0), en este caso lo más conveniente es
desinstalar la aplicación antigua e instalar la nueva versión.

10.2. 3.1 Desinstalar MySQL

- Detener el servidor de MySQL


shell> mysql.server stop
- Borrar los paquetes de la distribución MySQL instalados en el equipo (rpm)
Se consulta en primer lugar que paquetes hay instalados
rpm -qa mysql
A continuación se eliminan esos paquetes
rpm -e mysql
rpm -e mysql-client
- Eliminar manualmente los ficheros de configuración y las bases de datos que la
desinstalación de paquetes no elimina.
Eliminar el fichero /etc/my.cnf
Eliminar la carpeta /var/lib/mysql

10.2.3.2 Instalar MySQL

También comentamos en este apartado la instalación mediante paquetes rpm por ser la
más cómoda de realizar.

Para realizar una instalación mínima al menos se requiere la instalación de dos paquetes.

shell> rpm -i MySQL-server-VERSION.i386.rpm


shell> rpm -i MySQL-client-VERSION.i386.rpm

(VERSION corresponde al paquete cuya versión queremos instalar)

La instalación por paquetes rpm crea automáticamente una cuenta de usuario llamado
mysql que es el que ejecuta el proceso servidor y crea también las entradas adecuadas en
/etc/init.d/ para arrancar el servidor automáticamente al arrancar el equipo.
MySQL Documento de Administración 17

10.3. Tutorial Básico


10.3.1. Conectarse al servidor mediante el programa cliente en modo
consola mysql

El cliente básico de MySQL es el programa mysql (mysql.exe en Windows) que viene


en la distribución y una vez instalado se encuentra en la carpeta /bin que genera la
instalación

Para conectarse al servidor, usualmente necesitamos de un nombre de usuario (login) y


de una contraseña (password), y si el servidor al que nos deseamos conectar está en una
máquina diferente de la nuestra, también necesitamos indicar el nombre o la dirección
IP de dicho servidor. Una vez que conocemos estos tres valores, podemos conectarnos
de la siguiente manera:

shell> mysql -h NombreDelServidor -u NombreDeUsuario –p

Cuando ejecutamos este comando, se nos pedirá que proporcionemos también la


contraseña para el nombre de usuario que estamos usando.

Si la conexión al servidor MySQL se pudo establecer de manera satisfactoria,


recibiremos el mensaje de bienvenida y estaremos en el prompt de mysql:

shell>mysql -h 192.168.1.2 -u root -p

Enter password: ******

Welcome to the MySQL monitor. Commands end with ; or \g.


Your MySQL connection id is 5563 to server version: 4.1.8-nt-max-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

Este prompt mysql> nos indica que hemos conectado y mysql está listo para recibir
comandos.

Por defecto la instalación MySQL incorpora dos usuarios el usuario Administrador


(‘root’) y el usuario invitado (‘ODBC’ y también ‘’ ) ambos con privilegios de
administración cuando se conectan de modo local al servidor. Por lo tanto es posible
acceder con derechos de administrador local del propio equipo sin necesidad de
introducir ningún tipo de opción y sin password.

shell> mysql

Después de que nos hemos conectado de manera satisfactoria, podemos desconectarnos


en cualquier momento al escribir "quit " o "exit ".

Esta forma de acceso como administrador sin password por defecto es útil y cómoda
para esta fase de aprendizaje pero altamente insegura y desaconsejable en una
instalación de producción convencional.
MySQL Documento de Administración 18

En la mayoría de los ejemplos siguientes se asume que estamos conectados al servidor,


lo cual se indica con el prompt de mysql. ( mysql> )

Ejemplos de establecimiento de conexión entre cliente y servidor:

Conectarse localmente con el usuario invitado. Normalmente se accede con


privilegios de administrador

C:\MySQL\bin>mysql

Conectarse localmente con el usuario administrador root introduciendo la


password micontraseña en la propia línea de comandos.

C:\MySQL\bin>mysql -uroot -pmicontraseña

Conectarse localmente con el usuario administrador root sin introducir la


password en la propia línea de comandos. La password se introduce después de
pulsar Enter

C:\MySQL410\bin>mysql -uroot -p
Enter password: *********

Conectarse a un servidor de otra maquina con el usuario invitado sin password.


En este caso no se accede con privilegios de administrador. Lo normal (depende
de la distribución) es que solo tenga acceso a la base de datos test que viene
incluida para pruebas

C:\MySQL410\bin>mysql –h192.168.3.33

En el tema 11 de esta documentación se trata en profundidad el tema de los


usuarios de MySQL y sus privilegios de acceso.
MySQL Documento de Administración 19

10.3.2 Algunas consultas básicas de interés para el administrador

En este momento debimos de haber podido conectarnos ya al servidor MySQL, aún


cuando no hemos seleccionado alguna base de datos para trabajar. Lo que haremos a
continuación es escribir algunos comandos para irnos familiarizando con el
funcionamiento de mysql.

- Consulta para conocer la versión del servidor y la fecha actual:

mysql> SELECT VERSION(), CURRENT_DATE;


+------------------+--------------+
| VERSION() | CURRENT_DATE |
+------------------+--------------+
| 4.1.8-nt-max-log | 2005-01-08 |
+------------------+--------------+
1 row in set (0.33 sec)

mysql>

Esta comando ilustra distintas cosas acerca de mysql:

Un comando normalmente consiste de una sentencia SQL seguida por un punto y coma.
Cuando emitimos un comando, mysql lo manda al servidor para que lo ejecute, nos
muestra los resultados y regresa el prompt indicando que está listo para recibir más
consultas.
mysql muestra los resultados de la consulta como una tabla (filas y columnas). La
primera fila contiene etiquetas para las columnas. Las filas siguientes muestran los
resultados de la consulta. Normalmente las etiquetas de las columnas son los nombres
de los campos de las tablas que estamos usando en alguna consulta. Si lo que estamos
recuperando es el valor de una expresión (como en el ejemplo anterior) las etiquetas en
las columnas son la expresión en sí.
mysql muestra cuántas filas fueron regresadas y cuanto tiempo tardó en ejecutarse la
consulta, lo cual puede darnos una idea de la eficiencia del servidor, aunque estos
valores pueden ser un tanto imprecisos ya que no se muestra la hora del CPU, y porque
pueden verse afectados por otros factores, tales como la carga del servidor y la
velocidad de comunicación en una red.
Las palabras clave pueden ser escritas usando mayúsculas y minúsculas.

Aquí está un ejemplo que muestra una consulta simple escrita en varias líneas.

-Consulta para conocer el nombre del usuario que ha efectuado la conexión:

mysql> SELECT
-> USER();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
mysql>
MySQL Documento de Administración 20

En este ejemplo debe notarse como cambia el prompt (de mysql> a ->) cuando se
escribe una consulta en varias líneas. Esta es la manera en cómo mysql indica que está
esperando a que finalice la consulta. Sin embargo si deseamos no terminar de escribir la
consulta, podemos hacerlo al escribir \c como se muestra en el siguiente ejemplo:

mysql> SELECT
-> USER(),
-> \c
mysql>

De nuevo, se nos regresa el comando el prompt mysql> que nos indica que mysql está
listo para una nueva consulta.

En la siguiente tabla se muestran cada uno de los prompts que podemos obtener y una
breve descripción de su significado para mysql:

Prompt Significado

mysql> Listo para una nueva consulta.


-> Esperando la línea siguiente de una consulta multi- línea.
'> Esperando la siguiente línea para completar una cadena que comienza
con una comilla sencilla (').
"> Esperando la siguiente línea para completar una cadena que comienza
con una comilla doble (").

Los prompts '> y "> ocurren durante la escritura de cadenas. En mysql podemos escribir
cadenas utilizando comillas sencillas o comillas dobles (por ejemplo, 'hola' y "hola"), y
mysql nos permite escribir cadenas que ocupen múltiples líneas. De manera que cuando
veamos el prompt '> o "> , mysql nos indica que hemos empezado a escribir una cadena,
pero no la hemos finalizado con la comilla correspondiente.
MySQL Documento de Administración 21

10.3.3 Añadir password al usuario root


MySQL por defecto viene con la cuenta de administrador sin password.
Realmente MySQL incluye dos cuentas de root (administrador) una para conectarse
localmente y otra para conectarse desde cualquier máquina externa al servidor. Eso lo
podemos ver haciendo el siguiente select sobre la tabla de usuarios que se encuentra en
la base de datos mysql (diccionario de datos del servidor).
mysql> select user,host,password from mysql.user;
+------+-----------+----------+
| user | host | password |
+------+-----------+----------+
| root | localhost | |
| root | % | |
| | localhost | |
| | % | |
+------+-----------+----------+
4 rows in set (0.00 sec)

En este select se ve claramente como las cuentas de root y de invitado están sin
password, por lo tanto el sistema es totalmente inseguro, solo válido para pruebas.

Lo anterior nos indica que la primera vez que se inicialice el servidor la primera cosa
que se debe hacer es especificar un password para el usuario root (esto es para el
administrador). Esto se puede realizar de la siguiente manera:
shell> mysql -u root
mysql> SET PASSWORD FOR root=PASSWORD('new_password');

Con esta sentencia le hemos añadido un password a la cuenta de root que sirve para
conectar desde cualquier máquina.

Si también le queremos añadir un password a la cuenta de root para conectar en modo


localhost ejecutaremos la siguiente instrucción:

mysql> SET PASSWORD FOR root@localhost=PASSWORD('new_password');

Volvemos a repetir la select sobre la tabla usuarios para ver como ha cambiado después
de ejecutar las sentencias anteriores.

mysql> select user,host,password from mysql.user;


+------+-----------+-------------------------------------------+
| user | host | password |
+------+-----------+-------------------------------------------+
| root | localhost | *8C6D142DE6424E095EC1E1E756974E907289CE6B |
| root | % | *8C6D142DE6424E095EC1E1E756974E907289CE6B |
| | localhost | |
| | % | |
+------+-----------+-------------------------------------------+
4 rows in set (0.00 sec)

mysql>

Nota1: SET PASSWORD FOR se puede usar para establecer nueva contraseña para
cualquier usuario, no solo root.
Nota 2: La función PASSWORD(‘new_password’) genera la password encriptada.
MySQL Documento de Administración 22

10.3.4 Crear, usar y acceder a bases de datos en MySQL

Ahora que conocemos como escribir y ejecutar sentencias, es tiempo de crear y acceder
a una base de datos.

Esta sección muestra como ver las bases de datos a las que tenemos acceso en el
servidor, crear una base de datos nueva , posicionar al usuario en una determinada base
de datos y acceder a tablas de una base de datos cuando estamos situados en otra base
de datos.

Primeramente usaremos la sentencia SHOW DATABASES para ver cuáles son las bases de
datos existentes en el servidor al que estamos conectados:

mysql> SHOW DATABASES;


+----------+
| Database |
+----------+
| mysql |
| test |
+----------+
2 rows in set (0.00 sec)

mysql>

Es probable que la lista de bases de datos que veamos sea diferente en nuestro caso,
pero seguramente las bases de datos "mysql" y "test " estarán entre ellas. En particular, la
base de datos "mysql" es necesaria, ya que ésta tiene la información de los privilegios de
los usuarios de MySQL. La base de datos "test " se crea durante la instalación de
MySQL con el propósito de servir como área de trabajo para los usuarios que inician en
el aprendizaje de MySQL.

Para acceder a la base de datos "test " se usa el comando USE:

mysql> USE test


Database changed
mysql>

Observar que USE, al igual que QUIT, no requieren el uso del punto y coma, aunque si
se usa éste, no hay ningún problema. El comando USE es especial también de otra
manera: debe ser usado en una sola línea.

mysql> USE prueba


ERROR 1049: Unknown database 'prueba'
mysql>
MySQL Documento de Administración 23

El mensaje anterior indica que la base de datos no ha sido creada, por lo tanto
necesitamos crearla.

mysql> CREATE DATABASE prueba;


Query OK, 1 row affected (0.00 sec)

mysql> USE prueba


Database changed
mysql>

Ahora ya se pueden lanzar sentencias CREATE TABLE para crear tablas sobre la base de
datos prueba que hemos creado y hemos accedido. (Ver la sentencia CREATE TABLE en
el manual de SQL de este curso)

Bajo el sistema operativo Unix/Linux, los nombres de las bases de datos son sensibles al
uso de mayúsculas y minúsculas (no como las palabras clave de SQL), por lo tanto
debemos de tener cuidado de escribir correctamente el nombre de la base de datos. Esto
es cierto también para los nombres de las tablas.

Al crear una base de datos no se selecciona ésta de manera automática; debemos hacerlo
de manera explícita, por ello usamos el comando USE en el ejemplo anterior.

La base de datos se crea sólo una vez, pero nosotros debemos seleccionarla cada vez
que iniciamos una sesión con mysql. Por ello es recomendable que se indique la base de
datos sobre la que vamos a trabajar al momento de invocar al monitor de MySQL. Por
ejemplo:

shell>mysql -h 192.168.1.2 -u root –p prueba

Enter password: ******


Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 17 to server version: 4.1.8-nt-max-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer

mysql>

Observar que "prueba " no es la contraseña que se está proporcionando desde la línea de
comandos, sino el nombre de la base de datos a la que deseamos acceder. Si deseamos
proporcionar la contraseña en la línea de comandos después de la opció n "-p", debemos
de hacerlo sin dejar espacios (por ejemplo, -phola123, no como -p hola123). Sin
embargo, escribir nuestra contraseña desde la línea de comandos no es recomendado, ya
que es bastante inseguro.

Para ver en un momento dado en que base de datos nos encontramos situados podemos
lanzar la siguiente consulta:
MySQL Documento de Administración 24

mysql> select database();


+------------+
| database() |
+------------+
| prueba |
+------------+
1 row in set (0.00 sec)

mysql>

Para acceder a una tabla de una base de datos cuando nos encontramos situados en otra
base de datos es necesario anteponer en la sentencia el nombre de la base de datos
seguido de un punto. Por ejemplo accedo mediante el comando USE a la base de datos
test y a continuación hago un select de la tabla departamentos de la base de datos
prueba.

mysql> use test


Database changed
mysql> select * from prueba.departamentos;
+--------+---------------+-----------+
| DEP_NO | DNOMBRE | LOCALIDAD |
+--------+---------------+-----------+
| 10 | CONTABILIDAD | BARCELONA |
| 20 | INVESTIGACION | VALENCIA |
| 30 | VENTAS | MADRID |
| 40 | PRODUCCION | SEVILLA |
+--------+---------------+-----------+
4 rows in set (0.10 sec)

mysql>

Esto se podrá hacer siempre que el usuario tenga privilegios suficientes como para
acceder a ambas bases de datos (en este ejemplo a prueba y a test). (El tema de los
privilegios de acceso se ve en el punto 6 de este manual).
MySQL Documento de Administración 25

10.3.5 El comando SHOW y el comando DESC


Estos dos comandos son muy útiles cuando trabajamos con el cliente de MySQL en
entorno de comandos puesto que no tenemos el soporte visual que proporcionan los
clientes gráficos.

Para ver un listado con las tablas dentro de una determinada base de datos podemos
lanzar la sentencia:

mysql> show tables;


+------------------+
| Tables_in_prueba |
+------------------+
| departamentos |
| empleados |
+------------------+
2 rows in set (0.10 sec)

Para ver la descripción de una tabla en sus columnas y tipos asociados, además de poder
ver los atributos que aceptan nulos y las opciones por defecto debemos usar el comando
DESC o DESCRIBE que realmente es un sinónimo de la sentencia SHOW COLUMNS FROM.

mysql> desc departamentos;


+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| DEP_NO | int(2) | | PRI | 0 | |
| DNOMBRE | varchar(14) | YES | | NULL | |
| LOCALIDAD | varchar(10) | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
3 rows in set (0.05 sec)

Es muy interesante también poder ver la sentencia de creación de tabla asociada a una
determinada tabla de la base de datos. Es una información que puede complementar la
proporcionada por el comando DESC.

mysql> show create table departamentos \G


*************************** 1. row ***************************
Table: departamentos
Create Table: CREATE TABLE `departamentos` (
`DEP_NO` int(2) NOT NULL default '0',
`DNOMBRE` varchar(14) default NULL,
`LOCALIDAD` varchar(10) default NULL,
PRIMARY KEY (`DEP_NO`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

La opción \G permite visualizar la salida de la consulta en una sola fila.

Conviene fijarse que esta es una manera donde rápidamente se puede visualizar el tipo
de almacenamiento de la tabla (en el ejemplo se ve que la tabla es de tipo MyISAM.;
para más información sobre los tipos de almacenamiento soportados por MySQL ver el
punto 4.3 de este manual) que es una información que no proporciona DESC
directamente.
MySQL Documento de Administración 26

Otra sentencia que también permite obtener información acerca de las tablas es
SHOW TABLE STATUS [FROM nombre_bade_de_datos] [LIKE 'patron']. Siguiendo
con el ejemplo de la tabla DEPARTAMENTOS :

mysql> show table status like 'departamentos' \G


*************************** 1. row ***************************
Name: departamentos
Engine: MyISAM
Version: 9
Row_format: Dynamic
Rows: 0
Avg_row_length: 0
Data_length: 0
Max_data_length: 4294967295
Index_length: 1024
Data_free: 0
Auto_increment: NULL
Create_time: 2005-01-05 15:18:40
Update_time: 2005-01-05 15:18:41
Check_time: NULL
Collation: latin1_swedish_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)

Donde se observa que esta sentencia nos devuelve información de utilidad para el
Administrador de la Base de Datos.
MySQL Documento de Administración 27

10.3.6 Editar las sentencias desde el cliente en modo consola mysql

El programa cliente mysql no es muy amigable a la hora de editar sentencias largas de


SQL antes de lanzarlas. Es por lo tanto conveniente y aconsejable editar dichas
sentencias desde un sencillo editor ASCII (Notepad o Wordpad en entorno Windows) y
una vez editadas lanzar las sentencias mediante el usual procedimiento de “copiar y
pegar” al cliente mysql.

Con el siguiente ejemplo se muestra el proceso desde Windows (en Linux es muy
similar).

Paso 1. Se abre una ventana de comandos y se inicia una sesión con el cliente mysql
sobre la base de datos test.

Paso 2. Se abre en otra ventana el editor y se edita la sentencia SQL que se va a lanzar
al cliente.
MySQL Documento de Administración 28

Paso 3. Se marca con el ratón el párrafo con la sentencia para su copia mediante el
comando MenúàEdiciónàCopiar o bien pulsando Ctrl+C

Paso 4. Se pega la copia anterior pulsando con el botón derecho del ratón sobre
cualquier punto de la ventana de comandos y seleccionando la opción Pegar.

Paso 5. Se pulsa Enter para lanzar la sentencia.

Este proceso, aunque se haya explicado en cinco pasos, una vez que el usuario se ha
acostumbrado a la mecánica, es la manera más cómoda de trabajar cuando estamos en
entorno de comandos y no disponemos de un cliente gráfico.
MySQL Documento de Administración 29

10.3.7 Lanzar scripts desde el cliente en modo consola mysql.

Normalmente hasta ahora hemos usado mysql de manera interactiva para ejecutar
algunas consultas y ver los resultados. Sin embargo, es posible usar mysql en modo
batch. Para hacer esto tenemos que poner los comandos que deseamos ejecutar dentro
de un archivo, y entonces decirle a mysql que lea los comandos de dicho archivo:
shell> mysql < archivo-batch.sql

Si se usa mysql de esta manera, se está creando un pequeño script, y posteriormente se


está ejecutando dicho script. La extensión .sql no es obligatoria pero si aconsejable
para reconocer los scripts de sql . Al ejecutar las sentencias y comandos que se
encuentran en el script, es posible que suceda algún error. Si se desea que se continúen
ejecutando las demás sentencias, a pesar de que haya ocurrido un error, se tiene que usar
la opción --force
shell> mysql --force < archivo-batch.sql

Así mismo, es posible especificar los parámetros de conexión desde la línea de


comandos. Por ejemplo:

shell> mysql -h 192.168.2.1 –u root -p < archivo-batch.sql

Algunas cuantas razones para usar scripts en lugar de trabajar en modo interactivo:

• Si se ejecutan un cierto número de consultas frecuentemente (cada día, o cada


semana), al hacer un script nos evitamos tener que volver a teclear cada una de
las consultas.
• Se pueden generar nuevas consultas que sean similares a las existentes al copiar
y editar estos scripts.
• Al escribir consultas de varias líneas, los scripts ayudan bastante para que no se
tengan que escribir todas las líneas nuevamente si se comete algún error.
• Se puede guardar la salida en un archivo para revisarla posteriormente.

shell> mysql < archivo-batch.sql > salida-del-script.txt

• Se pueden distribuir los scripts a otras personas para que puedan ejecutar
también nuestros comandos y sentencias.
• En algunas situaciones no se permite el uso interactivo de mysql. (En el caso de
las tareas programadas ). En este caso, es indispensable usar el modo batch.

Cabe mencionar que el formato de la salida es diferente (más conciso) cuando se ejecuta
mysql en modo batch, que cuando se usa de manera interactiva.

También se puede lanzar el script una vez conectados a mysql mediante el comando
source (o el método abreviado \.)

mysql> source archivo-batch.sql

o el equivalente abreviado mysql> \. archivo-batch.sql


MySQL Documento de Administración 30

10.3.8 Verificar el estado, arrancar y detener el proceso servidor.


En la mayoría de las instalaciones de MySQL, en sus distintas versiones, se selecciona
por defecto la opción de arrancar automáticamente el proceso servidor cuando se
arranca el host sobre el que está instalado. Pero es fundamental para un administrador
saber verificar, en un momento dado, el estado del servidor (en ejecución o detenido) y
conocer perfectamente cual es el mecanismo de arranque y/o parada en el caso que sea
necesario efectuarlo.

Nota:
El proceso (demonio) servidor en MySQL se denomina mysqld o una de sus variantes mysqld-opt,
mysqld-nt, mysqld-max, mysqld-max-nt . (para ver las diferencias entre un proceso y otro
acceder al manual de referencia puntos 2.2.1.4 para Windows y 2.2.2 para Linux).

Verificar el estado del servidor en Windows.

En Windows (XP, 2000,…) lo más común es tener el servidor MySQL instalado como
un servicio de Windows. Basta con acceder a la ventana de servicios y comprobar su
estado.
Para acceder a la ventana de servicios de Windows rápidamente
Menú InicioàEjecutaràservices.msc
En la siguiente imagen se ve la ventana de servicios donde aparece el servicio asociado
al servidor MySQL51 que esta Iniciado y tiene un tipo de inicio Manual (el
administrador debe iniciar el servicio)

En el caso de no tener MySQL asociado a un servicio o tener MySQL instalado en W98


a versión anterior lo mejor es acceder al Administrador de tareas de Windows
(Menu Inicio—Ejecutaràtaskmgr)
En la pestaña de Procesos debe aparecer el proceso servidor si es que esta en ejecución
tal como aparece en al siguiente imagen
MySQL Documento de Administración 31

Verificar el estado del servidor en Linux.

En Linux abrimos una terminal y pulsamos el comando


ps –A | grep mysqld
Si MySQL esta ejecutándose deberá responder con algo parecido a:
2752 ? 00:00:00:00 mysqld

Arrancar el proceso servidor en Windows.

Si tenemos el proceso servidor asociado a un servicio de Windows (lo más habitual)


pulsamos botón derecho del ratón sobre el servicio que queremos iniciar y
seleccionamos Iniciar.

En caso contrario lo mejor es iniciar el proceso desde una consola de comandos, es muy
importante que en el proceso de arranque se indique mediante la opción defaults-
file donde se encuentra el fichero de configuración (ver el punto de 11.2.2 de la
documentación del curso para más información sobre el fichero de configuración). El
comando será algo parecido a lo siguiente
C:\MySQL410\bin\mysqld-max-nt --defaults-file="C:\MySQL410\my.ini

Arrancar el proceso servidor en Linux.

En Linux lo más habitual es tener automatizado el arranque del servidor de MySQL


cuando se inicia el equipo. En el caso de que el servicio este detenido tendremos que
arrancar el proceso de forma manual.

En Linux hay muchas formas de arrancar el servidor MySQL. (Ver el punto 5.1 del
Manual de Referencia de MySQL). Una de las formas más simples y seguras es arrancar
el servidor a través del script de arranque mysqld_safe que suele encontrarse en la
carpeta /usr/bin en la mayoría de las distribuciones. Por lo tanto abrimos una terminal
y pulsamos el comando
/usr/bin/mysqld_safe &

Detener el proceso servidor en Windows.

Si tenemos el proceso servidor asociado a un servicio de Windows (lo más habitual)


pulsamos botón derecho del ratón sobre el servicio que queremos iniciar y
seleccionamos Detener.

En caso contrario lo mejor es usar el programa mysqladmin desde la consola de


comandos de Windows y añadirle la orden shutdown
Ejemplo con usuario administrador de MySQL sin password
C:\> mysqladmin shutdown
Ejemplo con usuario administrador de MySQL con password
C:\>mysqladmin -uroot -ppassword shutdown

Detener el proceso servidor en Linux.

En Linux lo más cómodo es usar el programa mysqladmin exactamente igual como se


ha comentado en el apartado anterior para detener el proceso servidor en Windows
MySQL Documento de Administración 32

Tema 11.
Administración de MySQL (I)
Javier Robles Cascallar

11.1. Estructura interna


Cada propio sistema de base de datos tie ne una manera de organizar los datos y la
información que manipula y por lo tanto MySQL tiene su forma particular que se va a
detallar en este punto del documento.

11.1.1 Localización del directorio de datos

El directorio de datos hace referencia a la ubicación de la información que maneja el


servidor (mysqld). En este directorio (carpeta) se almacenan tanto las bases de datos
como los ficheros de estado (archivos de estado) que proporcionan la información sobre
la operación de los servidores.
En Windows la ubicación típica suele ser c:\mysql\data. Si no se conoce la ubicación
hay varias maneras de encontrarla:
• Utilizando mysqladmin variables.
En Windows :
C:\mysql\bin>mysqladmin variables | more

[el uso de more es para detener la salida pantalla a pantalla]


[Buscamos en la salida generada la siguiente línea donde indica el valor de la
variable datadir]

| datadir | C:\mysql\data\

• Buscando los archivos de tipo .frm (descripción) que forman parte de cualquier
instalación de MySQL
En Windows:
MySQL Documento de Administración 33

11.1.2 Estructura del directorio de datos


Las bases de datos de MySQL se encuentran organizadas en una estructura en árbol que
es implementado aprovechando la estructura jerárquica de archivos de los sistemas
operativos sobre los que trabaja (Windows, UNIX, Linux,…). De tal manera que en
líneas generales cada base de datos se corresponde con una carpeta bajo el directorio de
datos y las tablas de esa base de datos se corresponden con los archivos de esa carpeta.
Si se crea una base de datos llamada prueba las tablas de esa base de datos se
almacenarán en la carpeta DATADIR\prueba (siendo DATADIR el directorio de datos por
ejemplo c:\mysql\data)
C:\MySQL5\data>tree
Listado de rutas de carpetas
El número de serie del volumen es 000002C6 1229:8B69
C:.
+---mysql
+---prueba
+---test

11.1.3 Arquitecturas de almacenamiento de las tablas.

En este apartado es necesario detenerse en la forma que MySQL realiza el


almacenamiento interno de los datos. MySQL tiene 6 formas de almacenamiento o
indexación de la información que son las siguientes.

• MyISAM
• MERGE
• MEMORY (HEAP)
• BDB (Berkeley DB)
• ISAM
• InnoDB

MyISAM es la que se emplea por defecto en una instalación típica de MySQL a partir de
la versión 3.23 (es una versión mejorada de ISAM )

InnoDB es la que se emplea y se instala en este curso por que permite control efectivo de
transacciones, capacidad de bloqueo a nivel de fila y soporta la utilización de claves
ajenas.

El resto de métodos de almacenamiento es menos utilizado y no se va a entrar en este


documento a detallar sus características. (Remitimos al lector al manual de referencia de
MySQL)

11.1.3.1 Tablas MyISAM

Cada tabla de la base de datos existe como tres archivos en la carpeta de la base de datos
correspondiente: un archivo de formulario (o descripción), un archivo de datos y un
archivo índice. El nombre base de cada archivo coincide con el nombre de la tabla y
solo la extensión diferencia cada tipo de archivo.
MySQL Documento de Administración 34

Tipo de archivo Extensión Contenido del archivo


Archivo de formulario .frm Describe la estructura de la
tabla (columnas, tipo de
columnas, etc..)
Archivo de datos .MYD Contiene las filas de la
tabla (los datos)
Archivo de índice .MYI Contiene los índices que se
han creado sobre el archivo
de datos.

Cuando se ejecuta un CREATE TABLE nombre_tabla el servidor crea los tres archivos
(los de datos e índices también se crean aunque indicando que todavía están vacíos)

Por ejemplo si en una base de datos llamada mi_club creo dos tablas llamadas cuotas y
socios se obtiene el siguiente listado de archivos en la carpeta mi_club

C:\MySQL5\data\mi_club>dir
El volumen de la unidad C no tiene etiqueta.
El número de serie del volumen es: 1229-8B69

Directorio de C:\MySQL5\data\mi_club

17/01/2005 12:21 <DIR> .


17/01/2005 12:21 <DIR> ..
26/12/2004 22:14 8.740 cuotas.frm
26/12/2004 22:51 432 cuotas.MYD
26/12/2004 22:51 3.072 cuotas.MYI
26/12/2004 22:14 9.034 socios.frm
26/12/2004 22:15 680 socios.MYD
26/12/2004 22:21 4.096 socios.MYI
6 archivos 26.119 bytes
2 dirs 24.336.830.464 bytes libres

Opciones de almacenamiento para tablas MyISAM:

• fixed: Se selecciona automáticamente cuando la tabla no contiene


columnas tipo VARCHAR, TEXT o BLOB o también si la tabla se crea
con la opción ROW_FORMAT=FIXED en la sentencia de creación de tabla (si
se fuerza la creación de una tabla como fixed las columnas de longitud
variable pasan a tener longitud fija). Esto permite trabajar con tablas de
longitud fija de registro. Se puede acceder a las filas a través únicamente
de su número de fila sin necesidad de desplazamiento (offset) lo cual
permite que los índices asociados a este tipo de tablas sean más
pequeños, rápidos y eficientes. También son tablas que no necesitan
optimizarse ni reconstruirse puesto que no generan fragmentación.

• dinamic: Se selecciona automáticamente este tipo cuando la tabla


contiene, al menos, alguna columna tipo VARCHAR ,TEXT o BLOB o
también si la tabla se crea con la opción ROW_FORMAT=DYNAMIC en la
sentencia de creación de tabla. Estas tablas son de longitud de registro
variable por lo tanto cada fila contiene una cabecera indicando su
longitud. Todas las columnas de cadena (VARCHAR o CHAR) son de
MySQL Documento de Administración 35

tamaño variable incluso aquellas definidas como fijas (CHAR) con


longitud superior a cuatro caracteres.
Este tipo de almacenamiento tiene la ventaja de ahorrar espacio en disco.
Tiene por el contrario la desventaja de que los deletes y updates
generan fragmentación y acaban degradando su uso por lo que en tablas
con alto número de transacciones es conveniente, cada cierto tiempo,
realizar un proceso de optimización de la tabla o desfragmentación. La
optimización de tablas se puede realizar de dos forma s. Lanzando una
sentencia OPTIMIZE TABLE o ejecutando la utilidad myisamchk (que
se encuentra como programa ejecutable en la carpeta bin de la
distribución de MySQL).

Ejemplo de OPTIMIZE TABLE:

mysql> optimize table telefonos2;


+-----------------+----------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+-----------------+----------+----------+----------+
| test.telefonos2 | optimize | status | OK |
+-----------------+----------+----------+----------+
1 row in set (0.02 sec)

• Compressed: Es un formato para tablas de solo- lectura generado con la


herramienta myisampack que se encuentra en la carpeta bin de la
distribución de MySQL.
Este tipo de tablas se caracterizan por su ahorro de espacio en disco lo
que minimiza el uso de disco y es muy conveniente para dispositivos de
almacenamiento lentos como los CD-ROM.
Ejemplo de uso de myisampack sobre una tabla de nombre telefonos2 que
contiene 10000 registros:

C:\mysql\bin>myisampack ..\data\test\telefonos2
Compressing ..\data\test\telefonos2.MYD: (10000 records)
- Calculating statistics
- Compressing file
66.69%

Para volver a obtener la tabla original (descomprimida y en modo lectura


y escritura) usamos la herramienta myisamchk de la siguiente forma:

C:\mysql\bin>myisamchk -u ..\data\test\telefonos2
- recovering (with keycache) MyISAM-table
'..\data\test\telefonos2'
Data records: 10000

11.1.3.2 Tablas MERGE

Las tablas tipo MERGE no contienen datos por si mismas sino que hacen referencia a
dos o más tablas tipo MyISAM a través de una cláusula UNION.
MySQL Documento de Administración 36

CREATE TABLE parte1 (


campo1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
campo2 CHAR(20))
TYPE=MYISAM;
CREATE TABLE parte2 (
campo1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
campo2 CHAR(20))
TYPE=MYISAM;

INSERT INTO parte1 (campo2) VALUES ('uno'),('dos'),('tres');


INSERT INTO parte2 (campo2) VALUES ('cuatro'),('cinco'),('seis');
CREATE TABLE total (
campo1 INT NOT NULL AUTO_INCREMENT,
campo2 CHAR(20), INDEX(campo1))
TYPE=MERGE UNION=(parte1,parte2) INSERT_METHOD=LAST;

Después de crear las tablas podemos seleccionar todas las filas de ambas tablas a partir
de la tabla total

mysql> select * from total;


+--------+--------+
| campo1 | campo2 |
+--------+--------+
| 1 | uno |
| 2 | dos |
| 3 | tres |
| 1 | cuatro |
| 2 | cinco |
| 3 | seis |
+--------+--------+
6 rows in set (0.00 sec)

mysql>

Físicamente al crear una tabla tipo MERGE como una unión de varias tablas MyISAM
se generan dos ficheros uno de ellos con extensión .frm y el otro fichero con extensión
.MRG. En el ejemplo anterior si listamos los ficheros de su carpeta obtenemos:
Directorio de C:\MySQL\data\test

13/01/2005 21:15 <DIR> .


13/01/2005 21:15 <DIR> ..
13/01/2005 21:15 8.598 parte1.frm
13/01/2005 21:16 75 parte1.MYD
13/01/2005 21:15 2.048 parte1.MYI
13/01/2005 21:15 8.598 parte2.frm
13/01/2005 21:16 75 parte2.MYD
13/01/2005 21:15 2.048 parte2.MYI
13/01/2005 21:15 8.598 total.frm
13/01/2005 21:15 74 total.MRG
8 archivos 30.114 bytes
2 dirs 24.379.023.360 bytes libres

C:\MySQL\data\test>

Por supuesto que una ve z definida la tabla MERGE total podemos seguir accediendo y
modificando de forma independiente cada una de las tablas que forman total. Es decir
se puede perfectamente lanzar las siguientes dos sentencias:
MySQL Documento de Administración 37

update total set campo2=’primero’ where campo2=’uno’;


update parte2 set campo2=’quinto’ where campo2=’cinco’;

Una condición indispensable para crear tablas MERGE es que las tablas MyISAM de
partida sean de idéntica estructura.

Borrar una tabla MERGE mediante drop no supone borrar las tablas que la componen,
solo se borra la unión establecida entre las tablas.

11.1.3.3 Tablas MEMORY (HEAP)

Las tablas tipo HEAP (sinónimo de MEMORY) se caracterizan por almacenar todos los
datos de la tabla en memoria. Nunca se accede a disco en una tabla MEMORY para
acceder o guardar datos. Si se reinicia el servidor (¡ojo! el servidor, no la sesión de
cliente) todas las tablas tipo MEMORY estarán vacías de filas aunque conservan sus
estructura.
Ejemplo de creación de una tabla HEAP

CREATE TABLE emp_heap TYPE=MEMORY


SELECT * FROM empleados;

O también
CREATE TABLE emp_heap ENGINE=HEAP
SELECT * FROM empleados;

Estas tipo de tablas se caracterizan por ser extremadamente rápidas puesto que no
necesitan ningún acceso a disco y son muy útiles para crear tablas temporales.

Las tablas tipo HEAP únicamente guardan en disco un fichero con extensión .frm que
almacena la estructura de la tabla.

11.1.3.4 Tablas InnoDB

InnoDB realmente por si solo es un motor de bases de datos muy completo que ha sido
embebido dentro de MySQL.

Las características de las tablas InnoDB son las siguientes:

• Control de transacciones.

• Integridad referencial. Permite definir claves ajenas entre tablas InnoDB


relacionadas para asegurarse de que un registro no puede ser eliminado de una
tabla si aún está siendo referenciado por otra tabla.

• Bloqueo a nivel de filas. Al usar tablas MyISAM, y tener consultas muy grandes
que requieren de mucho tiempo, simplemente no se podían ejecutar más
MySQL Documento de Administración 38

consultas hasta que terminarán las consultas que estaban en ejecución. En


cambio, las tablas InnoDB usan bloqueo a nivel de filas para mejorar de manera
considerable el rendimiento.

• SELECTs sin bloqueo. Como si el bloqueo a nivel de filas no fuera suficiente, el


motor InnoDB usa una técnica conocida como multi- versioning (similar a la
base de datos PostgreSQL) que elimina la necesidad de hacer bloqueos en
consultas SELECT muy simples. Ya no es necesario molestarse porque una
simple consulta de sólo lectura está siendo bloqueada por otra consulta que está
haciendo cambios en una misma tabla.

La diferencia fundamental de InnoDB con respecto a MyISAM es que InnoDB


almacena todos los datos e índices de todas las tablas de todas las bases de datos en un
mismo tablespace que consiste un número reducido de archivos del sistema operativo
formado por ficheros de datos (data files ) y ficheros log (log files).
Si no se cambia la configuración de InnoDB que viene por defecto lo habitual es que se
cree un archivo de datos llamado ibdata1 de 10 Mbytes auto extensible y dos
archivos de log llamados ib_logfile0 y ib_logfile1 todos ellos en el directorio de
datos de MySQL.

Por lo tanto a diferencia del almacenamiento mediante MyISAM lo que hace InnoDB es
en la carpeta correspondiente al nombre de la base de datos crear un único fichero con
extensión .frm donde se describe la estructura de la tabla y los datos e índices quedan
almacenados en el tablespace definido.

Por ejemplo si en una base de datos llamada mi_club creo dos tablas con
almacenamiento InnoDB llamadas cuotas y socios se obtiene el siguiente listado de
archivos en la carpeta mi_club

C:\MySQL5\data\mi_club>dir
El volumen de la unidad C no tiene etiqueta.
El número de serie del volumen es: 1229-8B69
MySQL Documento de Administración 39

Directorio de C:\MySQL5\data\mi_club

17/01/2005 12:21 <DIR> .


17/01/2005 12:21 <DIR> ..
26/12/2004 22:14 8.740 cuotas.frm
26/12/2004 22:14 65 db.opt
26/12/2004 22:14 9.034 socios.frm
3 archivos 17.839 bytes
2 dirs 24.336.830.464 bytes libres
Es importante advertir en este punto que si tenemos instalado MySQL con soporte
InnoDB ello no implica que todas las tablas creadas tengan que ser de tipo InnoDB. El
administrador o cualquier usuario con privilegios de creación de tablas podrá crear
indistintamente tablas MyISAM o tablas InnoDB. El administrador se encargará de
indicar en el fichero de configuración que tipo de tabla es la que se crea por defecto
cuando no se especifica el tipo en la sentencia de SQL.

Es muy sencillo pasar una tabla de un tipo de almacenamiento a otro mediante el uso de
la sentencia ALTER TABLE que permite modificar la estructura de almacenamiento de
la tabla.

El siguiente ejemplo nos indica como a partir de la tabla empleados que inicialmente es
de tipo InnoDB podemos convertirla a tipo MyISAM mediante un ALTER TABLE para
volver a dejarla como estaba mediante un segundo ALTER TABLE:

ALTER TABLE empleados TYPE=MYISAM;

ALTER TABLE empleados TYPE=INNODB;

Las opciones de configuración de las tablas InnoDB son muchísimas y se sale de los
objetivos de este documento el dar una visión, aunque sea somera, de todas ellas. Como
en otras ocasiones remitimos al lector al Manual De MySQL (Concretamente a los
apartados 16.4 InnoDB Configuration y 16.5 InnoDB Startup Options )

Finalmente la siguiente tabla nos muestra una comparativa entre los tipos de
almacenamiento más importantes

Comparativa
MyISAM InnoDB MEMORY
Control de transacciones - X -
Claves ajenas - X -
Nivel de bloqueo Tabla fila tabla

indices BTREE X X -
Indices FULLTEXT X - -
Indices GIS, RTREE 4.1.0 - -
Unicode 4.1.0 4.1.2 -

Merge X - -
Almacenamiento de lectura comprimido X - -
Uso de disco Bajo alto -

Uso relativo de RAM Bajo alto bajo


MySQL Documento de Administración 40

11.2. Configuración
los programas que componen MySQL (mysqld, mysqladmin, etc.) admiten muchas
posibilidades de configuración. Dichas opciones pueden ser especificadas a través de la
línea de comandos o bien en ficheros de opciones. Algunas de las opciones es necesario
establecerlas configurando variables de entorno. Las especificadas a través de la línea
de comandos tienen preferencias sobre los ficheros de opciones y estos sobre los valores
de variables de entorno.

11.2.1 Usar opciones de configuración a través de la línea de comandos.

Las opciones introducidas a través de la línea de comandos deben seguir las siguientes
reglas.

• Siempre se introducen después del nombre del programa.


• La opción siempre va precedida de un guión o dos guiones (- , --) dependiendo
de si se utiliza la forma corta o la forma larga (muchas de las opciones admiten
las dos formas). Por ejemplo ambas líneas a continuación generan la misma
salida que es la ayuda on-line sobre el programa incluida la lista de opciones
admitida:
C:\mysql\bin> mysql --help
C:\mysql\bin> mysql –?
• Algunas de las opciones van seguidas de un valor (el valor que toma la opción)
si se usa la versión larga para el nombre de la opción el valor debe ir precedido
del signo ‘=’. Si se usa la versión corta no es necesario el signo ‘=’ se puede
poner un espacio para separar el nombre del valor pero tampoco es obligatorio
puede ir el nombre de la opción seguida del valor que toma la opción . Por
ejemplo las siguientes tres líneas son equivalentes y significan que se esta
ejecutando el programa mysql desde un equipo cliente para acceder a un host
llamado miservidordb:

C:\mysql\bin>mysql --host= miservidordb


C:\mysql\bin>mysql -h miservidordb
C:\mysql\bin>mysql -hmiservidordb

Una excepción a esta regla del espacio es la opción que permite introducir la
password con la que realiza la conexión al servidor. Solo admite dos formas
--pasword=contraseña o -pcontraseña
no está admitida la entrada
-p contraseña
Esto es debido a que si se introduce la opción –p sin introducir ninguna
contraseña el programa a continuación pide que se introduzca una. Si se
admitiera el espacio el programa no puede saber si lo que viene a continuación
es el nombre de la contraseña o el nombre de otra opción.
• Algunos de los programas tienen variables (parámetros operativos) que son
configurables. La opción –set-variable permite configurar este tipo de
variables. Se puede ver esto con el siguiente ejemplo:
MySQL Documento de Administración 41

El programa mysql tiene una variable que se llama max_allowed_packet que


indica el tamaño máximo del buffer de comunicación que se establece entre
cliente y servidor. Si se quiere ejecutar el programa mysql estableciendo un
tamaño de buffer en 16 Mbytes se lanza la siguiente orden:

C:\mysql\bin>mysql --set-variable=max_allowed_packet=16M

No se va a entrar en este documento a detallar todas las posibles opciones que admiten
los programas de MySQL a través de la línea de comandos. Para ello remitimos al lector
al Manual de Referencia de MySQL donde puede localizar toda la información necesaria
(Muy interesante, si se desea profundizar, es el punto 5.2.1 mysqld Command-Line
Options. Donde se explica de forma detallada las posibilidades de configuración del
servidor mysqld a través de la línea de comandos , de hecho, y como se verá más
adelante, toda la información de este punto es valida para configurar los “ficheros de
opciones” del punto siguiente).

11.2.2 Usar ficheros de opciones (ficheros de configuración).

Los ficheros de opciones o ficheros de configuración sirven para que los programas
MySQL puedan cargar siempre las mismas opciones de configuración al arrancar,
evitando de esta manera que se lancen muchas de las opciones de configuración de
forma manual desde la línea de comandos.

El listado de los programas MySQL que soportan ficheros de configuración es el


siguiente:

myisamchk, mysqlcheck,
myisampack, mysqld_safe,
mysql, mysqldump,
mysql.server, mysqld,
mysqladmin, mysqlhotcopy,
mysqlbinlog, mysqlimport,
mysqlcc, mysqlshow.

Los programas MySQL pueden consultar más de un fichero de configuración (o no


consultar ninguno) dependiendo de la ubicación en la que se encuentren dentro del
sistema operativo correspondiente.

Bajo Windows se comprueban los siguientes ficheros en el orden dado:

Nombre fichero Contenidos


WINDIR\my.ini Opciones globales
C:\my.cnf Opciones globales

WINDIR hace referencia a la ruta del sistema de Windows (típicamente ‘C:\Windows'


o ‘C:\WinNT').
MySQL Documento de Administración 42

Bajo UNIX/Linux se comprueban los siguientes ficheros en el orden dado:

Nombre fichero Contenidos


/etc/my.cnf Opciones globales
DATADIR/my.cnf Opciones especificas del servidor
~/.my.cnf Opciones especificas del usuario

DATADIR hace referencia al directorio de datos de MySQL.

La sintaxis de estos ficheros de configuración es muy similar a lo ya visto en el punto


anterior mediante entradas a través de la línea de comandos.

Las líneas en blanco se ignoran. Las líneas que no están en blanco deben ser de alguno
de los siguientes tipos:
#comentario
;comentario
Las líneas comentadas pueden empezar con ‘#’ y ‘;’

[grupo]
grupo es el nombre del programa MySQL sobre el que a continuación y sobre
el fichero se establecen las opciones de configuración. El nombre de grupo
client permite especificar opciones que se aplican de forma común a todos los
programas cliente.

nombre-opcion
Es el equivalente a --nombre-opcion en la línea de comandos.

nombre-opcion=valor
Es el equivalente a --nombre-opcion=valor en la línea de comandos.

set-variable = nombre_variable=valor
Es el equivalente a --set-variable = nombre_variable=valor en la línea
de comandos. Los espacios son válidos alrededor del primer signo ‘=’ pero no
son permitidos alrededor del segundo.
MySQL Documento de Administración 43

Ejemplo de fichero de opciones my.ini

#Opciones de configuración para el servidor mysqld


[mysqld]
basedir=C:/mysql
datadir=C:/mysql/data

#la siguiente línea permite poner los mensajes de error


#en castellano (comprobar el path)
language=C:/mysql/share/spanish

# descomentar solo si se desea cambiar el puerto por defecto


#port=3306

# Configuración del soporte InnoDB


#################################
# El nombre del tablespace es ibdata1 de 10Mbytes
# y auto extensible
innodb_data_file_path = ibdata1:10M:autoextend
#
# El tamaño para el buffer pool suele ser un 50%
# de la memoria ram del equipo
set-variable = innodb_buffer_pool_size=70M
# El tamaño adicional de pool se usa para alocar
#el diccionario de datos
set-variable = innodb_additional_mem_pool_size=10M
#
# Opciones para la configuración de los ficheros log
# se suele reservar el 25% del espacio reservado para el buffer pool
set-variable = innodb_log_file_size=20M
set-variable = innodb_log_buffer_size=8M
#La siguiente línea lo normal es ponerla a valor 1
innodb_flush_log_at_trx_commit=1
#La siguiente línea indica que las tablas por defecto se
#crean en modo InnoDB
default-table-type=innodb
########################################

[WinMySQLadmin]
Server=C:/mysql/bin/mysqld-max-nt.exe
user=admin
password=admin
MySQL Documento de Administración 44

11.3. Administración de cuentas de usuario y


seguridad

Este apartado proporciona información acerca de cómo el administrador MySQL


puede cumplir una de las tareas más importantes que tiene encomendada y es la
responsabilidad de mantener seguros los contenidos de las bases de datos para que los
registros sean accesibles únicamente por aquellos usuarios con autorización para ello

El administrador debe ser capaz de establecer cuentas de usuario de MySQL indicando


- que usuarios pueden conectar al servidor
- desde donde pueden conectar
- que pueden hacer mientras están conectados

El sistema de privilegios de MySQL asegura que todos los usuarios puedan hacer
exactamente las cosas que les son permitidas. Cuando se hace una conexión al servidor
MySQL, la identidad es determinada por el host desde el cual se hace la conexión y
el nombre de usuario. MySQL considera ambos el hostname y el nombre de usuario
en la identificación por esta razón se asume que un usuario dado se puede conectar
desde diferentes partes.

Por ejemplo: el usuario Pepe que se conecta desde cnice.mecd.es no necesita ser la
misma persona para conectarse como usuario Pepe desde educa.madrid.org MySQL
maneja esto para permitir que se distingan los usuarios en diferentes hosts que a
menudo tienen el mismo nombre: se puede otorgar un conjunto de privilegios para
conectarse desde cnice.mecd.es y otro conjunto de privilegios para la conexión desde
educa.madrid.org. El control de acceso al servidor se desarrolla en dos partes:

• El servidor chequea si está permitida la conexión.


• Asumiendo que existe una conexión, el servidor chequea cada petición que se
emita para ver sí se tiene suficientes privilegios para ejecutarla.

11.3.1 Introducción a las sentencias GRANT y REVOKE

A partir de la versión 3.22.11 de MySQL se introducen dos sentencias que son capaces
de realizar la tarea de la administración de cuentas de usuario. Dichas sentencias son
GRANT y REVOKE.
GRANT crea los usuarios y especifica sus privilegios y REVOKE elimina estos
privilegios.

El “diccionario de datos” de MySQL se encuentra en el “directorio de datos” en una


base de datos llamada mysql. En esta base de datos aparecen cuatro tablas que recogen
la información necesaria para especificar los usuarios y sus privilegios. GRANT y
REVOKE proporcionan una alternativa más cómoda a la manipulación directa del
contenido de estas tablas. Las tablas son las siguientes:
MySQL Documento de Administración 45

Nombre de tabla Contenido


user Usuarios que pueden conectar con el
servidor
db Privilegios a nivel de base de datos
tables_priv Privilegios a nivel de tabla
columns_priv Privilegios a nivel de columna

11.3.2 Sintaxis de la sentencia GRANT


GRANT privilegios (columnas)
ON nivel_privilegio
TO usuario@host IDENTIFIED BY “contraseña”
WITH GRANT OPTION

Para usar la sentencia tenemos que rellenar las partes que están en cursiva en la
sentencia anterior y que se explican brevemente a continuación

• Privilegios.

La tabla de los privilegios más importantes que se pueden conceder a un usuario es


la que se muestra a continuación

Privilegio Significado del privilegio


Privilegios aplicados a bases de datos, tablas y columnas
ALTER Permite alterar tablas e índices (ALTER TABLE)
CREATE Permite crear bases de datos y tablas (CREATE TABLE)
CREATE TEMPORARY Permite crear tablas temporales (CREATE TEMPORARY
TABLES
TABLE )
DELETE Permite borrar registros de las tablas existentes
(DELETE)
DROP Permite eliminar bases de datos y tablas (DROP TABLE )
INDEX Permite crear y eliminar índices asociados a tablas
(CREATE INDEX y DROP INDEX)
INSERT Permite insertar nuevos registros en tablas (INSERT)
SELECT Permite consultar información de tablas (SELECT)
UPDATE Permite modificar el contenido de registros existentes
(UPDATE)
Privilegios administrativos
FILE Permite leer y escribir archivos en el servidor
( SELECT ... INTO OUTFILE y LOAD DATA INFILE )
PROCESS Permite ver información sobre los procesos abiertos en
el servidor (SHOW FULL PROCESSLIST )
RELOAD Permite solicitar al servidor que cargue de nuevo en
memoria las tablas del diccionario de datos (FLUSH)
REPLICATION CLIENT Permite al usuario preguntar donde esta el servidor
esclavo o el maestro
MySQL Documento de Administración 46

REPLICATION SLAVE Permiso necesario para que el usuario pueda acceder al


fichero binary log del maestro desde el esclavo
SHUTDOWN Permite cerrar el servidor (mysqladmin shutdown)
Privilegios especiales
ALL [PRIVILEGES] Permite agrupar todos los privilegios en uno solo.
USAGE Es un privilegio especial que significa “ausencia de
privilegios”

• Nivel de privilegio.
Los privilegios pueden aplicarse a cuatro niveles

1. Nivel global. Se aplican los privilegios a todas las bases de datos y


todas las tablas del servidor.
La forma de indicar el nivel global será la siguiente:
GRANT privilegios ON *.* …
2. Nivel de base de datos. Se aplican los privilegios sobre todas las tablas
de la base de datos nombrada en la sentencia.
La forma de indicar el nivel de base de datos será la siguiente:
GRANT privilegios ON nombre_bd.* …
3. Nivel de tabla. Se aplican los privilegios sobre todas las columnas de la
tabla nombrada de la base de datos nombrada.
La forma de indicar el nivel de tabla será la siguiente:
GRANT privilegios ON nombre_bd.nombre_tabla …
4. Nivel de columna. Se aplican los privilegios sobre la/s columna/s
seleccionadas de una tabla determinada.

• Usuario@Host.

El nombre del usuario al que se le están asignando los privilegios. Consiste en un


nombre de usuario y un nombre de host (se especifica quien puede conectarse y
desde donde). Esto posibilita tener dos usuarios de idéntico nombre que se
conectan desde diferentes localizaciones y por lo tanto se les pueden administrar
privilegios distintos dependiendo de donde se conecten.

Los nombres de usuario de MySQL son independientes de los nombres de usuarios


de los Sistemas Operativos del equipo sobre el que están intentando efectuar la
conexión al servidor de base de datos.

Se puede permitir que un usuario se conecte desde un host específico o desde un


conjunto de ellos.

Como nombre de host se pueden utilizar direcciones IP o nombres DNS


Esta permitido el uso de caracteres comodín (‘%’) para direcciones IP o nombres
DNS.

La siguiente tabla muestra algunos ejemplos de nombres de usuario y nombres de


host que permiten ver las posibilidades de conexión que existen con las diferentes
combinaciones que se pueden dar:
MySQL Documento de Administración 47

host Usuario Conexiones permitidas con la


combinación usuario@host
'www.mecd.es' 'juan' juan, conectando desde el host
www.mecd.es
'www.mecd.es' '' Cualquier usuario, conectando desde
el host www.mecd.es
'%' 'juan' juan, conectando desde cualquier
host
'%' '' Cualquier usuario, conectando desde
cualquier host
'%. mecd.es ' 'juan' juan, conectando desde algún host
del dominio mecd.es
'x.y.%' 'juan' juan, conectando desde los host
x.y.es, x.y.com, x.y.org, etc.. (Se
puede usar aunque no parece muy
útil)
'144.155.166.177' 'juan' juan, conectando desde el host con
IP 144.155.166.177
'144.155.166.%' 'juan' juan, conectando desde cualquier
host de la subred 144.155.166
'144.155.166.0/255.255.255.0' 'juan' Otra forma de poner el ejemplo
anterior

• Contraseña.
La cláusula IDENTIFIED BY no es obligatoria, pero su ausencia, si el usuario no
existe, implica la creación de un usuario nuevo sin contraseña (lo cual por razones
evidentes de seguridad no es muy aconsejable). Si el usuario existe la contraseña
que acompaña la cláusula sustituye la anterior y si el usuario existe y no se usa la
cláusula IDENTIFIED BY permanece vigente la que tenia antes.

• Cláusula WITH GRANT OPTION.


Significa que el usuario tiene la posibilidad de transmitir sus privilegios a otros
usuarios. Por supuesto esta cláusula es opcional y se utiliza para permitir delegar
capacidades de transferencia a otros usuarios.

11.3.3 Sintaxis de la sentencia REVOKE

La sintaxis de REVOKE es muy parecida a GRANT excepto que TO es reemplazado


por FROM y no aparecen las cláusulas IDENTIFIED BY y WITH GRANT OPTION.

REVOKE privilegios (columnas)


ON nivel_privilegio
FROM usuario

La parte usuario de la sentencia REVOKE debe coincidir con la parte usuario de la


sentencia GRANT original cuyos privilegios se quieren revocar. Por el contrario la
parte privilegios no necesita coincidir por que puede que el administrador quiera
revocar solo parte de los privilegios que se le concedió al usuario inicialmente.
MySQL Documento de Administración 48

A partir de la versión 4.1.2 de MySQL existe una forma más cómoda de eliminar de
golpe todos los privilegios de un usuario (o varios)

REVOKE ALL PRIVILEGES, GRANT OPTION FROM usuario,usuario,…;

Eliminar todos los privilegios no supone la eliminación del usuario ya que este aun
permanece como un registro en la tabla user lo que significa que el usuario puede
conectar con el servidor.

11.3.4 Algunos ejemplos de la sentencia GRANT


shell> mysql --user=root mysql
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost
IDENTIFIED BY 'algo' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@"%"
IDENTIFIED BY 'algo' WITH GRANT OPTION;
mysql> GRANT RELOAD, PROCESS ON *.* TO admin@localhost;
mysql> GRANT USAGE ON *.* TO dummy@localhost;

Aquí se ha n creado tres nuevos usuarios: monty: Un superusuario el cual puede


conectarse al servidor desde cualquier parte, pero debe usar un password (como ser
algo). Notar que se debe emitir GRANT para monty@localhost y monty@"%". Si no
se agrega la entrada con localhost, el usuario anónimo entra por el localhost que es
creado por mysql_install_db tomando prioridad cuando se conecte desde un host local,
porque éste posee un valor de campo Host más específico y viene primero en el orden
de serie de la tabla user. admin: Un usuario que puede conectarse desde el localhost sin
un password y al cual se le otorga los privilegios de administración reload y process. A
este usuario se le permite ejecutar los comandos mysqladmin reload, mysqladmin
refresh y mysqladmin flush-*, así como también mysqladmin processlist. dummy: Un
usuario que puede conectarse sin un password, pero sólo desde host local. Los
privilegios globales son todos colocados a "N", el tipo de privilegio USAGE permite
colocar un usuario con ningún privilegio. Este asume que se deben otorgar privilegios
específicos para las bases de datos.

El siguiente ejemplo agrega un usuario cliente el cual puede conectarse desde los
siguientes hosts: localhost, server.domain y casa.gov. Éste desea acceder a la base de
datos Bancaria sólo desde el hostlocal, a la base de datos Costos sólo desde el host
casa.gov y a la base de datos Clientes desde los tres host. Se usará el password mipass
para los tres hosts. Se otorgaran estos privilegios usando ambos métodos.
shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON Bancaria.*
TO cliente@localhost
IDENTIFIED BY 'mipass';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON Costos.*
TO [email protected]
IDENTIFIED BY 'mipass';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON Clientes.*
TO cliente@'%'
IDENTIFIED BY 'mipass';
MySQL Documento de Administración 49

Si se desea dar acceso a un usuario específico desde cualquier máquina en un dominio


dado, se puede usar tanto la cláusula GRANT como INSERT de la siguiente forma:
mysql> GRANT ...
ON *.*
TO myusername@"%.mydomainname.com"
IDENTIFIED BY 'mypassword';

11.3.5 Eliminar una cuenta de usuario.

Para eliminar completamente una cuenta de usuario la sentencia que se utiliza es


DROP USER (antes de la versión 4.1.1 se usaba la sentencia DELETE).

Para poder eliminar completamente un usuario este ha tenido que ser revocado
previamente de todos sus privilegios.

Si no estamos seguros de los privilegios que tiene un determinado usuario podemos


usar la sentencia SHOW GRANTS para verlo. Por ejemplo

mysql> SHOW GRANTS FOR 'admin'@'localhost';

Si aparece un listado con privilegios debemos usar la sentencia REVOKE para


quitárselos antes de poder utilizar DROP USER.

mysql> DROP USER 'admin'@'localhost';


MySQL Documento de Administración 50

11.4. Índices.
Los índices son usados para encontrar rápidamente los registros que tengan un
determinado valor en alguna de sus columnas. Sin un índice, MySQL tiene que iniciar
con el primer registro y leer a través de toda la tabla para encontrar los registros
relevantes. Aún en tablas pequeñas, de unos 1000 registros, es por lo menos 100 veces
más rápido leer los datos usando un índice, que haciendo una lectura secuencial o
“escaneo completo de una tabla”.

En particular, debemos evitar las escaneos completos de tablas por las siguientes
razones:

Sobrecarga de CPU. El proceso de chequear cada uno de los registros en una tabla es
insignificante cuando se tienen pocos datos, pero puede convertirse en un problema a
medida que va aumentando la cantidad de registros en nuestra tabla.

Concurrencia. Mientras MySQL está leyendo los datos de una tabla, éste la bloquea,
de tal manera que nadie más puede escribir en ella, aunque si pueden leerla. Cuando
MySQL está actualizando o eliminando filas de una tabla, éste la bloquea, y por lo
tanto nadie puede al menos leerla.

Sobrecarga de disco. En una tabla muy grande, un escaneo completo consume una
gran cantidad de entrada/salida en el disco.

En resumen, lo mejor es tratar de que los escaneos completos de tablas sean mínimos -
- especialmente si nuestra aplicación necesita escalabilidad en tamaño, número de
usuarios, o ambos.

Cuando indexamos una columna en particular, MySQL crea otra estructura de datos
(un índice) que usa para almacenar información extra acerca de los valores en la
columna indexada. Los valores indexados son llamados frecuentemente claves.
Aunque esta es la manera simple de explicar los índices, realmente es un poco más
complejo, ya que MySQL almacena todas las claves del índice en una estructura de
datos de árbol. Esta estructura de datos de árbol le permite a MySQL encontrar claves
muy rápidamente.

11.4.1 Tipos de índices y su creación

Existen cuatro tipos de índices que podemos utilizar en MySQL:

• de clave primaria
• únicos
• de texto completo
• ordinarios

Cada uno de ellos será explicado a continuación.


MySQL Documento de Administración 51

Índices de clave primaria

Una clave primaria, como ya sabemos, es un índice sobre uno o más campos donde
cada valor es único y ninguno de los valores son NULL.

Para crear un índice de clave primaria tenemos básicamente dos opciones:

1. Crear el índice de clave primaria al momento de crear la tabla. En este caso se usa,
como ya sabemos la opción PRIMARY KEY al final de la definición de los campos,
con una lista de los campos que serán parte del índice.

2. Crear una clave primaria en una tabla existente con el uso del comando ALTER
TABLE:

La sentencia DESC es útil para ident ificar las columnas que son clave primaria en la
tabla
mysql> DESC usuarios;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| nombre | varchar(50) | YES | | NULL | |
| apellidos | varchar(70) | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

El campo id no tiene un valor YES en la columna Null, lo que indica que este campo
ya no podrá almacenar valores nulos. Se puede observar también que se tiene un valor
PRI en la columna Key, lo que indica que este campo es una clave primaria.

Las claves primarias pueden constar de más de un campo. Hay algunas veces en las
que un solo campo no puede identificar de manera única a un registro.

Índices ordinarios

Son índices que no son primarios y permiten valores duplicados (a menos que los
campos hayan sido especificados como UNIQUE).

Para crear un índice ordinario tenemos básicamente tres opciones:

1. Podemos crear un índice ordinario al mismo tiempo que creamos la tabla


con el uso de la opción INDEX.

CREATE TABLE nombreTabla(campo1 tipoDato, campo2 tipoDato,..


INDEX [nombreIndice] (campo1 [,campo2...]));

2. De igual manera, podemos crear el índice con el uso de la sentencia


ALTER TABLE si es que la tabla ya existe.
MySQL Documento de Administración 52

ALTER TABLE nombreTabla ADD INDEX [nombreIndice] (campo1


[,campo2...]);

3. También es posible usar la sentencia CREATE INDEX para crear un índice


en una tabla existente.

CREATE INDEX nombreIndice ON nombreTabla(campo1 [,campo2...]);

De todas las formas se pide el nombre del índice, sin embargo con la sentencia CREATE
INDEX el nombre es obligatorio.

Por ejemplo, para la siguiente definición de tabla:

CREATE TABLE usuarios(id int, nombre varchar(50), apellidos


varchar(70));

Se puede crear un índice en la columna apellidos con una sentencia ALTER TABLE:

ALTER TABLE usuarios ADD INDEX idx_apellidos (apellidos);

O bien, con una sentencia CREATE INDEX:

CREATE INDEX idx_apellidos ON usuarios(apellidos);

Índices de texto completo

Los índices de texto completo son del tipo FULLTEXT, se usan en tablas del tipo
MyISAM, y pueden contener uno o más campos del tipo CHAR, VARCHAR y TEXT. Un
índice de texto completo está diseñado para facilitar y optimizar la búsqueda de
palabras clave en tablas que tienen grandes cantidades de información en campos de
texto.

Para crear un índice de texto completo tenemos básicamente las mismas tres opciones:

1. CREATE TABLE nombreTabla( campo1 TIPO, campo2 TIPO,


FULLTEXT [nombreIndice] (campo1 [campo2,...]) );

2. ALTER TABLE nombreTabla ADD FULTEXT [nombreIndice] (campo1


[,campo2,...]);

3. CREATE FULLTEXT INDEX nombreIndice ON nombreTabla(campo1


[,campo2,...]);

Como ejemplo consideremos la siguiente definición de tabla:

CREATE TABLE usuarios(id int, nombre varchar(50), apellidos


varchar(70));

Podríamos crear un índice FULLTEXT en la columna nombre, en la columna


apellidos, o bien, un índice que ocupe ambos campos. A continuación se muestran
los tres casos.

CREATE FULLTEXT INDEX idx_nombre ON usuarios(nombre);


MySQL Documento de Administración 53

CREATE FULLTEXT INDEX idx_apellidos ON usuarios(apellidos);

CREATE FULLTEXT INDEX idx_nombre_apellidos ON


usuarios(nombre,apellidos);

- Nota: Cuando se tienen grandes cantidades de datos, es mucho más rápido cargar los
datos en una tabla que no tiene índices de texto completo y después crear los índices
necesarios, ya que la carga de datos en una tabla que ya tiene índices de este tipo es un
proceso lento.

Índices únicos

Los índices únicos son básicamente como los índices ordinarios, excepto que los
valores duplicados no son permitidos.

Para crear un índice UNIQUE se tienen de nuevo las mismas tres opciones:

1. CREATE TABLE nombreTabla(campo1 tipoDato, campo2 tipoDato,..


UNIQUE [nombreIndice] (campo1 [,campo2...]));

2. ALTER TABLE nombreTabla ADD UNIQUE [nombreIndice] (campo1,


campo2) ...

3. CREATE UNIQUE INDEX nombreIndice ON nombreTabla(campo1


[,campo2...]);

Siguiendo con el ejemplo, consideremos de nuevo la siguiente definición de tabla:

CREATE TABLE usuarios(id int, nombre varchar(50), apellidos


varchar(70));

Podríamos crear un índice UNIQUE en la columna nombre, y un índice UNIQUE en la


columna apellidos.

ALTER TABLE usuarios ADD UNIQUE idx_nombre (nombre);

CREATE UNIQUE INDEX idx_apellidos ON usuarios(apellidos);

En el primer caso hacemos uso del comando ALTER TABLE, y en el segundo caso
creamos el índice con la sentencia CREATE INDEX.
MySQL Documento de Administración 54

11.4.2 Eliminar o cambiar un índice

Algunas veces tendremos la necesidad de cambiar o eliminar un índice. Cuando


hagamos algún cambio en el índice, necesitamos eliminar primero el índice y entonces
reconstruirlo con la nueva definición.

Para eliminar un índice de clave primaria podemos usar la siguiente sintaxis:

ALTER TABLE nombreTabla DROP PRIMARY KEY;

Para eliminar un índice ordinario, único, o de texto completo, necesitamos especificar


el nombre del índice y usar esta sintaxis:

ALTER TABLE nombreTabla DROP INDEX nombreIndice;

También es válida esta otra sintaxis:


DROP INDEX nombreIndice ON nombreTabla;

Si no estamos seguros de cuál es el nombre del índice que deseamos eliminar,


podemos hacer uso de la sentencia SHOW KEYS :

SHOW KEYS FROM nombreTabla;

Este es un ejemplo.
CREATE TABLE usuarios
(
id INT NOT,
nombre VARCHAR(50) NOT NULL,
apellidos VARCHAR(70) NOT NULL,
PRIMARY KEY (id),
INDEX (nombre, apellidos)
);

Veamos los índices que existen en esta tabla:

mysql> SHOW KEYS FROM usuarios;


+----------+------------+----------+--------------+-------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name |
+----------+------------+----------+--------------+-------------+ .
| usuarios | 0 | PRIMARY | 1 | id | .
| usuarios | 1 | nombre | 1 | nombre | .
| usuarios | 1 | nombre | 2 | apellidos |
+----------+------------+----------+--------------+-------------+

3 rows in set (0.00 sec)

La tercera columna es la que nos proporciona los nombres de los índices. Podemos
observar que al no especificar un nombre al índice ordinario en (nombre, apellidos), se
le ha asignado el nombre de la primera columna que forma el índice.

A continuación vamos a eliminar los dos índices que existen en esta tabla:

mysql> ALTER TABLE usuarios DROP PRIMARY KEY;


MySQL Documento de Administración 55

Query OK, 0 rows affected (0.01 sec)


Records: 0 Duplicates: 0 Warnings: 0

mysql> ALTER TABLE usuarios DROP INDEX nombre;


Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0

Por último, podemos verificar que estos índices ya no existen:

mysql> SHOW KEYS FROM usuarios;


Empty set (0.00 sec)

11.4.3 Uso eficiente de los índices

Dado que los índices hacen que las consultas se ejecuten más rápido, podemos estar
incitados a indexar todas las columnas de nuestras tablas. Sin embargo, lo que tenemos
que saber es que el usar índices tiene un precio. Cada vez que hacemos un INSERT,
UPDATE, o DELETE sobre una tabla, MySQL tiene que actualizar cualquier índice en la
tabla para reflejar los cambios en los datos.

¿Así que, cómo decidimos usar índices o no?. La respuesta es "depende". De manera
simple, depende que tipo de consultas ejecutamos y que tan frecuentemente lo
hacemos, aunque realmente depende de muchas otras cosas.

La razón para tener un índice en una columna es para permitirle a MySQL que ejecute
las búsquedas tan rápido como sea posible (y evitar los escaneos completos de tablas).
Podemos pensar que un índice contiene una entrada por cada valor único en la
columna. En el índice, MySQL debe contar cualquier valor duplicado. Estos valores
duplicados decrementan la eficiencia y la utilidad del índice.

Así que antes de indexar una columna, debemos considerar que porcentaje de entradas
en la tabla son duplicadas. Si el porcentaje es demasiado alto, seguramente no veremos
alguna mejora con el uso de un índice.

Otra cosa a considerar es qué tan frecuentemente los índices serán usados. MySQL
puede usar un índice para una columna en particular únicamente si dicha columna
aparece en la cláusula WHERE en una consulta.

Si muy rara vez usamos una columna en una cláusula WHERE, seguramente no tiene
mucha sentido indexar dicha columna. De esta manera, probablemente sea más
eficiente sufrir el escaneo completo de la tabla las raras ocasiones en que se use esta
columna en una consulta, que estar actualizando el índice cada vez que cambien los
datos de la tabla.

Ante la duda, no tenemos otra alternativa que probar. Siempre podemos ejecutar
algunas pruebas sobre los datos de nuestras tablas con y sin índices para ver como
obtenemos los resultados más rápidamente. Lo único a considerar es que las pruebas
sean lo más realistas posibles.
MySQL Documento de Administración 56

11.5. Backup
MySQL ofrece varias alternativas para hacer copias de seguridad de sus bases de datos
y posteriormente restaurarlas.

Para bases de datos que contengan tablas InnoDB lo más aconsejable es el uso de la
herramienta cliente mysqldump.

Para bases de datos con tablas exclusivamente MyISAM puede ser una alternativa el
uso de la herramienta mysqlhotcopy (mas rápida que mysqldump). La herramienta
mysqlhotcopy funciona de forma similar a lo que seria la copia directa usando
comandos de copia propios del sistema operativo sobre el que se ejecuta MySQL.

Muy importante para llevar una política eficaz de copias de seguridad seguir los
siguientes principios:

• Realizar copias de seguridad regularmente

• Activar los logs de actualización (binary log se ve en el punto siguiente de


este documento). Los logs de actualización permiten, una vez restaurada la
copia de una BD dañada, volver a aplicar las operaciones que se realizaron
después de efectuado el ultimo proceso de back up. Es decir permite llevar de
nuevo las tablas al punto inmediatamente anterior al momento que se decidió
restaurar la copia.

• Usar un esquema para nombrar archivos de copia de seguridad coherente y


comprensible y establecer una política de rotación de copias.

11.5.1 mysqldump

Esta herramienta permite hacer la copia de seguridad de una o múltiples bases de


datos. Además permite que estas copias de seguridad se puedan restaurar en distintos
tipos de gestores de bases de datos, sin la necesidad de que se trate de un gestor de
MySQL. Esto lo consigue creando unos ficheros, que contienen todas las sentencias
SQL necesarias para poder restaurar la tabla, que incluyen desde la sentencia de
creación de la tabla, hasta una sentencia de inserción por cada uno de los registros que
forman parte de la misma.
mysqldump dispone de una amplia variedad de opciones que nos permitirá realizar la
copia de la forma más conveniente para el propósito de la misma.
Para poder restaurar la copia de seguridad, bastará con ejecutar todas las sentencias sql
que se encuentran dentro del fichero, bien desde la línea de comandos de mysql, o
desde la pantalla de creación de sentencias SQL de cualquier entorno gráfico como
puede ser el Mysql Control Center.

Las limitaciones de la restauración dependerán de las opciones que se han especificado


a la hora de hacer la copia de seguridad, por ejemplo, si se incluye la opción --add-
drop-table al hacer la copia de seguridad, se podrán restauran tablas que existen
actualmente en el servidor (borrándolas primero). Por lo que es necesario estudiar
MySQL Documento de Administración 57

primero los procedimientos que se utilizarán tanto en la copia como en la restauración,


para que todo salga correcto.

Las opciones de configuración de mysqldump son muchas y vienen detalladas en el


manual de referencia de MySQL (8.8 The mysqldump Database Backup Program).
Algunas de las opciones más interesantes que tiene son:

--add-locks
Añade LOCK TABLES antes, y UNLOCK TABLE después de la copia de cada tabla. De esta forma se
evita que se produzcan modificaciones en la tabla durante el proceso de copia.

--add-drop-table
Añade un drop table antes de cada sentencia create

-A, --all-databases
Copia todas las bases de datos. Es lo mismo que utilizar --databases seleccionando todas.

-a, --all
Incluye todas las opciones de creación específicas de Mysql.

-B, --databases
Para copiar varias bases de datos. En este caso, no se especifican tablas. El nombre de los argumentos se
refiere a los nombres de las bases de datos. Se incluirá USE db_name en la salida antes de cada base de
datos.

-F, --flush-logs
Escribe en d isco todos los logs antes de comenzar con la copia

-f, --force,
Continúa aunque se produzca un error de SQL durante la copia.

-h, --host=..
Copia los datos del servidor de Mysql especificado. El servidor por defecto es localhost.

-d, --no-data
No incluirá ninguna información sobre los registros de la tabla. Esta opción sirve para crear una copia
de sólo la estructura de la base de datos.

--opt
Lo mismo que --quick --add-drop-table --add-locks --extended-insert
--lock-tables. Esta opción le debería permitir realizar la copia de seguridad de la base de datos de
la forma más rápida y efectiva.

-pyour_pass, --password[=your_pass]
Contraseña utilizada cuando se conecta con el servidor. Si no se especifica, `=your_pass',
mysqldump preguntará la contraseña.

Ejemplos de llamadas a mysqldump:

Se quiere realizar una copia de seguridad completa de todas las bases de datos:
mysqldump --opt --all-databases >copia_seg_04_12_04.sql

Se quiere realizar una copia de varias bases de datos completas(bases de datos test y
prueba).
mysqldump --opt --databases test prueba > copia_seg_test_prueba.sql
MySQL Documento de Administración 58

Se quiere realizar una copia de algunas tablas de una base de datos (base de datos test
tablas articulo y almacen)
mysqldump --opt test articulo almacen>copia_seg_test_art_alm.sql

Se quiere realizar la copia se seguridad de la base de datos mibase


mysqldump --opt mibase > copia_seg_mibase_04_12_04.sql

El aspecto de un fichero copia generado por mysqldump es el siguiente:


-- MySQL dump 10.7
--
-- Host: localhost Database: test
-- ------------------------------------------------------
-- Server version 4.1.2-alpha-nt-max-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT,


CHARACTER_SET_CLIENT=utf8 */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */;

--
-- Current Database: `test`
--

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test`;

USE `test`;

--
-- Table structure for table `accesslog`
--

DROP TABLE IF EXISTS `accesslog`;


CREATE TABLE `accesslog` (
`ip` varchar(15) default NULL,
`fecha` varchar(40) default NULL,
`operacion` varchar(5) default NULL,
`fichero` varchar(100) default NULL,
`protocolo` varchar(10) default NULL,
`num1` varchar(5) default NULL,
`num2` varchar(5) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- etc,etc,etc…
--

Restaurar una copia hecha con mysqldump

La manera más directa de restaurar una copia hecha con mysqldump es ejecutando el
cliente mysql desde la línea de comandos y lanzando directamente el script generado
previamente por mysqldump.

Ejemplo el usuario root va a restaurar la copia generada mediante mysqldump el


4/12/2004:
C:\mysql\bin> mysql -uroot -pPassword < copia_seg_mibase_04_12_04.sql
MySQL Documento de Administración 59

11.5.2 mysqlhotcopy (solo Linux , Unix)

Esta herramienta que viene de serie en la distribución de MySQL permite crear copias
de seguridad de las tablas tipo ISAM y MyISAM mientras el servidor esta en
ejecución. Funciona estableciendo un bloqueo de solo lectura (read lock) en las tablas
que se van a copiar, se efectúa la copia y se libera el bloqueo.

mysqlhotcopy es un script de perl y por defecto no esta disponible en las instalaciones


para Windows.

Como ejemplo de uso de mysqlhotcopy lanzando desde la línea de comandos la


siguiente orden

$ mysqlhotcopy -uroot -pPassword prueba /tmp

obtenemos una copia de las tablas de la base de datos prueba. Se habrá creado una
subcarpeta prueba debajo de la carpeta tmp que podemos comprobar ejecutando
$ ls -l /tmp/prueba

total 108

-rw-rw---- 1 mysql users 8550 May 3 12:02 tabla1.frm


-rw-rw---- 1 mysql users 25 May 3 12:02 tabla1.MYD
-rw-rw---- 1 mysql users 2048 May 23 12:58 tabla1.MYI
-rw-rw---- 1 mysql users 8924 Mar 4 21:52 tabla2.frm
-rw-rw---- 1 mysql users 7500 Mar 5 21:11 tabla2.MYD
-rw-rw---- 1 mysql users 5120 May 23 12:58 tabla2.MYI
-rw-rw---- 1 mysql users 8550 May 3 12:02 tabla3.frm
-rw-rw---- 1 mysql users 25 May 3 12:02 tabla3.MYD
-rw-rw---- 1 mysql users 2048 May 23 12:58 tabla3.MYI

Restaurar una copia hecha con mysqlhotcopy

Para restaurar una copia hecha con mysqlhotcopy simplemente tenemos que restaurar
los ficheros a la carpeta del directorio de datos correspondiente de MySQL.

Para restaurar la copia de la base de datos prueba realizada anteriormente lanzamos la


orden
$ cp /tmp/prueba/*.* datadir/prueba
MySQL Documento de Administración 60

11.5.3 Importar tablas desde ficheros de texto delimitados

Prácticamente todos los sistemas de gestión de bases de datos tienen la capacidad de


importar y exportar tablas a ficheros de texto (ASCII) de campos delimitados. Por lo
tanto esta utilidad es muy aconsejable para pasar datos de un SGBD a otro además de
para hacer copias de seguridad de tablas individuales.

Un ejemplo de fichero de texto de campos delimitados podría ser el siguiente:


1112345;"Martínez Salas,;Fernando";"PROFESOR;2200.00;10
4123005;"Bueno Zarco,;Elisa";"PROFESOR";2200.00;10
4122025;"Montes García, M.Pilar";"PROFESOR";2200.00;10
1112346;"Rivera Silvestre, Ana";"PROFESOR";2050.00;15
9800990;"Ramos Ruiz, Luis";"PROFESOR";2050.00;15
8660990;"De Lucas Fdez, M.Angel";"PROFESOR";2050.00;15
7650000;"Ruiz Lafuente, Manuel";"PROFESOR";2200.00;22
43526789;"Serrano Laguía, María";"PROFESOR";2050.00;45
4480099;"Ruano Cerezo, Manuel";"ADMINISTRATIVO";1800.00;10
1002345;"Albarrán Serrano, Alicia";"ADMINISTRATIVO";1800.00;15
7002660;"Muñoz Rey, Felicia";"ADMINISTRATIVO";1800.00;15
5502678;"Marín Marín, Pedro";"ADMINISTRATIVO";1800.00;22
6600980;"Peinado Gil, Elena";"CONSERJE";1750.00;22
4163222;"Sarro Molina, Carmen";"CONSERJE";1750.00;45

Fichero personal.txt

Estos ficheros se caracterizan por estar almacenados en formato ASCII habitualmente


con las extensiones .txt o .csv. Tienen los registros de longitud variable y los campos
están delimitados por un carácter especial (en este caso “;”). También habitualmente
los campos de caracteres vienen entrecomillados.

MySQL proporciona dos métodos para importar directamente este tipo de ficheros a
tablas. Una de ellas es la utilidad mysqlimport , el otro método es lanzar la sentencia
LOAD DATA INFILE. En este apartado se comenta únicamente este último método. La
utilidad mysqlimport se puede ver en detalle en la sección 8.10 del Manual de MySQL.

Sintaxis genérica de la sentencia LOAD DATA INFILE :


LOAD DATA [LOCAL] INFILE 'path/nombre_fichero.txt'
[REPLACE | IGNORE]
INTO TABLE nombre_tabla
[FIELDS
[TERMINATED BY '\t']
[[OPTIONALLY] ENCLOSED BY '']
[ESCAPED BY '\\' ]
]
[LINES
[STARTING BY '']
[TERMINATED BY '\n']
]
[IGNORE number LINES]
[(col_name,...)]

Se observa en esta sintaxis que la mayoría de las cláusulas de esta sentencia son
optativas, vamos a comentar las más interesantes.

Si se especifica la cláusula LOCAL significa que el fichero es leído por el por el


programa cliente en el equipo donde se esta ejecutando el cliente de MySQL desde el
MySQL Documento de Administración 61

que se esta lanzando la sentencia LOAD DATA. Si la cláusula LOCAL se omite significa
que el fichero debe encontrarse en el host del servidor MySQL .
Para poder ejecutar esta sentencia es necesario crear previamente la tabla sobre la que
van a ir los datos. La tabla puede o no estar vacía. Habrá que tener cuidado al hacer
una carga masiva de datos con esta sentencia el evitar entradas duplicadas en campos
marcados como UNIQUE o PRIMARY KEY.

En el siguiente ejemplo se va a crear una tabla y lanzar la sentencia LOAD DATA que
permita cargar los datos del fichero de personal (personal.txt) anterior.

USE TEST;
CREATE TABLE IF NOT EXISTS personal(
dni int(10),
apellidos varchar(30),
funcion enum('PROFESOR','ADMINISTRATIVO','CONSERJE'),
salario float(6,2),
cod_centros int(5),
CONSTRAINT pk_codigo PRIMARY KEY (dni));

LOAD DATA INFILE 'C:\\temp\\personal.txt'


INTO TABLE personal
FIELDS TERMINATED BY ';' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n';

Muy importante es construir correctamente las cláusulas FIELDS y LINES de la


sentencia LOAD DATA. En la cláusula FIELDS indicamos que el carácter delimitador es
el “;” y que las cadenas de texto van entrecomilladas. En la cláusula LINES indicamos
que el carácter de final de línea es ‘\r\n’. (Los ficheros de texto de Windows suelen
llevar \r\n como carácter de final de línea mientras que los ficheros de texto en Linux
es únicamente \n)

Para poder lanzar una sentencia LOAD DATA es necesario ser administrador de la base
de datos o al menos tener concedido el privilegio FILE.
MySQL Documento de Administración 62

11.5.4 Exportar tablas a ficheros de texto delimitados

La sentencia que permite exportar tablas a ficheros ASCII delimitados tiene la


siguiente sintaxis

SELECT columnas INTO OUTFILE 'path/nombre_fichero.txt'


[FIELDS
[TERMINATED BY '\t']
[[OPTIONALLY] ENCLOSED BY '']
[ESCAPED BY '\\' ]
]
[LINES
[STARTING BY '']
[TERMINATED BY '\n']
]
FROM nombre_tabla;

A diferencia de LOAD DATA… la sentencia SELECT…INTO OUTFILE siempre genera el


fichero en el host donde esta ejecutándose el servidor. Si lo que se desea es que el
fichero se cree en el equipo del cliente esta sentencia no nos sirve. Podemos usar en su
lugar el siguiente comando
shell> mysql -e "SELECT ..." > nombre_fichero

En el siguiente ejemplo se va a crear un fichero llamado personal2.txt a partir de la


tabla a tabla personal del punto anterior.

SELECT * INTO OUTFILE 'C:\\temp\\personal2.txt'


FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
FROM personal;

Al igual que ocurre con LOAD DATA para poder lanzar una sentencia SELECT ... INTO
OUTFILE es necesario ser administrador de la base de datos o al menos tener concedido
el privilegio FILE.
MySQL Documento de Administración 63

Tema 12.
Administración de MySQL (II)
Javier Robles Cascallar

12.1. Los ficheros Log


12.1.1 El log de error (error log)

Contiene información indicando cuando se arranca y detiene el servidor y cualquier


error crítico que ocurra mientras el servidor se esta ejecutando.

A no ser que se especifique de forma explicita otro nombre distinto en el fichero de


configuración (my.ini o my.cnt) el log de error llevará el nombre del propio host
seguido de la extensión .err (nombre_host.err) y estará ubicado en el directorio de
datos de MySQL. En sistemas operativos Windows en lugar de llevar el nombre de
host el fichero log de error se llama mysql.err

Ejemplo del contenido del fichero log de error.


MySql: ready for connections.
Version: '4.1.2-alpha-nt-max' socket: '' port: 3306
040702 7:30:47 Aborted connection 2 to db: 'unconnected' user: 'ODBC'
host: `localhost' (Got an error reading communication packets)
040702 7:58:14 MySql: Normal shutdown

040702 7:58:14 InnoDB: Starting shutdown...


040702 7:58:15 InnoDB: Shutdown completed; log sequence number 0 43634
040702 7:58:15 MySql: Shutdown Complete

MySql: ready for connections.


Version: '4.1.2-alpha-nt-max' socket: '' port: 3306
040702 8:15:43 Aborted connection 1 to db: 'unconnected' user: 'admin'
host: `localhost' (Got an error reading communication packets)
040702 8:15:49 MySql: Normal shutdown

040702 8:15:49 InnoDB: Starting shutdown...


040702 8:15:51 InnoDB: Shutdown completed; log sequence number 0 43634
040702 8:15:51 MySql: Shutdown Complete

MySql: ready for connections.


Version: '4.1.2-alpha-nt-max' socket: '' port: 3306
040702 8:41:29 MySql: Normal shutdown

040702 8:41:30 MySql: Forcing close of thread 3 user: 'root'

040702 8:41:30 InnoDB: Starting shutdown...


040702 8:41:33 InnoDB: Shutdown completed; log sequence number 0 43634
040702 8:41:33 MySql: Shutdown Complete
MySQL Documento de Administración 64

12.1.2 El fichero log general (query log file)

Para saber todo lo que ha ocurrido en la base de datos es necesario activar en el fichero
de configuración (my.ini o my.cnt ) la opción log[=nombre_fichero] si no se le
pasa nombre el nombre del fichero log coincide con el nombre del servidor seguido de
la extensión .log (nombre_host.log)

Este fichero log puede crecer muy rápidamente. Es desde el sistema operativo desde
donde conviene realizar los siguientes pasos cuando el fichero haya alcanzado un
tamaño conveniente o cuando haya pasado un número de días suficiente.
- Parar el servidor MySQL
- Renombrar el fichero log y/o moverlo a una carpeta de respaldo
- Iniciar el servidor. Se crea un fichero log nuevo.

12.1.3 El fichero log de modificaciones (update log )

El fichero update log ha sido sustituido en las versiones actuales de MySQL por el
fichero binary log que viene comentado a continuación

12.1.4 El fichero de log binario (binary log).

Este fichero ha reemplazado el antiguo fichero update log de versiones anteriores de


MySQL.

El binary log recopila toda la información de transacciones efectuadas en la base de


datos (modificaciones , inserciones y borrados ).

El principal uso del binary log es la posibilidad de efectuar una recuperación de la base
de datos ya que contiene toda la información de las modificaciones en la BD.

El binary log también se usa para replicar servidores de datos entre servidores
maestros y servidores esclavos.

Tener activo el servicio de binary log supone una perdida de rendimiento en velocidad
del servidor en torno a un 1%. Sin embargo los beneficios proporcionados por la
posibilidad de recuperar la información ante un posible fallo o caída del servidor
compensan la perdida de rendimiento.

Activación del binary log


Parar la base de datos.
Editar el fichero my.ini o my.cnf y añadir la siguiente línea en la sección
[mysqld] del fichero

#Habilitar el binary log


log-bin
Arrancar la base de datos.
MySQL Documento de Administración 65

A partir de la activación se crean por defecto en el directorio de datos de MySQL el


fichero binary log que tendrá como nombre el nombre del host seguido de –bin junto
con una extensión formada por una secuencia de números. Cada vez que se reinicia el
servidor se genera un nuevo fichero de log con la secuencia numérica incrementada.
También se crea un fichero índice de logs con el mismo nombre que cada uno de los
ficheros binary log y con la extensión .index. Por ejemplo:

26/11/2004 09:27 275 servidorXPASI2-bin.000001


26/11/2004 09:27 56 servidorXPASI2-bin.index
26/11/2004 09:27 170 servidorXPASI2-bin.000002

Para examinar los ficheros binary log se puede utilizar la herramienta mysqlbinlog que
se encuentra en la carpeta /bin de la distribución de MySQL.

Ejemplo de uso de mysqlbinlog :

Se quiere visualizar las modificaciones realizadas en la base de datos y almacenadas en


el fichero de log de nombre servidorXPASI-bin.000001

E:\mysql\bin>mysqlbinlog ..\data\servidorXPASI2-bin.000001

La salida generada por el programa mysqlbinlog es la siguiente:

/*!40019 SET @@session.max_insert_delayed_threads=0*/;


# at 4
#041126 9:17:35 server id 1 end_log_pos 95 Start: binlog v 4, server v 5.0.
1-alpha-nt-log created 041126 9:17:35 at startup
# at 95
#041126 9:18:55 server id 1 end_log_pos 173 Query thread_id=1 exec_tim
e=0 error_code=0
use test;
SET TIMESTAMP=1101457135;
SET @@session.foreign_key_checks=67108864, @@session.sql_auto_is_null=16384, @@s
ession.unique_checks=134217728;
SET @@session.sql_mode=0;
delete from accesslog;
# at 173
#041126 9:19:45 server id 1 end_log_pos 275 Query thread_id=1 exec_tim
e=0 error_code=0
SET TIMESTAMP=1101457185;
delete from telefonos4 where numtel=910201700;

Ejecutar una parte del fichero binary log.

En ocasiones y después de restaurar una copia de seguridad habrá que ejecutar de


nuevo parte de un fichero binary log para dejar la base de datos tal como se encontraba
en el momento de producirse el fallo o el error que motivó el proceso de restauración
de la copia de seguridad. Antes de ejecutar el fichero convendrá analizar si interesa
ejecutar todo o solo una parte. Para ejecutar un fichero binary log a partir de una
determinada posición del fichero hasta otra determinada posición del fichero se
utilizan las opciones –-start-position y –-stop-position. Lo que se hace es que
la salida generada por mysqlbinlog sea la entrada del cliente mysql. Para ello
empleamos el operador “|” desde la línea de comandos como en el siguiente ejemplo:

C:\mysql\bin>mysqlbinlog --start-position=95 --stop-position=173


..\data\ servidorXPASI2-bin.000001 | mysql
MySQL Documento de Administración 66

Eliminar ficheros binary log.

Una forma de eliminar ficheros binary log es usando la sentencia PURGE MASTER
LOGS (o PURGE BINARY LOGS). Se puede hacer de dos formas eliminar por
nombre de fichero o por fecha. Ejemplo de uso por nombre de fichero
Se ejecuta el comando show master logs para obtener una lista de los ficheros binary log
almacenados.

mysql> show master logs;


+---------------------------+
| Log_name |
+---------------------------+
| servidorXPASI2-bin.000001 |
| servidorXPASI2-bin.000002 |
+---------------------------+
2 rows in set (0.00 sec)

Se lanza la sentencia que elimina todos los ficheros log anteriores al fichero log
'servidorXPASI2-bin.000002’

mysql> purge binary logs to 'servidorXPASI2-bin.000002';


Query OK, 0 rows affected (0.03 sec)

Se vuelve a ejecutar el comando show master logs para ver el resultado

mysql> show master logs;


+---------------------------+
| Log_name |
+---------------------------+
| servidorXPASI2-bin.000002 |
+---------------------------+
1 row in set (0.00 sec)

Para eliminar por fecha es muy similar a lo anterior cambiando la sentencia por la
siguiente por ejemplo

PURGE MASTER LOGS BEFORE '2004-11-22 22:46:26';

Nota: Por defecto cualquier modificación en cualquier base de datos queda registradas
en el binary log. A veces puede ser interesante solamente registrar modificaciones en
determinadas bases de datos o ignorar modificación en otras, para ello se utilizan las
opciones de configuración

binlog-do-db=nombre_bd
binlog-ignore-db=nombre_bd

Estas entradas se ponen en el fichero my.ini una vez habilitado el binary log
MySQL Documento de Administración 67

12.2. Ejecutar varios servidores MySQL en la


misma máquina
En ocasiones puede ser que necesitemos ejecutar varios procesos mysqld en la misma
máquina, por ejemplo si queremos testear una nueva release de MySQL y no queremos
detener nuestro servidor de MySQL que está en funcionamiento o por que se quiere
dar a diferentes grupos de usuarios acceso a servidores diferentes de MySQL para que
los administren ellos mismos y no disponemos de más equipos.

12.2.1 Ejecutar varios servidores MySQL en Windows

En Windows tenemos la posibilidad de arrancar los servidores manualmente desde la


línea de comandos o bien instalarlos como servicios de Windows. En este apartado
vamos a comentar solo la primera opción, es decir, arrancando los servidores
manualmente desde la línea de comandos. Normalmente arrancar varios servidores en
un mismo equipo suele ser algo provisional por eso no es necesario instalarlo como un
servicio de Windows. De todas formas cualquier combinación es valida podemos tener
el servidor de MySQL de producción instalado como servicio y arrancar manualmente
la nueva release que queremos testear.

Lo fundamental para que el proceso funcione y los servidores no se interfieran entre si


es que cada servidor arranque leyendo un fichero de configuración distinto (my.ini)
esto se consigue fácilmente si en el arranque manual se ejecutan los procesos de
servidor con la opción --defaults-file apuntando cada proceso servidor a su
propio fichero my.ini.

En el ejemplo que detallamos a continuación vamos a ejecutar dos procesos servidores


uno va a escuchar las peticiones por el puerto 3307 y el por el puerto 3308 (es básico
que los puertos sean distintos). Además necesitamos tener dos directorios de datos
cada uno de ellos con, al menos, su correspondiente base de datos mysql con las tablas
del diccionario de datos. (Se puede copiar una base de datos mysql de una ubicación a
otra simplemente copiando la carpeta mysql que se crea tras el proceso de instalación
del software MySQL bajo la carpeta data). Los directorios de datos van a ser por
ejemplo c:\mysql1\misdatos1 y c:\mysql2\misdatos2 respectivamente. (Es
conveniente insistir en este punto que deben existir al menos las subcarpetas
c:\mysql1\misdatos1\mysql y c:\mysql2\misdatos2\mysql cada una con sus
correspondientes tablas del diccionario de datos)

Se crean los dos ficheros de configuración. Uno de ellos será por ejemplo
c:\mysql1\my1.ini con la siguiente información:

[mysqld]
datadir = c:\mysql1\misdatos1
port = 3307

El segundo lo llamamos c:\mysql2\my2.ini con la siguiente información:


[mysqld]
datadir = c:\mysql2\misdatos2
port = 3308
MySQL Documento de Administración 68

Importante. Para arrancar los servidores necesitamos una consola de comandos para
cada servidor, ya que no vuelve a aparecer el prompt una vez lanzado el proceso.

Abrimos una ventana de comandos y lanzamos el comando:


C:\> C:\mysql\bin\mysqld --defaults-file= c:\mysql1\my1.ini

Abrimos una segunda ventana para al siguiente orden:

C:\> C:\mysql\bin\mysqld-max --defaults-file= c:\mysql2\my2.ini

Para detener los procesos servidor necesitamos abrir una tercera ventana y ejecutar
mysqladmin de la siguiente forma:

C:\> C:\mysql\bin\mysqladmin --port=3307 shutdown


C:\> C:\mysql\bin\mysqladmin --port=3308 shutdown

Para ejecutar el cliente y acceder a las distintas bases de datos tendremos siempre que
tener en cuenta el número de puerto.

Para comprobar que funcionan los dos servidores ejecutamos dos clientes uno
accediendo a cada servidor desde dos ventanas de comandos distintas. Suponemos que
estamos conectando desde el mismo equipo (modo localhost) como administradores
sin password:

C:\> C:\mysql\bin\mysql --port=3307

C:\> C:\mysql\bin\mysql --port=3308

12.2.2 Ejecutar varios servidores MySQL en Linux

La manera más sencilla en Linux (u otro servidor UNIX) es compilar los servidores
con un diferentes puerto TCP , con diferentes ficheros de socket y también con
diferentes directorios base lo que implica que tendrán diferentes directorios de datos.

Para simplificar suponemos que ya tenemos instalado un servidor con la configuración


que viene por defecto en la instalación (puerto 3306, fichero de socket en la dirección
/tmp/mysql.sock).

Para configurar un nuevo servidor usamos el comando configure de esta manera:

shell> ./configure --with-tcp-port=port_number \


--with-unix-socket-path=file_name \
--prefix=/usr/local/mysql-5.0.2

donde port_number y file_name deben corresponder a valores diferentes de los ya


instalados por defecto y la dirección asociada a --prefix no debe ser la misma de la
que tiene el servidor ya instalado..
MySQL Documento de Administración 69

12.3. Replicación
En las primeras versiones de MySQL el proceso de replicación era una tarea de
implantación compleja y que tenía sus dificultades por que el proceso estaba
defectuosamente documentado.
A partir de la versión 4.1 el proceso de replicación se ha simplificado
considerablemente.

La forma más básica de replicación de bases de datos consta de dos servidores un


servidor maestro y un servidor esclavo. El servidor maestro registra todas las
modificaciones de la base de datos en su fichero de log binario o binary log (ver
apartado ….), el servidor esclavo se conecta con el servidor maestro accede al fichero
binary log y ejecuta las sentencias de modificación que en el están registradas en su
base de datos local. De esta manera se consigue que ambas bases de datos (maestro y
esclavo) sean coincidentes y estén sincronizadas.

Replicación Backup Cinta


BD MySQL BD MySQL backup
del Servidor del Servidor
Maestro Esclavo

12.3.1 Ventajas de la replicación

Facilita el concepto de distribución de la información. Permite mantener copias


idénticas de la base de datos en sitios que pueden estar muy alejados geográficamente
y no requieren estar permanentemente conectados.

Permitir el balanceo de carga. La replicación es una excelente manera de implementar


un balanceo de carga efectivo entre los servidores. Teniendo uno o más servidores
esclavos podemos distribuir las peticiones de consulta entre todos ellos evitando la
sobrecarga en un único servidor.

Copias de seguridad y recuperación de la información. Resulta más sencillo implantar


un sistema de copia de seguridad sobre un servidor esclavo que sobre un servidor
maestro con gran demanda de solicitud de información por parte de los clientes.
Además los clientes nunca se ven penalizados por que no es necesario detener el
servicio para generar el proceso de copia.

Aumento de la fiabilidad ante caídas. Un servidor esclavo siempre puede convertirse


en maestro en caso de que el servidor maestro sufra una caída por algún motivo.
MySQL Documento de Administración 70

12.3.2 Implantación del servicio de replicación

En este apartado se pretende explicar el método de implantación de un servicio de


replicación en dos posibles escenarios. En primer lugar se planteará la replicación en
un servidor de base de datos recién instalado y que por lo tanto aun no contiene datos
propios a excepción de la base de datos test y la base de datos mysql. A continuación
se comentará como instalar el servicio de replicación en un servidor que ya ha estado
un tiempo funcionando para que cause el menor perjuicio por interrupciones en los
usuarios.

12.3.2.1 Replicación en un nuevo servidor.

Los pasos necesarios para llevar a cabo el proceso en el servidor maestro y esclavo
(master and slave ) son los siguientes:
1. Crear una cuenta de usuario encargado de la replicación en el maestro.
2. Añadir las modificaciones necesarios en los ficheros de configuración
del maestro y el esclavo (my.ini o my.cnf).
3. Reiniciar el servidor maestro y verificar la creación del fichero de log
binario (binary log)
4. Reiniciar el servidor esclavo y comprobar que la replicación funciona
correctamente.

Paso 1. Creación de la cuenta de usuario en el servidor maestro.

El usuario se debe crear en el servidor maestro y será el encargado de ejecutar el


servicio. El usuario nuevo debe ser creado con los privilegios mínimos para poder
realizar el proceso de replicación conectándose desde el usuario esclavo. Estos
privilegios son REPLICATION SLAVE y REPLICATION CLIENT. Llamamos al
usuario nuevo repl con password repl. La dirección IP del servidor esclavo será por
ejemplo 192.168.1.2 y la del servidor maestro 192.168.1.1.

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO

repl@"192.168.1.0/255.255.255.0" IDENTIFIED BY 'repl';

Query OK, 0 rows affected (0.00 sec)

Después de crear la cuenta verificamos que se ha creado correctamente:


mysql> SHOW GRANTS FOR repl;

+----------------------------------------------------------------------------------+

|Grants for repl@"192.168.1.0/255.255.255.0" |

+----------------------------------------------------------------------------------+

| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'...' IDENTIFIED BY ...|

+-------------------------------------------------------------------------+

Paso 2. Modificación de los ficheros de configuración en el maestro y el esclavo.

Cada servidor debe ser identificado con un entero que le sirve de identificador. Esto es
necesario por las distintas combinaciones de maestros esclavos que pueden darse. En
MySQL Documento de Administración 71

este caso que estamos estudiando se asignará al maestro el identificador 1 y al esclavo


el identificador 2.

Por lo tanto en el fichero my.ini del maestro en la sección [mysqld] se añadirán las dos
líneas siguientes.
log-bin

server-id = 1

La opción log-bin activa el binary log en el maestro (fundamental para que la


replicación tenga lugar).

En le fichero my.ini del esclavo es necesario añadir más información. La


identificación del esclavo, la dirección del maestro, el usuario y password del maestro
encargado de efectuar la replicación y el puerto. Las líneas son por lo tanto las
siguientes:

server-id = 2

master-host = master.example.com

master-user = repl

master-password = c0pyIT!

master-port = 3306

Paso 3. Reiniciar el maestro.

Una vez modificado los ficheros de configuración podemos reiniciar el maestro y


verificar una vez arrancado el servidor que se han activado los ficheros binary log.
Basta con echar un vistazo a la carpeta de datos de MySQL (datadirectory) y ver si
aparecen dos ficheros con la siguiente apariencia:
Nombre-host-bin.000001
Nombre-host-bin.index

Paso 4. Reiniciar el esclavo.

Una vez reiniciado el maestro basta con reiniciar el servidor esclavo para que la
replicación entre en funcionamiento. Para comprobar que el servicio de replicación
está en marcha conviene echar un vistazo al fichero log de error (nombre-host.err)
que debe tener al final la siguiente información:

021103 17:58:10 Slave I/O thread: connected to master


'[email protected]:3306',

replication started in log 'nombre-host-bin.000001' at position 4

También podemos verificar el correcto funcionamiento de la replicación haciendo


cualquier modificación en la base de datos del servidor maestro y ver como queda
replicada en el servidor esclavo.
MySQL Documento de Administración 72

12.3.2.2 Replicación en un servidor existente.

Este es el caso más frecuente y el que añade un poco más de trabajo que el caso
anterior sobre servidores nuevos por que requiere hacer una copia completa de los
datos que se quieran mantener replicados del servidor maestro en el servidor esclavo
en el momento justo antes de poner en marcha la replicación (si la copia se realiza on-
line se denomina snapshot).

12.3.3 Otros datos útiles en el proceso de replicación.

En el servidor esclavo podemos parar y arrancar el proceso de replicación sin


necesidad de reiniciar el servidor de base de datos. Basta con usar estas sentencias;

mysql> stop slave; (para parar el proceso de replicación).


mysql> start slave; ( para reiniciarlo).

La siguiente sentencia permite ver desde el esclavo el estado del proceso de


replicación (la opción \G permite una línea por columna y facilita la visualización en
pantalla)

mysql> SHOW SLAVE STATUS \G

*************************** 1. row ***************************


Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.1
Master_User: repl
Master_Port: 3306
Connect_retry: 60
Master_Log_File: nombre-host-master-log.004
Read_Master_Log_Pos: 635904807
Relay_Log_File: nombre-host-slave-log.004
Relay_Log_Pos: 846096118
Relay_Master_Log_File: binary-log.004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_do_db:
Replicate_ignore_db:
Last_errno: 0
Last_error:
Skip_counter: 0
Exec_master_log_pos: 635904807
Relay_log_space: 846096122
1 row in set (0.00 sec)

El parámetro Slave_IO_State permite ver rápidamente si el proceso de replicación


esta en marcha y funcionado. En el caso de que este parado e servicio de replicación la
salida SHOW SLAVE STATUS \G queda
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.1.1
Master_User: repl
Master_Port: 3306
etc.,etc.…
MySQL Documento de Administración 73

12.3.4 Posibles arquitecturas de replicación.

Una vez visto que establecer un servicio de replicación en MySQL es relativamente


sencillo, se pueden combinar los servicios de replicación en múltiples arquitecturas
para con ello dar solución a muy diversos tipos de problemas o mejoras en el
rendimiento que se puedan plantear.
Es conveniente que todas las arquitecturas de replicación sigan las siguientes reglas
básicas:
1. Cada esclavo debe tener un identificador único.
2. Un esclavo solo debe tener un maestro.
3. Un maestro puede tener varios esclavos.
4. Esclavos pueden ser a su vez maestros de otros esclavos.

Tipo 1. Un maestro y varios esclavos.

Esta situación es típica de una BD que tiene pocas sentencias de modificación pero si
muchas sentencias de consulta. El trabajo de servir las sentencias de consulta se puede
distribuir entre los esclavos estableciendo un balanceo de carga. De hecho los
servidores esclavos pueden estar ejecutando a su vez otros servicios como Apache.

Tipo 2. Un esclavo con dos maestros.

En ocasiones puede ser interesante tener un solo host que haga de esclavo
simultáneamente de varios maestros cuyos datos no guarden relación entre si. La
principal ventaja de este tipo de arquitectura es el ahorro de costes por que se utiliza
MySQL Documento de Administración 74

una sola máquina para respaldo de varios servidores . Esta arquitectura aparentemente
viola una de las reglas básicas comentadas anteriormente que dice que un servidor
esclavo solo debe tener a lo sumo un maestro asociado. Para evitar esta violación de la
regla lo que se hace es crear sobre la misma máquina dos instancias de MySQL
distintas trabajando sobre distintos puertos TCP. Cada instancia (servicio) de MySQL
es responsable de replicar un maestro distinto. No existe ningún impedimento para que
un único host pueda ejecutar simultáneamente varias instancias de MySQL siempre
que tenga suficiente espacio en disco y potencia de CPU.

Tipo 3. Configuración dual con dos maestros.

Esta configuración es útil cuando, por ejemplo, existe una organización dividida en
dos partes separadas geográficamente por una gran distancia (conexión WAN) y
ambas partes de la organización necesitan acceso de lectura/escritura a los mismos
datos. Con este tipo de arquitectura ninguna de las partes de la organización se quedan
sin acceso a los datos cuando haya problemas en la línea WAN de conexión, y una vez
reestablecida, los equipos se ponen al corrie nte de sus respectivos cambios entre ellos

Tipo 4. Anillo de maestros.


MySQL Documento de Administración 75

Realmente el caso anterior (configuración dual con dos maestros) es un caso particular
de la arquitectura de anillo de maestros donde hay al menos tres o más equipos
maestros formando un anillo en el que cada equipo es esclavo de uno de sus vecinos y
maestro del otro. La ventaja de esta configuración es la misma que en el caso anterior
de configuración dual de cercanía geográfica de los datos que evita las incomodidades
de la pérdida de conexión WAN. La desventaja es que estas arquitecturas son frágiles.
Si un equipo falla por alguna razón el anillo se rompe y el servicio no queda
restablecido hasta que todos los nodos no estén operativos.

Tipo 5. Piramidal

Otro tipo de organización puede requerir otro tipo de arquitectura. Por ejemplo, una
gran base de datos centralizada que se replica a cada una de las pequeñas oficinas
geográficamente dispersas donde se efectúan consultas de datos mientras que la carga
transaccional recae en la base de datos de la oficina central. En este caso lo que parece
más manejable es un solo equipo maestro inicial que se va replicando sucesivamente
en forma piramidal a los distintos equipos en cada una de las sedes de la organización.

También podría gustarte