Mysql AulaMentor PDF
Mysql AulaMentor PDF
Mysql AulaMentor PDF
Gestión de datos
PARTE I
LENGUAJE SQL. GESTION DE DATOS
Página: 1
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Página: 2
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Paulina Barthelemy
1 – Bases de datos
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.
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.
Además, la información contenida en una base de datos cumple una serie de requisitos o
características:
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.
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.
• 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.
Página: 4
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Página: 5
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
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
Y también, una relación pertenece a representa la relación entre las entidades EMPLEADO Y
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
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,...
Página: 7
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Ejemplos de tablas:
Tabla DEPARTAMENTOS:
Tabla de EMPLEADOS:
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
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.
• 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.
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
TABLA CLIENTES
cliente_no CLAVE PRIMARIA
vendedor_no CLAVE AJENA QUE REFERENCIA emp_no DE 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
El SGBD velará porque todas las operaciones que se realicen respeten estas restricciones
manteniendo así la integridad de la información (integridad referencial)
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.
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
• Los nombres de objetos (tablas, columnas, etcétera) aparecen en el formato TipoTítulo (las
iniciales de las palabras en mayúsculas)
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.
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.
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
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
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.
Página: 15
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
3 - Datos
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.
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
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
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:
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
+ Suma
- Resta
* Multiplicación
/ División
Div División entera ( parte entera de la división, sin decimales)
= Igual
!= Distinto
<> Distinto
< Menor
<= Menor o igual
> Mayor
>= Mayor o igual
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:
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:
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'.
+--------+---------+----------+------------+----------+---------+
| 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)
! 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
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.
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:
+----------+---------+----------+
| 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:
+----------+---------+------------+
| 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
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)
+----------+---------+----------+--------+
| 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)
Página: 23
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
2º +, - Suma, resta.
5º AND Conjunció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.
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
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.
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.
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
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)
Página: 28
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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
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
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:
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):
Página: 31
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
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.
• 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
Página: 33
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Paulina Barthelemy
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
Página: 35
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
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
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
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:
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.
Las restricciones solo se pueden definir de esta forma si afectan a una sola columna, la que estamos
definiendo es ese momento.
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.
Página: 38
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
b) NOT NULL. La columna teléfono es obligatoria en la tabla socios, nunca irá sin información.
c) DEAFAULT. En ausencia de valor el campo fecha _ alta tomará el valor de 1 de enero de 2000.
Página: 39
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
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.
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
a)PRIMARY KEY. El numero de socio será la clave primaria en la tabla socios. Será
obligatoriamente no nulo y único.
b) UNIQUE. El campo apellido es único. Tendrá valores diferentes en cada fila o el valor nulo
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)
Página: 41
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
d) FOREIGN KEY. El número de socio en una tabla prestamos será clave ajena referenciando a la
columna correspondiente de la tabla socios.
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:
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.
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.
Vamos a crear la tabla socios y prestamos con el formato completo. Algunas CONSTRAINTS
las creamos a nivle de columna y otras de tabla:
Página: 43
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Página: 44
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
Página: 45
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
f) RENOMBRAR LA TABLA
RENAME [TO] NombreTablaNuevo
Página: 46
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Página: 47
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
2 - Borraremos una tabla empleados7, que no existe, con la cláusula IF EXISTS y vemos
que no nos da error.
Página: 48
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Notación: se pueden renombrar varias tablas en una sentencia por eso van entre
corchetes las siguientes tablas a renombrar.
Página: 49
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
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.
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).
Página: 51
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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)
7 - Inserción de un socio con socio_no=1004, con una instrucción INSERT sin lista de columnas:
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)
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:
3 - Inserción en la tabla socios de una fila con valores duplicados en la columna apellidos:
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> 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
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.
2 – Inserción de toda la fila ( en este caso debe ponerse NULL en la columna correspondiente)
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.
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.
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'.
2 - Supongamos que se desea cambiar el teléfono del socio de número 1000 y el nuevo teléfono es
918455431
También podíamos haber modificado las dos columnas con una sola sentencia:
Las actualizaciones anteriores afectan a una única fila pero podemos escribir comandos de
actualización que afecten a varias filas:
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.
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.
Para eliminar o suprimir filas de una tabla utilizaremos la sentencia DELETE. Su formato genérico es el
siguiente:
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
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
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
Página: 59
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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 .
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.
Página: 61
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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.
Página: 62
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
Página: 63
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
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> SELECT *
-> FROM inventario;
+-----+----------------+
| num | descripcion |
+-----+----------------+
| 1 | ARMARIO BLANCO |
| 2 | MESA MADERA |
| 3 | ORDENADOR |
| 4 | SILLA GIRATORIA|
+-----+----------------+
4 rows in set (0.00 sec)
Página: 64
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
mysql> ROLLBACK;
Query OK, 0 rows affected (0.09 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.
Página: 65
Lenguaje SQL con MySQL Parte I - Lenguaje Sql. Gestión de datos
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
Página: 66
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
PARTE II
LENGUAJE SQL. CONSULTA DE DATOS
Página: 1
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Página: 2
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Paulina Barthelemy
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.
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.
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.
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.
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.
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)
+--------+
| 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
+------------+--------+
| oficio | dep_no |
+------------+--------+
| VENDEDOR | 30 |
| EMPLEADO | 10 |
| DIRECTOR | 30 |
| DIRECTOR | 10 |
| PRESIDENTE | 10 |
| ANALISTA | 20 |
| EMPLEADO | 20 |
+------------+--------+
7 rows in set (0.00 sec)
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
+----------+------------+
| 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.
+---------------+
| 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)
+---------------+
| 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)
+-------------+----------+--------------+
| 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
Notación: la cláusula WHERE es opcional, por eso aparece toda ella entre corchetes
+-------------+----------+--------------+
| 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.
Página: 9
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+-------------+----------+--------------+
| 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.
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.
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
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
Vamos a ver algún ejemplo de cada uno de estos tipos de funciones dentro de las expresiones y las
condiciones.
+----------+-----------------------+
| 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
1 - Visualizar los tres primeros caracteres de los apellidos de los empleados seguidos de un punto
+-----------+
| 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 ‘*’
+--------------------------+
| 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
+------------+----------------------+
| 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>.
+----------+----------------------------+
| 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)
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)
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>
Página: 15
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
1 - Visualizar para cada empleado el valor que sea mayor entre su salario y su comisión
+----------+---------+----------+----------------------------+
| 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
+----------+---------+----------+
| 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
+--------------------+
| VERSION() |
+--------------------+
| 5.1.0-alpha-nt-max |
+--------------------+
1 row in set (0.00 sec)
+----------------+
| 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.
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
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.
+--------+----------+---------+
| 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)
3. Obtener los datos de los empleados clasificados por oficios y en orden descendente de salarios.
Página: 19
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Página: 20
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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.
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)
Página: 22
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Página: 23
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Paulina Barthelemy
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.
[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.
Página: 24
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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.
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.
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
STDDEV(expr) Calcula la desviación típica para los valores de la expresión de columna que le
acompaña.
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.
Página: 26
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+--------------+
| SUM(salario) |
+--------------+
| 23100.62 |
+--------------+
1 row in set (0.00 sec)
+------------------+------------------+------------+
| Salario mas alto | Salario mas bajo | Diferencia |
+------------------+------------------+------------+
| 6000.00 | 1350.50 | 4649.50 |
+------------------+------------------+------------+
1 row in set (0.00 sec)
+------------+
| Fecha alta |
+------------+
| 1983-03-24 |
+------------+
1 row in set (0.00 sec)
+---------------+
| 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:
+-------------------------------+
| SUM(comision)/COUNT(comision) |
+-------------------------------+
| 666.6667 |
+-------------------------------+
1 row in set (0.00 sec)
+---------------+
| Salario medio |
+---------------+
| 3350.000000 |
+---------------+
1 row in set (0.00 sec)
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)
+------------+-----------------+
| 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.
+----------+----------+
| 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.
Página: 29
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+----------+----------+
| 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
+--------+----------+
| 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
Página: 31
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
TEMA 7. SUBCONSULTAS
Paulina Barthelemy
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:
+---------------+
| Salario Medio |
+---------------+
| 2566.735569 |
+---------------+
1 row 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.
Página: 32
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+-------------+----------+---------+
| Nº Empleado | apellido | salario |
+-------------+----------+---------+
| 30 | GARRIDO | 3850.12 |
| 10 | REY | 6000.00 |
| 20 | GIL | 3350.00 |
+-------------+----------+---------+
3 rows in set (0.00 sec)
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.
Página: 33
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+---------+
| 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.
+--------+----------+----------+--------+
| 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
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á.
Página: 35
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+-------------+----------+----------+
| Nº Empleado | apellido | oficio |
+-------------+----------+----------+
| 7698 | GARRIDO | DIRECTOR |
| 7782 | MARTINEZ | DIRECTOR |
+-------------+----------+----------+
2 rows in set (0.00 sec)
2. Obtener información de los empleados que ganan más que cualquier empleado del departamento 30.
+-------------+----------+---------+-----------------+
| Nº Empleado | apellido | salario | Nº Departamento |
+-------------+----------+---------+-----------------+
| 7839 | REY | 6000.00 | 10 |
+-------------+----------+---------+-----------------+
1 row in set (0.00 sec)
Página: 36
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
4. Visualizar la suma de los salarios para cada oficio de los empleados del departamento VENTAS.
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.
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).
Página: 37
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+--------+----------+--------+
| 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.
2. Listar los nombres de los departamentos que tengan algún empleado con fecha de alta anterior a 1982.
+----------------+--------------+
| 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.
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.
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.
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..
+-----------------+---------------+
| 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
+-----------------+---------------+
| 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.
+-----------------+--------------+
| Nº Departamento | Departamento |
+-----------------+--------------+
| 30 | VENTAS |
+-----------------+--------------+
1 row in set (0.00 sec)
+-----------------+----------+---------+
| Nº Departamento | apellido | salario |
+-----------------+----------+---------+
| 30 | GARRIDO | 3850.12 |
| 10 | REY | 6000.00 |
+-----------------+----------+---------+
2 rows in set (0.00 sec)
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)
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.
+--------+--------------+
| 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.
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.
+-----------+
| localidad |
+-----------+
| MADRID |
+-----------+
1 row in set (0.00 sec)
Página: 42
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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.
Página: 43
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+--------+----------+
| 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
+--------+----------+
| emp_no | apellido |
+--------+----------+
| 7876 | GIL |
+--------+----------+
1 row in set (0.00 sec)
4 - Visualizar los empleados que tienen el mismo jefe y departamento que ALONSO excluido el
mismo.
+--------+----------+----------+--------+
| 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
+-----------------+---------------+
| 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.
+--------+---------------------------------+
| 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
Página: 46
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
+--------------+-------------------+
| 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.
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.
2 - Visualizar los datos, número, nombre y localidad, del departamento donde trabaja el empleado
más antiguo con el mismo oficio que GIL
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.
Por ejemplo:
Visualizar los empleados que ganan más salario que la media de la empresa
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.
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.
+-----------------+------------+---------+
| Nº Departamento | oficio | salario |
+-----------------+------------+---------+
| 30 | DIRECTOR | 3850.12 |
| 10 | PRESIDENTE | 6000.00 |
| 20 | ANALISTA | 3350.00 |
+-----------------+------------+---------+
3 rows in set (0.00 sec)
+------------+--------+----------+------------+
| 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)
+----------+--------+----------+---------+
Página: 50
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Página: 51
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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.
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
+-------------+----------+---------------+-----------+
| 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
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:
+-------------+----------+---------------+-----------+
| 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.
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.
Página: 55
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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.
+-------------+----------+---------------+-----------+
| 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
• 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
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.
+-----------------+---------------+
| 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.
+-------------+----------+---------------+-----------+
| 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
+------------+----------+
| 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.
+------------+----------+
| 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
+------------+----------+
| 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
En este caso, como ambas tablas se llaman igual, es necesario obligatoriamente un alias para
diferenciar las columnas de cada tabla.
+------------+-----------------+------------+-----------------+
| 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
+------------+----------+----------+-------------+-----------------+
| 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
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).
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
Página: 62
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Por ejemplo si queremos visualizar los datos de los departamentos y de sus empleados, visualizando
también los departamentos que no tengan empleados.
+---------------+-----------+------------+----------+
| 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
+---------------+-----------+-------------+----------+
| Departamento | localidad | Nº empleado | apellido |
+---------------+-----------+-------------+----------+
| CONTABILIDAD | BARCELONA | 7521 | LOPEZ |
Página: 63
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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.
+------------+----------+---------------+-----------+
| 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.
+---------------+-----------+---------------+
| 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) .
+----------+-----------------+
| 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.
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.
+----------+----------+
| 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.
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
Página: 68
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Paulina Barthelemy
Notación: las definiciones de las columnas son opcionales, por lo que están entre corchetes.
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.
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.
Página: 70
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
Notación: la lista de columnas en las que insertamos va es opcional, por lo que va entre
corchetes.
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> 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.
Página: 71
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
mysql> SELECT *
-> FROM n2dept;
+--------+---------------+
| DEP_NO | NOMBRE |
+--------+---------------+
| 10 | CONTABILIDAD |
| 20 | INVESTIGACION |
| 40 | PRODUCCION |
+--------+---------------+
3 rows in set (0.00 sec)
Por ejemplo, supongamos que se desea elevar en 500 Euros. el salario de todos los empleados cuyo
departamento no esté en MADRID
Página: 72
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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> 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.
Página: 73
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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:
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.
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;
Para ello crearemos vistas y permitiremos a los usuarios tener acceso a las vistas sin tenerlo de la tabla
completa.
Página: 75
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
El siguiente ejemplo crea la vista emple_dep30 para la gestión de los empleados del departamento 30
mencionada en el apartado anterior.
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.
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:
Por ejemplo:
+--------+----------+-----------+----------+------------+--------+
| 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)
+----------+----------+
| 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:
+-------+----------+---------+---------+------------+---------+--------+--------+
|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)
Página: 77
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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.
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> 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:
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.
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
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
+--------+--------------+
| 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):
Página: 80
Lenguaje SQL con MySQL Parte II. Lenguaje Sql. Consulta de datos
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.
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> 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
10.2. Instalación
11.2. Configuración
11.4. Í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
12.3. Replicación
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:
10.2. Instalación
10.2.1 Instalación de MySQL versión 4.1 para entorno Windows con
soporte InnoDB.
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
4. Ventana que avisa que ya esta preparado para instalar el producto. Pulsamos
Install
MySQL Documento de Administración 8
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
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
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
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
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
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.
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.
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
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.
shell> mysql
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
C:\MySQL\bin>mysql
C:\MySQL410\bin>mysql -uroot -p
Enter password: *********
C:\MySQL410\bin>mysql –h192.168.3.33
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.
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
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
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.
Volvemos a repetir la select sobre la tabla usuarios para ver como ha cambiado después
de ejecutar las sentencias anteriores.
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
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>
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.
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.
El mensaje anterior indica que la base de datos no ha sido creada, por lo tanto
necesitamos crearla.
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:
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>
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>
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
Para ver un listado con las tablas dentro de una determinada base de datos podemos
lanzar la sentencia:
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.
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.
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 :
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
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.
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
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
Algunas cuantas razones para usar scripts en lugar de trabajar en modo interactivo:
• 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 \.)
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).
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 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
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 &
Tema 11.
Administración de MySQL (I)
Javier Robles Cascallar
| 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
• 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.
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
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
C:\mysql\bin>myisampack ..\data\test\telefonos2
Compressing ..\data\test\telefonos2.MYD: (10000 records)
- Calculating statistics
- Compressing file
66.69%
C:\mysql\bin>myisamchk -u ..\data\test\telefonos2
- recovering (with keycache) MyISAM-table
'..\data\test\telefonos2'
Data records: 10000
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
Después de crear las tablas podemos seleccionar todas las filas de ambas tablas a partir
de la tabla total
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
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
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.
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
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.
InnoDB realmente por si solo es un motor de bases de datos muy completo que ha sido
embebido dentro de MySQL.
• Control de transacciones.
• 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
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
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:
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 -
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.
Las opciones introducidas a través de la línea de comandos deben seguir las siguientes
reglas.
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
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).
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.
myisamchk, mysqlcheck,
myisampack, mysqld_safe,
mysql, mysqldump,
mysql.server, mysqld,
mysqladmin, mysqlhotcopy,
mysqlbinlog, mysqlimport,
mysqlcc, mysqlshow.
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
[WinMySQLadmin]
Server=C:/mysql/bin/mysqld-max-nt.exe
user=admin
password=admin
MySQL Documento de Administración 44
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:
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.
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.
• Nivel de privilegio.
Los privilegios pueden aplicarse a cuatro niveles
• Usuario@Host.
• 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.
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)
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.
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
Para poder eliminar completamente un usuario este ha tenido que ser revocado
previamente de todos sus privilegios.
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.
• de clave primaria
• únicos
• de texto completo
• ordinarios
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.
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).
De todas las formas se pide el nombre del índice, sin embargo con la sentencia CREATE
INDEX el nombre es obligatorio.
Se puede crear un índice en la columna apellidos con una sentencia ALTER TABLE:
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:
- 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:
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
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)
);
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:
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:
11.5.1 mysqldump
--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.
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
--
-- Current Database: `test`
--
USE `test`;
--
-- Table structure for table `accesslog`
--
--
-- etc,etc,etc…
--
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.
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.
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
Para restaurar una copia hecha con mysqlhotcopy simplemente tenemos que restaurar
los ficheros a la carpeta del directorio de datos correspondiente de MySQL.
Fichero personal.txt
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.
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.
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));
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
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
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.
El fichero update log ha sido sustituido en las versiones actuales de MySQL por el
fichero binary log que viene comentado a continuación
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.
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.
E:\mysql\bin>mysqlbinlog ..\data\servidorXPASI2-bin.000001
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.
Se lanza la sentencia que elimina todos los ficheros log anteriores al fichero log
'servidorXPASI2-bin.000002’
Para eliminar por fecha es muy similar a lo anterior cambiando la sentencia por la
siguiente por ejemplo
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
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
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.
Para detener los procesos servidor necesitamos abrir una tercera ventana y ejecutar
mysqladmin de la siguiente forma:
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:
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.
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.
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.
+----------------------------------------------------------------------------------+
+----------------------------------------------------------------------------------+
+-------------------------------------------------------------------------+
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
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
server-id = 2
master-host = master.example.com
master-user = repl
master-password = c0pyIT!
master-port = 3306
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:
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).
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.
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.
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
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.