Administración de Bases de Datos Ernesto Martín Pintado
1- Concesionario motocicletas (FullGas) Se desea diseñar una base de datos para almacenar la información de un concesionario dedicado exclusivamente a la venta de motocicletas teniendo en cuenta los siguientes aspectos. La empresa tiene una serie de motocicletas para su venta por lo que se almacenará su matrícula, su cilindrada, caballos, número de bastidor y el precio de cada motocicleta. Además la empresa necesitará almacenar los datos de los empleados, que serán, nombre, apellidos, dirección, teléfono y un código de empleado. Los empleados pueden ser de tres tipos, vendedores, mecánicos y servicio de mantenimiento. La empresa contará con una serie de proveedores de los cuales se almacenará el nombre del proveedor, un teléfono de contacto y su NIF. Los datos que nos interesa conocer de cada cliente serán, nombre, apellidos, DNI, teléfono, edad y su dirección. Un cliente puede comprar tantas motocicletas como desee, pero una única motocicleta solo podrá ser comprada por un cliente. Los clientes podrán hacer reserva de una motocicleta en particular, por lo que deberá dejar una fianza y se apuntará la fecha en la que se hizo la reserva. 2- Diagrama 1
3- Paso a tablas EMPLEADOS (CODIGO_EMPLEADOS, NOMBRE, APELLIDOS, DIRECCION, TELEFONO) CLIENTES (DNI, NOMBRE, APELLIDOS, DIRECCIÓN, EDAD, TELEFONO, MATRICULA_MOTO) PROVEEDORES (NIF, TELEFONO, NOMBRE) MOTOCICLETAS (ID, MATRICULA, CILINDRADA, CABALLOS, NUM_BASTIDOR, PRECIO, MODELO, TIPO) RESERVA (ID, FIANZA, FECHA, ID_MOTO, DNI_CLIENTES) VENDEN (ID, DNI_CLIENTE, ID_MOTO, CODIGO_EMPLEADO, FECHA) COMPRAN (ID, NIF_PROVEEDORES, ID_MOTO, CODIGO_EMPLEADO) USUARIOS (ROL, NOMBRE, EMAIL, CONTRASENA) 2
4- Insertar los datos INSERT INTO EMPLEADOS VALUES (001, 'GEMA', BARBA TENA', 'C/CUEVAS', 500000001), (002, 'PEDRO', 'HERNANDEZ PINES', 'C/MEDIODIA', 500000002), (003, 'DANIEL', 'RODRIGUEZ CAMARA', 'C/BODEGA', 500000003), (004, 'ALBERTO', 'MARTINEZ CARO', 'C/F C PERALTA', 500000004), (005, 'FRANCISCO', 'BECKER GARCIA', 'C/MONTE', 500000005), (006, 'ESPERANZA', 'ANGULO PEREZ', 'C/BUENSUCESO', 500000006), (007, 'VERONICA', 'LARA MORENO', 'C/CONVENTO', 500000007), (008, 'JORGE', 'SOLANILLA GARCIA', 'C/MEMBRILLA', 500000008); INSERT INTO CLIENTES VALUES ('7000001A', 'DANIEL', 'PEDROSA', 'C/AMERICA', 28, 902303030, '1234A'), ('7000001B', 'VALENTINO', 'ROSSI', 'C/TISTAS', 35, 902303040, '1234B'), ('7000001C', 'JORGE', 'LORENZO', 'C/TENCIA', 25, 902303050, '1234C'), ('7000001D', 'CASEY', 'STONER', 'C/TIRO', 27, 902303060, '1234D'), ('7000001E', 'MARC', 'MARQUEZ', 'C/ALEGRIA', 23, 902303070, '1234E'), ('7000001F', 'ANDREA', 'DOVICIOSO', 'C/CARSAN', 28, 902303080, '1234F'), ('7000001G', 'MAVERICK', 'VIÑALES', 'C/LUZ', 20, 902303090, '1234G'), ('7000001H', 'CARL', 'CRUTCHLOW', 'C/SINO', 36, 902304000, '1234H'), ('7000001I', 'ANDREA', 'IANNONE', 'C/KAZE', 22, 902304010, '1234I'); INSERT INTO PROVEEDORES VALUES (987654, 905000001, 'MARQUEMOTOR'), 3
(987653, 905000002, 'MOTOVENTURA'), (987652, 905000003, 'BERNARDO'); INSERT INTO MOTOCICLETAS VALUES (1,'1234A',675, 95, ' ', '7.675 EUR', 'TRIUMPH STREET TRIPLE','NAKED'), (2,'1234B',806, 96, ' ', '7.399 EUR', 'KAWASAKI Z800','NAKED'), (3,'1234C',821, 112, ' ', '11.390 EUR', 'DUCATI MONSTER','NAKED'), (4,'1234D',124, 15, ' ', '14.433 EUR', 'HONDA CBR 500','DEPORTIVA'), (5,'1234E',124, 14.5, ' ', '3.499 EUR', 'KAWASAKI CROSS','MOTOCROSS'), (6,'1234G',49, 8, ' ', '2.819 EUR', 'APRILIA SR','SCOOTER'), (7,'1234H',49, 8.3, ' ', '2.769 EUR', 'GILERA RUNNER','SCOOTER'), (8,'1234I',49, 8.5, ' ', '2.699 EUR', 'YAMAHA AEROX','SCOOTER'); INSERT INTO RESERVA (FIANZA, FECHA, ID_MOTOCICLETAS, DNI_CLIENTES) VALUES (2000,'2017-1-21',1,'7000001A'), (2000,'2017-1-22',2,'7000001B'), (3000,'2017-1-22',3,'7000001C'), (1000,'2017-1-23',4,'7000001D'), (1000,'2017-1-21',5,'7000001E'), (1000,'2017-1-23',6,'7000001F'), (800,'2017-1-21',7,'7000001G'), (800,'2017-1-24',8,'7000001H'), (800,'2017-1-21',9,'7000001I'); INSERT INTO VENDEN VALUES ('7000001A', 1, 001), ('7000001B', 2, 002), 4
('7000001C', 3, 003), ('7000001D', 4, 004), ('7000001E', 5, 005), ('7000001F', 6, 006), ('7000001G', 7, 007), ('7000001H', 8, 008); INSERT INTO COMPRAN VALUES (987654, 1, 001), (987654, 2, 002), (987654, 3, 003), (987653, 4, 004), (987653, 5, 005), (987653, 6, 006), (987652, 7, 007), (987652, 8, 008); INSERT INTO USUARIOS VALUES (1, ernesto, 'ernesto@gmail.com', MD5(clave) ), (0, diana, 'diana@gmail.com', MD5(clave) ), (0, miguel, 'miguel@mail.com', MD5(clave) ); 5
5- Consultas multitabla --- DNI y fianza del cliente con la fianza de compra más alta mysql> select r.fianza, c.dni from clientes c join reserva r on r.dni_clientes=c.dni order by r.fianza desc limit 1; +--------+----------+ fianza dni +--------+----------+ 3000 7000001C +--------+----------+ 1 row in set (0.00 sec) --- DNI y fianza de los 3 clientes con la fianza más baja mysql> select r.fianza, c.dni from clientes c join reserva r on r.dni_clientes=c.dni order by r.fianza asc limit 3; +--------+----------+ fianza dni +--------+----------+ 800 7000001G 800 7000001H 800 7000001I +--------+----------+ 3 rows in set (0.00 sec) 6
--- Nombre de los clientes, modelo de moto y cilindrada mysql> select c.nombre, m.modelo, m.cilindrada from motocicletas m join clientes c where m.matricula=c.matricula_moto; +-----------+---------------------+------------+ nombre modelo cilindrada +-----------+---------------------+------------+ DANIEL TRIUMPH STREET TRIP 675 VALENTINO KAWASAKI Z800 806 JORGE DUCATI MONSTER 821 CASEY KTM RC 124 MARC RIEJU RS3 124 ANDREA HONDA CBR 124 MAVERICK APRILIA SR 49 CARL GILERA RUNNER 49 ANDREA YAMAHA AEROX 49 +-----------+---------------------+------------+ 9 rows in set (0.00 sec) --- Nif de proveedor, modelo de moto y precio de la moto con cilindrada 49cc select c.nif_proveedores, m.modelo, m.precio from compran c join motocicletas m on c.matricula_motocicletas=m.matricula where m.cilindrada=49; +-----------------+---------------+--------+ nif_proveedores modelo precio +-----------------+---------------+--------+ 987652 APRILIA SR 2819 987652 GILERA RUNNER 2769 +-----------------+---------------+--------+ 2 rows in set (0.00 sec) 7
--- Precio medio de las motocicletas mysql> select round(avg(precio),4) from motocicletas; +----------------------+ round(avg(precio),4) +----------------------+ 5186.8889 +----------------------+ 1 row in set (0.02 sec) --- Código de empleados y nombre que no han vendido nunca mysql>select v.codigo_empleados, e.nombre from venden v left join empleados e where v.matricula_motocicleta is null; +------------------+--------+-----------------------+ CODIGO_EMPLEADOS NOMBRE MATRICULA_MOTOCICLETA +------------------+--------+-----------------------+ 9 ALVARO NULL +------------------+--------+-----------------------+ 3 rows in set (0.00 sec) --- Edad media de los clientes mysql> select avg(edad) from clientes; +-----------+ avg(edad) +-----------+ 27.1111 +-----------+ 1 row in set (0.00 sec) 8
--- Nombre, apellidos y modelo de moto de los clientes select c.nombre, c.apellidos, m.modelo from clientes c join motocicletas m on c.matricula_moto=m.matricula; +-----------+-----------+---------------------+ nombre apellidos modelo +-----------+-----------+---------------------+ DANIEL PEDROSA TRIUMPH STREET TRIP VALENTINO ROSSI KAWASAKI Z800 JORGE LORENZO DUCATI MONSTER CASEY STONER KTM RC MARC MARQUEZ RIEJU RS3 ANDREA DOVICIOSO HONDA CBR MAVERICK VIÑALES APRILIA SR CARL CRUTCHLOW GILERA RUNNER ANDREA IANNONE YAMAHA AEROX +-----------+-----------+---------------------+ 9 rows in set (0.00 sec) --- Los 5 clientes que mas dinero han gastado en una moto select c.nombre, c.apellidos, m.modelo, m.precio from clientes c join motocicletas m on c.matricula_moto=m.matricula group by modelo order by m.precio desc limit 5; +-----------+-----------+---------------------+--------+ nombre apellidos modelo precio +-----------+-----------+---------------------+--------+ JORGE LORENZO DUCATI MONSTER 11390 DANIEL PEDROSA TRIUMPH STREET TRIP 7675 VALENTINO ROSSI KAWASAKI Z800 7399 CASEY STONER KTM RC 4433 MARC MARQUEZ RIEJU RS3 3999 9
+-----------+-----------+---------------------+--------+ 5 rows in set (0.00 sec) 6- Subconsultas y JOIN --- Nif de proveedor, modelo de moto y precio de la moto con cilindrada 124cc --SUBC-- select modelo, precio, (select(select nif_proveedores from proveedores where nif=nif_proveedores) from compran where matricula_motocicletas=matricula) as "nif" from motocicletas where cilindrada="124"; +-----------+--------+--------+ modelo precio nif +-----------+--------+--------+ KTM RC 4433 987653 RIEJU RS3 3999 987653 HONDA CBR 3499 987653 +-----------+--------+--------+ 3 rows in set (0.00 sec) --- Apellido de los clientes, modelo de moto y cilindrada select modelo, cilindrada, (select apellidos from clientes where matricula=matricula_moto) as "Piloto" from motocicletas; 10
+---------------------+------------+-----------+ modelo cilindrada Piloto +---------------------+------------+-----------+ TRIUMPH STREET TRIP 675 PEDROSA KAWASAKI Z800 806 ROSSI DUCATI MONSTER 821 LORENZO KTM RC 124 STONER RIEJU RS3 124 MARQUEZ HONDA CBR 124 DOVICIOSO APRILIA SR 49 VIÑALES GILERA RUNNER 49 CRUTCHLOW YAMAHA AEROX 49 IANNONE +---------------------+------------+-----------+ 9 rows in set (0.00 sec) --- Los 5 clientes que más han gastado en una moto y su precio select precio, (select apellidos from clientes where matricula_moto=matricula) as "piloto" from motocicletas order by precio desc limit 5; +--------+---------+ precio piloto +--------+---------+ 11390 LORENZO 7675 PEDROSA 7399 ROSSI 4433 STONER 3999 MARQUEZ +--------+---------+ 5 rows in set (0.00 sec) 11
--- Fecha, fianza y modelo de moto que ha reservado "CAL CRUTCHLOW" --JOIN-- select r.fecha, r.fianza, m.modelo from clientes c join motocicletas m join reserva r on c.dni=r.dni_clientes and r.matricula_motocicletas=m.matricula where c.nombre="carl" and c.apellidos="crutchlow"; +------------+--------+---------------+ fecha fianza modelo +------------+--------+---------------+ 2017-01-24 800 GILERA RUNNER +------------+--------+---------------+ 1 row in set (0.00 sec) --SUBC-- select fecha,fianza, (select modelo from motocicletas where matricula=matricula_motocicletas) as "modelo" from reserva where dni_clientes=(select dni from clientes where nombre="carl" and apellidos="crutchlow"); +------------+--------+---------------+ fecha fianza modelo +------------+--------+---------------+ 2017-01-24 800 GILERA RUNNER +------------+--------+---------------+ 1 row in set (0.00 sec) 12
--- Precio y modelo de las 3 motos más caras compradas a "MOTOVENTURA" --JOIN-- select m.precio, m.modelo from motocicletas m join proveedores p join compran co on m.matricula=co.matricula_motocicletas and co.nif_proveedores=p.nif where p.nombre="motoventura" order by m.precio desc limit 3; +--------+-----------+ precio modelo +--------+-----------+ 4433 KTM RC 3999 RIEJU RS3 3499 HONDA CBR +--------+-----------+ 3 rows in set (0.00 sec) --SUBC-- select precio, modelo from motocicletas where matricula in(select matricula_motocicletas from compran where nif_proveedores=(select nif from proveedores where nombre="motoventura")) order by precio desc limit 3; +--------+-----------+ precio modelo +--------+-----------+ 4433 KTM RC 3999 RIEJU RS3 3499 HONDA CBR +--------+-----------+ 3 rows in set (0.00 sec) 13
--- Matriculas y modelo de motocicletas que compran del proveedor "MARQUEMOTOR" y a que cliente pertenece cada una --JOIN-- select c.matricula_moto, c.apellido, c.nombre, m.modelo from clientes c join proveedores p join motocicletas m join compran cr on m.matricula=c.matricula_moto and c.matricula_moto=cr.matricula_motocicletas and cr.nif_proveedores=p.nif where p.nombre="marquemotor"; +----------------+---------------------+-----------+-----------+ matricula_moto modelo apellidos nombre +----------------+---------------------+-----------+-----------+ 1234A TRIUMPH STREET TRIP PEDROSA DANIEL 1234B KAWASAKI Z800 ROSSI VALENTINO 1234C DUCATI MONSTER LORENZO JORGE +----------------+---------------------+-----------+-----------+ 3 rows in set (0.00 sec) --SUBC-- select matricula_moto, apellidos, nombre,(select modelo from motocicletas where matricula=matricula_moto) from clientes where matricula_moto in(select matricula_motocicletas from compran where nif_proveedores in(select nif from proveedores where nombre="marquemotor")); +----------------+-----------+-----------+---------------------- --------------------------------------------+ matricula_moto apellidos nombre (select modelo from motocicletas where matricula=matricula_moto) +----------------+-----------+-----------+---------------------- --------------------------------------------+ 1234A PEDROSA DANIEL TRIUMPH STREET TRIP 1234B ROSSI VALENTINO KAWASAKI Z800 14
1234C LORENZO JORGE DUCATI MONSTER +----------------+-----------+-----------+---------------------- --------------------------------------------+ 3 rows in set (0.00 sec) --- Nif del proveedor que ha suministrado la moto con matricula "1234F", la edad y apellidos del cliente a la que corresponde y su codigo de vendedor --JOIN-- select c.apellidos, c.edad, v.codigo_empleados, pr.nif from proveedores pr join compran co join clientes c join venden v on pr.nif=co.nif_proveedores and co.matricula_motocicletas=c.matricula_moto and c.dni=v.dni_clientes where c.matricula_moto="1234f"; +--------+-----------+------+------------------+ nif apellidos edad codigo_empleados +--------+-----------+------+------------------+ 987653 DOVICIOSO 28 6 +--------+-----------+------+------------------+ 1 row in set (0.00 sec) 15
--SUBC-- select apellidos, edad, (select codigo_empleados from venden where dni_clientes=dni), (select(select nif from proveedores where nif=nif_proveedores) from compran where matricula_motocicletas=matricula_moto) as "codigo" from clientes where matricula_moto="1234f"; +-----------+------+-------------------------------------------- ------------------+--------+ apellidos edad (select codigo_empleados from venden where dni_clientes=dni) codigo +-----------+------+-------------------------------------------- ------------------+--------+ DOVICIOSO 28 6 987653 +-----------+------+-------------------------------------------- ------------------+--------+ 1 row in set (0.00 sec) 16
7- Creación de usuarios y privilegios Creo el usuario ernesto para un host determinado y le doy contraseña: >CREATE USER ernesto@localhost IDENTIFIED BY inves ; Creo otros dos usuarios directamente con INSERT: >INSERT INTO mysql.user (User, Host, Password) VALUES ( alberto, localhost, password ( inves )); >INSERT INTO mysql.user (User, Host, Password) VALUES ( hugo, localhost, password ( inves )); > FLUSH PRIVILEGES; Cambio el password de un ernesto: >SET password for ernesto@localhost=pasword( inves1 ); Doy privilegios al usuario Ernesto en toda la base de datos fullgas: >GRANT ALL PRIVILEGES ON fullgas.* TO ernesto @ localhost IDENTIFIED BY inves1 ; Doy privilegios al usuario Alberto en la tabla motocicletas de la base de datos Fullgas: >GRANT ALL PRIVILEGES ON fullgas.motocicletas TO alberto @ localhost IDENTIFIED BY inves ; El usuario Hugo podrá consultar la tabla proveedores de la base de datos Fullgas: >GRANT SELECT ON fullgas.proveedores TO hugo @ localhost IDENTIFIED BY inves ; El usuario Hugo podrá consultar, insertar y actualizar las columnas de la tabla motocicletas de la base de datos Fullgas: >GRANT INSERT, SELECT, UPDATE (MATRICULA, CILINDRADA, CABALLOS, NUM_BASTIDOR, PRECIO, MODELO) ON fullgas.motocicletas TO hugo @ localhost ; El usuario Alberto podrá consultar e insertar las columnas de la tabla reservas de la base de datos Fullgas: >GRANT INSERT, SELECT (ID, FIANZA, FECHA, MATRICULA_MOTOCICLETAS, DNI_CLIENTES) ON fullgas.reservas TO alberto @ localhost ; El usuario Ernesto podrá actualizar las columnas de la tabla compran de la base de datos Fullgas: >GRANT UPDATE (NIF_PROVEEDORES, MATRICULA_MOTOCICLETAS, CODIGO_EMPLEADOS) ON fullgas.compran TO ernesto @ localhost ; 17
El usuario Ernesto podrá borrar las columnas de la tabla motocicletas de la base de datos Fullgas: >GRANT DELETE (MATRICULA, CILINDRADA, CABALLOS, NUM_BASTIDOR, PRECIO, MODELO) ON fullgas.motocicletas TO ernesto @ localhost ; El usuario Ernesto solo se podrá conectar dos veces por hora: >GRANT USAGE ON fullgas.* TO ernesto @ localhost WITH max_connections_per_hour 2; El usuario Hugo solo se podrá conectar 1 veces por hora: >GRANT USAGE ON fullgas.* TO hugo @ localhost WITH max_connections_per_hour 1; El usuario Ernesto solo podrá hacer diez consultas por hora: >GRANT USAGE ON fullgas.* TO ernesto @ localhost WITH max_queries_per_hour 10; El usuario Alberto solo podrá hacer diez consultas por hora: >GRANT USAGE ON fullgas.* TO alberto @ localhost WITH max_queries_per_hour 10; Mostrar los privilegios de todos los usuarios: >SHOW GRANTS ernesto.localhost; >SHOW GRANTS alberto.localhost; >SHOW GRANTS hugo.localhost; 8- Exportación Base de datos Realizaré una exportación de la base de datos por si hay algún fallo en el servidor o se borrasen los datos inesperadamente. Esto servirá de copia de seguridad. Aquí la vemos creada: 18
9- Procedimientos Creo un procedimiento que nos diga el empleado que ha vendido más motos en todo el año 19
Creo un procedimiento que nos diga la fecha y la fianza que se pagó por una motocicleta pasando como parámetro el DNI del cliente, ordenado por fecha. 20
Creo un procedimiento para que me diga qué empleado vendió una motocicleta con matricula X (En este caso utilizo 1234F ) y a qué cliente fue. Utilizo consultas multitabla para ello. drop procedure if exists procedimiento; delimiter // create procedure procedimiento (in matricula varchar(6)) begin select c.apellidos, c.edad, v.codigo_empleados, pr.nif from proveedores pr join compran co join clientes c join venden v on pr.nif=co.nif_proveedores and co.matricula_motocicletas=c.matricula_moto and c.dni=v.dni_clientes where c.matricula_moto=matricula; end// delimiter ; call procedimiento ("1234F"); +-----------+------+------------------+--------+ apellidos edad codigo_empleados nif +-----------+------+------------------+--------+ DOVICIOSO 28 6 987653 +-----------+------+------------------+--------+ 1 row in set (0.14 sec) Query OK, 0 rows affected (0.16 sec) 21
10- Funciones Creo una función que me devolverá 1 si el email del usuario está en uso y 0 si está disponible. No puede haber dos emails iguales 22
Creo una función que me diga el tipo de la motocicleta pasando como parámetro el modelo 11- Vista Creo una vista que muestre las motocicletas con una cilindrada superior a 50cc 23
CREATE VIEW cilindrada as select ID, MODELO, PRECIO, CABALLOS, CILINDRADA from motocicletas where cilindrada > 50 12- Eventos El precio de las motocicletas de tipo NAKED se rebajará un 8% cada tres meses El precio de las motocicletas de tipo SCOOTER aumentará un 3% cada cinco meses 24
13- Trigger Crearé un trigger para almacenar en una tabla los usuarios que se han dado de baja en nuestro servidor. La tabla será llamada BAJAS. 25
26