SlideShare una empresa de Scribd logo
1 de 107
Descargar para leer sin conexión
Bases de datos
Versión 1.1

Óscar Gómez

Curso 2012-2013
Índice general

1. Introducción
1.1. Historia de las bases de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2. Historia del software libre GNU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3. Un repaso al resto del libro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3
3
3
3

2. Diseño de bases de datos
2.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . .
2.2. Modelado de datos . . . . . . . . . . . . . . . . . . . . .
2.3. Modelos E/R . . . . . . . . . . . . . . . . . . . . . . . .
2.4. Problemas . . . . . . . . . . . . . . . . . . . . . . . . .
2.5. Transformación de modelos E/R en modelos relacionales .
2.6. Normalización . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

5
. 5
. 6
. 6
. 11
. 22
. 24

3. Diseño físico
3.1. Introducción . . . . . .
3.2. BBDD en Access . . . .
3.3. Claves ajenas . . . . . .
3.4. MySQL . . . . . . . . .
3.5. Tablespaces y undo files

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

27
27
27
31
31
37

.
.
.
.
.
.
.
.

39
39
39
39
41
44
45
46
59

.
.
.
.
.

.
.
.
.
.

4. Consultas SQL
4.1. Introducción . . . . . . . .
4.2. La sentencia SELECT . . .
4.3. Condiciones . . . . . . . .
4.4. Consultas con agregados . .
4.5. Consultas multitabla . . . .
4.6. Algunos ejercicios resueltos
4.7. Subconsultas . . . . . . . .
4.8. Actualización y borrado . .

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

5. Programación
61
5.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.2. Procedimientos almacenados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.3. Sentencias básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
I
5.4.
5.5.
5.6.

Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Funciones MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Solución al examen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

6. Administración
6.1. Introducción . . . . . . . . . . . .
6.2. Aspectos básicos de las contraseñas
6.3. El sistema de privilegios . . . . . .
6.4. El sistema de concesiones . . . . .
6.5. Usuarios con restricciones . . . . .
6.6. Vistas . . . . . . . . . . . . . . . .
6.7. Recuperando la clave de root . . . .
6.8. Copias de seguridad . . . . . . . .

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

79
79
79
80
82
82
83
85
85

7. Access
89
7.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.2. El entorno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
8. BBDD Objeto relacionales
8.1. Introducción . . . . . . . . . . . . . .
8.2. Instalación de PostgreSQL . . . . . . .
8.3. Uso de Postgres en una máquina virtual
8.4. Funcionamiento básico de Postgres . .
8.5. Comandos de Postgres . . . . . . . . .
8.6. Creación de tipos de datos . . . . . . .
8.7. Soporte documental . . . . . . . . . .
8.8. Sistemas de información geográfica . .
9. Índices y tablas

II

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

91
91
91
91
92
92
96
98
99
103
Bases de datos, Versión 1.1

Contents:

Índice general

1
Bases de datos, Versión 1.1

2

Índice general
CAPÍTULO 1

Introducción

1.1 Historia de las bases de datos
1.2 Historia del software libre GNU
1.3 Un repaso al resto del libro

3
Bases de datos, Versión 1.1

4

Capítulo 1. Introducción
CAPÍTULO 2

Diseño de bases de datos

2.1 Introducción
En general, la construcción de una casa se considera un proyecto de envergadura. Dado que no se puede
permitir que cada uno de los participantes en el proyecto siga su propio ritmo o haga lo que crea conveniente, se asume que habrá un arquitecto que diseña una estructura y realiza los cálculos necesarios
para que todo se construya correctamente. En las bases de datos ocurre lo mismo: determinados negocios necesitarán una infraestructura de información muy sofisticada por lo que puede ser conveniente
disponer de unos “planos” que permitan la comunicación entre los distintos miembros que participan en
un proyecto de desarrollo de un programa informático.
Además, muy a menudo ocurre que transcurrido un tiempo, el usuario del programa desea hacer mejoras
o ampliaciones pero por desgracia, la estructura de una base de datos o de un programa no son tan visibles
como los muros de una casa. La existencia de los planos o diagramas que expliquen como se hizo una
base de datos pueden ser de gran ayuda para tales mejoras. Es de esperar que un cliente con visión de
futuro exija una cierta documentación de como se hizo un programa.
Por otro lado, un problema habitual para los desarrolladores informáticos es la necesidad de conocer un
poco el “dominio de conocimiento”. Es decir, si se necesita construir una base de datos que almacene
información sobre impuestos, es muy probable que primero se necesite conocer un poco más como
funciona ese mundo. El conocimiento que se obtenga junto a los requisitos que tenga el cliente deberían
plasmarse de alguna forma en un documento.
Al igual que la construcción de una casa requiere la elaboración de planos y cálculos el diseño de una
estructura de almacenamiento de datos requiere que exista un mecanism
Los diagramas como “planos” de una BBDD. Se utilizarán para que despues todo el mundo pueda
entender qué hay dentro de la BBDD por si se necesita modificar algo.
Un problema fundamental es el dominio de conocimiento. Como informáticos debemos intentar
adquirir el conocimiento del cliente para reflejarlo en una BD. En esencia debemos intentar extraer
la información RELEVANTE
Otro problema de gran importancia es la ambigüedad. Se debe concretar al máximo el significado
de cada palabra o término específico.
En suma, un informático va a construir un modelo del conocimiento del cliente. La primera labor
a la hora de construir una BD es modelar la información.

5
Bases de datos, Versión 1.1

Las reuniones, el proceso de desambigüación etc... deben plasmarse en una especificación de
requisitos. Un ejemplo de especificación es el estándar IEEE 830, que ofrece una plantilla que
podemos rellenar.
Una vez hecha la especificación, se procederá a la realización del diseño, modelo, plano...

2.2 Modelado de datos
Al hacer un modelo, plano o diagrama de datos, se hacen abstracciones
• Hay que reseñar que no seremos expertos en el campo de aplicación.
• Es muy importante utilizar un lenguaje estándar.
• Los distintos SGBD (Sistemas Gestores de Bases de Datos) son muy distintos entre sí
◦ Por ejemplo, tenemos SGBD monolíticos: se caracterizan por utilizar un solo programa
de uso y administración de los datos.
◦ También existen los SGBD basados en un modelo cliente/servidor. Los SGBD
cliente/servidor hacen que los datos estén gestionados por un solo programa llamado
servidor. A dichos datos pueden acceder montones de clientes.
• Debido a estas diferencias el proceso de crear tablas necesita pasar por varias fases.
◦ Primero se debe hacer el llamado modelo conceptual. Este modelo consiste en hacer los
diagramas que reflejan los requisitos.
◦ Despues haremos el llamado diseño lógico que consiste en crear una estructura de tablas
y claves.
◦ Por último se debe hacer el diseño físico que consiste en pasar el diseño lógico a un
lenguaje SQL de un SGBD.

2.3 Modelos E/R
El modelo E/R se remonta al año 1970, cuando Peter Chen observó lo complejo que era diseñar una base
de datos. Decidió crear un lenguaje común de símbolos que facilitara la comunicación.

2.3.1 Entidades
Se denomina entidad a cualquier elemento sobre el cual se desea almacenar información. Aunque las
entidades suelen corresponderse con los sustantivos, no todos los sustantivos merecen ser entidades que
aparezcan en el modelo.
Las entidades pueden ser fuertes o débiles:
Una entidad fuerte es aquella que existe por sí sola.
Una entidad débil es aquella que requiere que otra entidad exista antes que ella.
Supongamos una situación como “empleado realiza viajes”. No se puede almacenar nada sobre un viaje
si previamente no existe un empleado que lo realice.
En la debilidad hay dos posibilidades:

6

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

Dependencia en existencia: una entidad es débil con dependencia en existencia si antes de poder
“existir” o “almacenarse” requiere que otra entidad exista primero.
Dependencia en identificación: la entidad débil no tiene clave propia sino que necesita la de otra
entidad.

2.3.2 Ocurrencia de entidades
En general una misma entidad puede ocurrir muchas veces, se dice que una entidad puede tener “varias
instancias”. Una entidad “Coche” puede tener infinitas instancias como “Seat Ibiza CR-2785-X”, “Renault 21 8765-CWG”, ...

2.3.3 Interrelaciones
Son asociaciones entre entidades. En general se corresponden con los verbos. Se representan por medio
de un rombo con el nombre dentro.
Las interrelaciones pueden ser entre distintos conjuntos de entidades
Interrelación binaria: se da entre dos entidades.
Interrelación ternaria: se da entre tres entidades que participan de forma simultánea en una asociación.
Interrelación n-aria.
Interrelaciones reflexivas: se dan entre una entidad y sí misma. El principal ejemplo se da en la
sentencia “unos empleados son jefes de otros”.

2.3.4 Participación o “cardinalidad”
En las bases de datos se debe reflejar el hecho de que las entidades puedan aparecer 0 veces, 1 vez,
muchas veces.
En el diagrama, se ponen las cardinalidades junto a la entidad y con el mínimo y el máximo.
Para abreviar,a veces se ponen los máximos encima de la relación y tendremos entonces relaciones como
esta:
“Uno a uno” o 1:1
“Uno a muchos” o 1:n
“Muchos a muchos” o m:n
Ejercicios: hacer el diagrama E/R con entidades, debilidades, interrelaciones y cardinalidades de los
siguientes supuestos.
Hombre se casa con mujer en sociedad monógama
Hombre se casa con mujer en sociedad polígama masculina
Hombre se casa con mujer en sociedad polígama mixta
Pescador pesca pez
Arquitecto diseña casa

2.3. Modelos E/R

7
Bases de datos, Versión 1.1

Piezas forman producto
• Téngase en cuenta que producto no es débil. Esto se debe a que podemos almacenar
un producto en la base de datos indicando un hecho:”el producto P1 está hecho de los
tornillos T1, T2 y T3”. Este hecho se puede almacenar aunque no tengamos físicamente
los tornillos. A la hora de comprobar la “debilidad” de una entidad se debe ver si podemos almacenar los hechos o no, sin pensar en productos o piezas físicos.
Turista visita hotel
Jugador juega equipo
Político gobierna país.
Autor publica libro en una editorial
• Podría verse la solución a esto como tres relaciones
1. Autor escribe libro
2. Libro es editado por editorial
3. Editorial publica libro
• O como una relación ternaria: “Autor publica libro en editorial”
• En resumen, ante las dudas debemos fabricar un diagrama que recoja las posibles asociaciones: supongamos que conocemos los siguientes hechos
◦ Cervantes escribe Quijote
◦ Cervantes escribe Novelas Ejemplares
◦ Iván López escribe Bases de datos
◦ M.J Castellanos escribe Bases de datos
◦ Ed. Anagrama publica Quijote
◦ Ed. Anagrama publica Novelas ejemplares
◦ Ed. Garceta publica Bases de datos
◦ Ed. Garceta publica Lazarillo
• Si en las distintas asociaciones encontramos que hay asociaciones rígidas que no pueden
cambiar, deberemos usar una interrelación ternaria: Cervantes escribe Quijote es un hecho
que no puede variar. Es cierto que la otra asociación sí puede cambiar: por ejemplo, mañana
Ed. Anagrama publica Bases de datos. Aunque esto es un hecho flexible la relación “AutorLibro” no puede cambiarse.

2.3.5 Atributos
Se denomina atributos a propiedades de las entidades que tienen la importancia suficiente para almacenar
datos sobre ellas y que por tanto aparecerán en el diagrama E/R.
Los atributos suelen tener un dominio: es decir un conjunto de valores del cual toman su información.
Un detalle sutil pero importante es que en ocasiones los atributos no son de las entidades, sino de las
relaciones. Ej: pensemos en el diseño E/R de un enunciado como este: “un mecanico repara un coche en
una cierta fecha del año”. La información de un conjunto cualquiera de mecánicos podría ser la siguiente

8

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

DNI
10
20
30

Nombre
Juan
Luis
Angel

Ap1
Sanz
Sanz
Diaz

Ap2
Alcolea
Ruiz
Diaz

Es evidente que no podemos poner la fecha de reparación en la entidad Mecánico: un mecánico solo
podría reparar coches una vez en su vida, ya cada mecánico solo aparece una vez en la tabla.
Por otro lado, supongamos la siguiente información sobre un conjunto de coches.
Matric.
2211-ZW
4324-EE
5421-AA

Marca
Seat
Renault
VW

Modelo
Ibiza
21
Bora

La fecha de reparación tampoco es de la entidad Coche: si lo hiciéramos así un coche solo podría
repararse una vez en la vida (recordemos que cada coche solo aparece una vez en la tabla).
A veces, hay atributos que se comportan de una forma especial y esto se recoge en el diseño E/R
Atributos opcionales: pueden aparecer o no.
Atributos monovaluados: solo toman un valor (o como mucho dos, por exclusión).
Atributos compuestos: por ejemplo, el campo “Dirección”.
Atributos derivados: son aquellos que pueden obtenerse o calcularse a partir de otros. Por ejemplo,
el campo “Edad” puede obtenerse a partir de “Fecha de nacimiento”.

2.3.6 Entidades débiles
Ya hemos dicho que hay entidades que muestran “debilidad” en base a dos características
Dependencia en existencia: por ejemplo la entidad “Transacción” es débil con respecto a “Cuenta
Corriente”. En este caso, la interrelación llevará una letra E, para indicar este tipo de dependencia.
Dependencia de identificación: en este caso, la relación utiliza una I para señalar la dependencia.
Ejercicio:¿Qué tipo de relación existe entre estas entidades?
1. Toro y Ganadería: Toro es débil (dependencia en identificación) con respecto a Ganadería.
2. Una empresa tiene un párking y desea almacenar qué empleados aparcan vehículos y los datos
sobre los mismos.

2.3.7 Ejercicio de modelado
Enunciado
Analiza el siguiente enunciado y transfórmalo en DOS diagramas E/R. ¿Qué características reflejan uno
u otro modelo?:
Una serie de empresas con CIF, Nombre y Dirección desean ofrecer beneficios a sus clientes. Estos
beneficios tienen un código, una descripción y una limitación. Para obtener dichos beneficios se emiten
una serie de cupones que tienen un código y una fecha de vencimiento

2.3. Modelos E/R

9
Bases de datos, Versión 1.1

Solución
No hay una solución correcta a partir de lo que nos dicen. Podemos pensar en dos posible situaciones
1. Las empresas son libres de ofrecer beneficios, modificarlos y hacer cambios cuando lo deseen.
2. Los beneficios solo los inserta un administrador y las empresas deben ceñirse a la lista de posibilidades que les ofrecemos
Esto da lugar a que el ejemplo a) sea un modelo en el que se da libertad mientras que el modelo b) sea
más rígido, lo que a su vez condiciona el modelo
Podemos por tanto contemplar dos soluciones a partir de las tres entidades Empresa, Beneficio y Cupón
1. Dos relaciones binarias
Relación “Empresa ofrece Beneficio”
Relación “Beneficio Se Plasma En Cupón”
2. Una sola relación ternaria “Empresa con Beneficio con Cupón”
Imaginemos las tres tablas, Empresa, Beneficio y Cupón.
CIF
E1
E2

Nombre
ACME
XYZ Sport

Direccion
C/ Guadiana
C/ Rio

Codigo
B1
B2

Desc.
10 % desc.
5 % desc

Codigo
C1
C2

Limit.
Excepto rebajas
LaJ

Fecha venc
31-12-2011
20-12-2011

A la hora de insertar en la tabla Beneficios puede que si damos libertad acaben apareciendo filas iguales
Codigo
B1
B2
B3
B4
B5

Desc.
10 % desc.
5 % desc
5 % desc
5 % desc
15 % desc.

Limit.
Excepto rebajas
LaJ
LaJ
LaJ
Solo S y D

En este caso, B2, B3 y B4 corresponden a los beneficios que ofrecen distintas empresas, dando la casualidad de que sus descripciones son iguales. Hay quien considera eso un problema, pero no lo es, sino
que es una consecuencia de la libertad que tienen las empresas para actuar.

2.3.8 Herencia
En ocasiones hay objetos que comparten muchas propiedades y características. Supongamos el ejemplo
de una base de datos para la DGT. Para cada coche puede haber un dueño, pero este dueño puede
ser una persona física o jurídica. Si construyéramos dos entidades separadas “Persona” y “Empresa”
descubriríamos que tienen cosas en común.
Para ahorrar esfuerzos se puede poner una sola entidad general que “ofrece” los atributos, y dichos
atributos son “heredados” por las entidades hija.

10

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

Cuando hay una herencia es posible que una instancia pueda ser de dos entidades a la vez. Por ejemplo,
pensemos en las entidades “Personal Contratado” y las entidades “Estudiante” y “Trabajador”. ¿Puede
una persona ser estudiante y trabajador a la vez? SÍ . Por lo tanto esta herencia no es disjunta, pero la de
“Persona” y “Empresa” sí es disjunta.
Las herencias disjuntas se marcan con una “d” en el triángulo.

2.3.9 Relaciones exclusivas
A veces dos entidades pueden ir relacionadas por dos o más conexiones. En determinadas situaciones
interesa restringir el número de conexiones posibles.
Por ejemplo, cuando una entidad “Cliente” se conecta con una entidad “Piso” puede hacerlo por medio
de varias relaciones como “Vende”, “Alquila”, “Hace leasing”. Si por ejemplo la ley obligase a que solo
podamos tener un tipo de relación, se pondrá un arco en las relaciones.

2.4 Problemas
2.4.1 Problema 1: Comunidades de vecinos
Una firma de abogados dedicada a la administración de fincas desea tener una base de datos para gestionar la información de sus clientes.
La firma tiene varios abogados y cada uno de ellos ejerce de administrador de una o más comunidades de
vecinos, por lo que cobra unos honorarios anuales. Una comunidad es gestionada por un único administrador (nombre, DNI y número de colegiado). Las funciones de un administrador consisten en llevar la
contabilidad de la comunidad, gestionar los recibos y realizar los pagos a las distintas compañías (luz,
agua...)
De las empresas que cada comunidad tiene contratadas se guarda su nombre, dirección, teléfono y una
persona de contacto. Además puede interesar tener agrupadas a las compañías por sectores (sector de
seguridad, sector de suministros básicos).
De cada comunidad se almacena un código, su nombre, calle, código postal y población. Cada comunidad consta de una serie de propiedades que pueden ser de tres tipos (vivienda particular, local y
oficina). Cada propiedad se caracteriza por un número de portal, planta y letra, un nombre y apellidos
del propietario, un porcentaje de participación en los gastos de la comunidad así como los datos de la
cuenta bancaria en la que el propietario desea se le domicilie el pago de los recibos.
Si el propietario no habita en su propiedad se necesitan sus datos (nombre, apellidos, dirección y teléfono) y los datos de su inquilino (nombre apellidos y teléfono).
Si la vivienda es particular se guarda el número de habitaciones. Si es un local se almacena el tipo de
local y el horario. Si es una oficina se guarda la actividad a la que se dedica.
Cada comunidad tiene un presidente (nombre, apellidos y propiedad de la que son dueños) y varios
vocales que tratan con el administrador los asuntos que hay que tratar. Cada comunidad tiene una cuenta
en un banco y todo banco tiene un código y un nombre comercial. De las cuentas se almacena el código
de cuenta (que consta de un código de sucursal, dos dígitos de control y un número de cuenta) y un
saldo. Para identificar la cuenta hay que añadir el código del banco al código de cuenta.
Se almacenan dos tipos de apuntes:

2.4. Problemas

11
Bases de datos, Versión 1.1

El banco emite los recibos, pero el administrador guarda información sobre dichos recibos como
el número de recibo, fecha, importe y si se ha podido cobrar o no. Esta última información se
necesitará para llevar un registro de impagados.
En cuanto a los apuntes sobre gastos se tienen los importes que cobran las empresas contratadas
por cada comunidad. Las compañías cobran sus recibos (número, fecha e importe) cargándolo en
la cuenta de la comunidad

2.4.2 Solución al problema 1
0. Leer el enunciado completo
1. Leer otra vez examinando cuidadosamente los elementos siguientes
1.1. Sustantivos: entidades/atributos
1.1.1. Abogado/administrador
1.1.2. Finca/propiedad
1.1.2.1. Num de portal
1.1.2.2. Planta y letra
1.1.2.3. ¿Nombre y ap del propietario?
Esta frase nos dice que el nombre y el apellido del propietario deben estar
aqui. Sin embargo, si luego resulta que necesito una entidad Propietario, ya
no podremos poner a esa entidad estos atributos. Si resulta que luego necesitamos esta entidad habremos descubierto que “Propiedad” es débil por identificación.
1.1.2.4. Porcentaje de particip.
1.1.2.5. Datos cuenta bancaria
1.1.3. Comunidad de vecinos
1.1.3.1. Nombre
1.1.3.2. Calle
1.1.3.3. CP
1.1.3.4. Población
1.1.4. Honorarios
1.1.5. Funciones
1.1.6. Pagos
1.1.7. Compañía
1.1.8. Empresa
1.1.8.1. Nombre
1.1.8.2. Dirección
1.1.8.3. Teléfono
1.1.8.4. Persona de contacto
12

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

1.1.9. Sector
1.1.10. Tipos
1.1.10.1. Viv. particular
Num. habitaciones
1.1.10.2. Local
Tipo
Horario
1.1.10.3. Oficina
Actividad
1.1.11. Propietario
1.1.1. Nombre
1.1.2. Apellidos
1.1.3. Dirección
1.1.4. Teléfono
Al leer que un propietario tiene que aparecer como entidad, descubrimos que
“Propiedad” va a ser débil, como supusimos.
1.1.12. Inquilino
1.1.12.1. Nombre
1.1.12.2. Apellidos
1.1.13. Presidente
1.1.13.1. Nombre
1.1.13.2. Apellidos
1.1.13.3. Propiedad que poseen
1.1.14. Vocales
1.1.15. Cuenta
1.1.15.1. Código de cuenta
1.1.15.2. DC
1.1.15.3. Número de cuenta
1.1.15.4. Código de banco
Como nos dicen que se necesita el código del banco para poder
“identificar” esta entidad, hemos descubierto que esta entidad es débil
1.1.16. Banco
1.1.16.1. Codigo de banco
1.1.16.2. Nombre comercial

2.4. Problemas

13
Bases de datos, Versión 1.1

1.1.17. Apunte
1.1.17.1. Recibo (cobramos a prop)
Número de recibo
Fecha
Importe
¿Se pagó?
1.1.17.2. Pago (pagamos luz..)
Número de recibo
Importe
Fecha
1.2. Verbos: relaciones
1.2.1 “Abogado” administra “Comunidad”
1.2.2 “Abogado” cobra “Honorarios” (¡¡MAL!!, los honorarios no llegarán a ser entidad)
1.2.3 “Comunidad” es gestionada por “Abogado” es lo mismo que “administra”
1.2.4 “Administrador” realiza funciones
1.2.5 “Comunidad” contrata “Empresa”
1.2.6 “Comunidad” consta de “Propiedades”
1.2.7 “Propiedad” paga a través de “Cuenta”
1.2.8 “Comunidad” tiene “Presidente”
1.2.9 “Comunidad” posee “Vocales”
1.2.10 “Comunidad” opera con “Cuenta”
1.2.11 “Banco” emite “Recibo”

2.4.3 Problema 2: Ajedrez
La federación de ajedrez desea disponer de una base de datos de todas las partidas que se celebren bajo
su auspicio.
Toda partida viene caracterizada por una fecha de inicio, una duración en horas, los jugadores que
se enfrentaron y si eligieron blancas o negras
Dos jugadores pueden enfrentarse solo una vez por día, aunque pueden hacerlo muchas veces en
días distintos.
Se anota cada movimiento de la partida: número de movimiento, casilla de origen y casilla de
destino. Si se borra una partida se deben borrar los movimientos
Las partidas no pueden ser aplazadas
De los jugadores se recogen sus nombres, apellidos, dirección postal y electrónica, la federación
a la que pertenecen y el número de federado (que es único en cada federación)

14

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

Solo hay una federación por país con un nombre, país al que pertenece, telefono de contacto y
fecha de fundación
Una federación no se clausura hasta que no se reasignan sus jugadores a otra federación.
Las partidas pueden darse o no dentro de un torneo. Los torneos tienen un nombre, periodicidad,
fecha de creación y son organizados por una federación
En cada edición de un torneo (número ordinal) se registran todos los enfrentamientos y el nombre
del ganador. También se anotan la fecha de inicio, la cuantía del premio y el jugador que lo gana
Si desaparece una federación, desaparecen los torneos y por ende, sus ediciones
Aunque un jugador desaparezca, sus partidas no deben desaparecer

2.4.4 Solución al problema 2 (ajedrez)
Entidades
Federación
• Atributo:nombre
• Atributo:país
Partida
• Atributo:fecha de inicio
• Atributo:duración
• Atributo:¿blancas?
Jugador
• Atributo:nombre
• Atributo:apellidos
• Atributo:dirección postal
• Atributo:dirección electrónica
• Atributo:num de federado
Movimiento
• Atributo:número
• Atributo:casilla origen
• Atributo:casilla destino
Torneo: es una entidad débil ya que nos dicen “Si desaparece una federación, desaparecen los
torneos y por ende, sus ediciones”. Por tanto, no puede haber torneo en la BD sin que haya una
federación que lo organice.
• Atributo:nombre
• Atributo:periodicidad
• Atributo:fecha

2.4. Problemas

15
Bases de datos, Versión 1.1

• Atributo:ganador
• Atributo:fecha inicio
• Atributo:periodicidad
• Atributo:cuantía del premio
Relaciones
Se necesita una relación para conectar los jugadores con partida: “Partida enfrenta jugadores”. El
enfrentamiento tiene atributos
• También podríamos considerar que hay una sola relación reflexiva “Jugador Se Enfrenta Con
Jugador”. Esta relación tendría atributos como “fecha de inicio”, “duración”, etc...
“Partida Consta De Movimiento”: aquí se descubre que Movimiento es débil, no puede almacenarse un movimiento sin que esté “dentro de una partida”
“Jugador Pertenece A Federación”.
Hay dos posibilidades de relación
• “Federación organiza Torneo que Consta De Partidas”: relación ternaria
• “Federación organiza Torneo y Torneo Consta De Partidas”: dos binarias
• Dado que se permite que las partidas estén o no dentro de un torneo es más apropiados que
el modelo permita cierta libertad para lo cual es más apropiado utilizar las dos binarias.

2.4.5 Problema 3: Formación
El departamento de formación de una empresa desea construir una BD para planificar y gestionar la
formación de sus empleados. Los supuestos semánticos que deben recogerse son los siguientes:
La empresa organiza cursos internos de formación de los que se desea conocer el código de curso,
el nombre, una descripción, el número de horas de duración y el coste del curso.
Un curso puede tener como prerrequisito haber realizado otro(s) previamente, y, a su vez, la realización de un curso puede ser prerrequisito de otros. Un curso que es prerrequisito de otro puede
serlo de forma obligatoria u opcional.
Un mismo curso tiene diferentes ediciones, es decir, se imparte en distintos lugares,fechas y con
diversos horarios (intensivo, mañana o tarde). En una misma fecha de inicio sólo puede impartirse
una edición de un curso.
Los cursos se imparten por personal de la propia empresa. Un curso puede tener varios docentes
pero una edición sólo tiene un profesor.
De los empleados se desea almacenar su código de empleado, nombre y apellidos,dirección, teléfono, NIF, fecha de nacimiento, nacionalidad, sexo, firma y salario,así como si está o no capacitado
para impartir cursos.
Un mismo empleado puede ser docente en una edición de un curso y alumno en otra edición, pero
nunca puede ser ambas cosas a la vez (en una misma edición de un curso o lo imparte o lo recibe)

16

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

2.4.6 Solución al problema 3 (Formación)
Entidades
Curso
• Código de curso (clave)
• Nombre
• Descripción
• Duración (número de horas)
• coste
Edición (débil con respecto a curso)
• Lugar
• Fecha: clave
• Horario
Empleado
• Nombre
• Ap
• Dirección
• Tlf
• Dni: clave
• Nacionalidad
• Firma
• Sexo
• Salario
• Capacitado
Relaciones
“Curso Es Prerrequisito De Curso”: muchos a muchos
“Curso Celebra Ediciones”: edición es débil con respecto a curso
“Empleado Imparte Edición”.
“Empleado Sigue Edición”
Nos dicen que no se puede hacer las dos cosas a la vez en una edición, o una u otra.

2.4. Problemas

17
Bases de datos, Versión 1.1

2.4.7 Problema 4: viveros
Se desea diseñar una Base de Datos para gestionar los empleados y productos a la venta de una cadena
de viveros dedicados a la venta de diversos productos relacionados con la jardinería. Los supuestos que
hay que recoger en la BD son los siguientes:
La cadena de viveros dispone de varios viveros en la provincia de Madrid identificados por un
código de tienda y de los que se almacenará un teléfono, una dirección y un responsable que será
uno de los empleados que trabaja en el vivero (es necesario almacenar durante qué períodos de
tiempo ha sido responsable cada empleado).
Los productos que se venden tienen asignado un código de producto y nos interesa guardar el
precio y el stock que hay de cada producto en cada uno de los viveros y pueden ser de tres tipos:
plantas de las que se guardará su nombre, y una breve descripción de los cuidados que requiere;
accesorios de jardinería y artículos de decoración.
Estos productos se distribuyen en zonas dentro de cada vivero cada una de ellas identificadas por
un nombre dentro de cada vivero (zona exterior regadío, interior climatizada, zona de caja, etc.).
Se desea conocer el stock de cada producto de acuerdo a las zonas del vivero.Los empleados
estarán asignados a una determinada zona en un vivero la cual podrá cambiar a lo largo del tiempo
(se guardará histórico de ello) y además, los empleados puedenmo verse de un vivero a otro según
las necesidades en distintos períodos de tiempo.
De los empleados se quiere conocer su DNI, su nombre y un teléfono de contacto.En cuanto al
proceso de venta de los distintos productos, sólo se almacenarán los pedidos que realizan los
clientes pertenecientes al Club VIP que es una promoción especial que permite a los clientes
obtener descuentos según las cuantías de sus compras. De estos clientes se almacena su DNI, su
nombre, dirección, teléfono y la fecha de incorporación al club así como los datos de sus pedidos
que incluyen un número de pedido, la fecha de realización, los productos adquiridos junto con las
unidades y el descuento realizado; por último, también se incluye el precio de los portes en caso
de que se hayan contratado. De cada cliente se almacenarán todos los pedidos que haya realizado
hasta la fecha.En cuanto a estos pedidos de clientes pertenecientes al Club VIP interesa también
guardar quién fue el empleado que lo gestionó y en qué vivero se realizó el pedido teniendo en
cuenta que un pedido en un determinado vivero lo gestiona un único empleado
Solución al problema 4 (Viveros)
Entidades:
Empleado
• DNI
• Nombre
• Número de contacto
Producto
• Código
• Precio
• Stock (más tarde se descubre que stock NO ES UN ATRIBUTO DE PRODUCTO sino de
una relación)
Planta es una entidad hija de Producto
18

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

• Nombre
• Cuidados
Accesorio de jardinería (hija de producto)
Artículo
Viveros
• Código
• Teléfono
• Dirección
• ¿Responsable? No, esto es una relación
Zona
• Nombre (clave)
Pedido
• Número: clave
• Fecha
• Unidades, precio de portes y descuento son atributos de una relación cuyo nombre todavía
no conocemos.
Cliente: habrá “Normales” y “Club VIP”
• DNI
• Dirección
• Teléfono
• Fecha de incorporación (solamente para el club VIP)
Relaciones:
“Empleado es Responsable De Vivero” tiene unos atributos de fecha de inicio y fin.
“Producto Se Distribuye en Zona”. Esto implica que hay un atributo en esta relacion llamado
Stock.
“Empleado Trabaja en Zona”
A la hora de almacenar el hecho de que un pedido consta de varios productos vamos a descubrir
que la relación ternaria no es la mejor opción ya que nos obligaría a que en un pedido solo apuntásemos un producto
VIP1
VIP1
VIP1

Ped1
Ped1
Ped1

Rosas
Tijeras
Semillas

Técnicamente, esta relación ternaria es capaz de guardar el hecho de que el cliente VIP1, en su pedido 1
compró “Rosas, Tijeras y Semillas”, sin embargo este modelo ternario nos está obligando a repetir datos.
Como conclusión la relación “Cliente hace pedido que consta de Artículos” no es la mejor opción, sino
que desglosaremos esto en dos binarias
“Vip Realiza Pedido” (esto implica que Pedido es débil)

2.4. Problemas

19
Bases de datos, Versión 1.1

“Pedido consta de Productos”.
Hay una relación a cuatro entre “Pedido” “Cliente VIP”, “Vivero” y “Empleado”
Problema

2.4.8 Problema 5: Universidad
El Departamento de Informática de la universidad necesita una base de datos para almacenar la información concerniente a los proyectos de investigación tanto actuales como pasados en los que trabajan los
profesores y así poder llevar a cabo una gestiónmás eficiente. La información que se desea almacenar
corresponde a los siguientes supuestossemánticos.
En el departamento los profesores participan en proyectos de investigación caracterizados por un
código de referencia único, por un nombre, un acrónimo, un presupuesto total, el programa de
I+D que lo financia, una fecha de inicio y una fecha de finalización y una breve descripción de los
objetivos del proyecto.
En los proyectos trabajan profesores del departamento durante un período de tiempo, esdecir, una
fecha de inicio y una fecha de fin, pudiendo ocurrir que un profesor trabaje en elmismo proyecto
en varias épocas (f_ini, f_fin) diferentes.
Un profesor se identifica por su nombre y apellidos y se caracteriza por su despacho y teléfono
y puede trabajar en varios proyectos simultáneamente y en un proyecto de investigación trabajan
varios profesores. De todos los profesores que trabajan en el proyecto hay uno que es el investigador principal deproyecto que interesa conocer. Es importante tener en cuenta que el profesor
investigador del proyecto nunca varía a lo largo de la vida del proyecto de investigación.
Los profesores pueden ser doctores o no doctores, de tal manera que un profesor nodoctor siempre tiene a un único profesor doctor como supervisor en un momento determinado,interesando
almacenar los supervisores y períodos de tiempo de la supervisión que ha tenido undeterminado
profesor no doctor.
En relación con la participación de los profesores en proyectosde investigación, el investigador
principal de un proyecto siempre tiene que ser un doctor.Por otro lado, los proyectos de investigación producen una serie de publicaciones sobrelas que también interesa guardar información.
Una publicación se caracteriza por un número en secuencia dentro de cada proyecto de investigación y se guardará el título y los profesores que la han escrito; las publicaciones son de dos
tipos, publicaciones en congresos y publicaciones en revista; de las primeras se almacenará el
nombre del congreso, su tipo (nacional ointernacional), la fecha de inicio y de fin, el lugar de celebración, país y la editorial que hapublicado las actas del congreso (si es que se han publicado);
de las publicaciones en revista interesa saber el nombre de la revista, la editorial, el volumen, el
número y las páginas de inicio y fin.
No solamente interesa conocer los profesores que han participado en las publicaciones de los
proyectos de investigación sino también las líneas de publicación que cubren estas publicaciones.
Una línea de investigación se identifica por un código, un nombre (por ejemplo,recuperación de
información multilingüe, bases de datos espacio-temporales, etc.) y un conjunto de descriptores
(por ejemplo, la línea de investigación bases de datos temporales puede tener como descriptores
Bases de Datos, SGBD Relacional, Dimensión temporal).
Los profesores tendrán asociados en la BD las líneas de investigación en las quetrabajan incluso podría ocurrir que hubiera profesores que no tuvieran ninguna línea asignada.Así, tanto los
profesores doctores como los no doctores pueden escribir publicaciones sobre una o más líneas
de investigación y nos interesa saber sobre qué línea de investigación ha escrito un determinado
20

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

profesor en una publicación, teniendo en cuenta que un profesor queparticipa en una publicación
sólo escribe en el ámbito de una línea de investigación y que una determinada publicación puede
cubrir varias líneas de investigación
Solución: entidades
Proyecto
• código de referencia único
• un nombre
• un acrónimo
• un presupuesto total
• el programa de I+D que lo financia
• una fecha de inicio y una fecha de finalización
• y una breve descripción
Profesor
• Nombre y apellidos.
• Despacho y teléfono.
• ¿Investigador principal hijo de Profesor? Es mala idea porque usaríamos una entidad para
algo que aparecerá una sola vez.
• “Doctor” y “No doctor” sí pueden ser entidades hija.
Publicación.
• Número
• Título
• Profesores que lo escriben (esto será una relación)
• “En congreso” y “En revista” serán entidades hija.
◦ En congreso tiene los atributos: Tipo, nombre, fecha de inicio, de fin, lugar de celebración, país y editorial.
◦ En revista tiene los atributos: nombre de revista, el volumen, editorial, páginas de inicio
y fin.
Línea
• Código
• Nombre
Descriptores:
• Nombre

2.4. Problemas

21
Bases de datos, Versión 1.1

Solución: relaciones
“Profesor Participa en Proyecto”
“Profesor dirige proyecto”, esta relación contiene el hecho de que un proyecto tiene 1 y solo 1
“investigador principal”.
“Doctor supervisa a No Doctor”
“Doctor dirige proyecto”, esta relación sustituye a la anterior “Profesor dirige proyecto”.
“Proyecto produce publicación”. En realidad, más adelante descubriremos que el Profesor debe
intervenir en esta relación dando lugar a una relación ternaria “Proyecto produce publicación en
la que interviene profesor”

2.5 Transformación de modelos E/R en modelos relacionales
Toda entidad se convierte en tabla.
Toda entidad débil se convierte en tabla. La clave de esta tabla será la mezcla de la clave del débil
más la clave del fuerte.
En una herencia, la entidad padre se convierte de forma normal. Las hijas heredan la clave del
padre (y en las hijas será además clave ajena).
En las relaciones se trabaja de la siguiente forma
• Si la relación es 1:1 ambas entidades se convierten a tablas Y UNA DE ELLAS TOMA LA
CLAVE DE LA OTRA que actuará solo como clave ajena
• Si la relación es 1:N el que tiene el N toma la clave del que tiene el 1, que actuará como
parte de la clave primaria además de ser clave ajena. Si además la relación tuviera atributos,
estos atributos van en el que tiene el N.
• Si la relación es M:N LA RELACIÓN SE CONVIERTE EN TABLA. La clave de esa
tabla es la mezcla de las claves de los participantes. Todas ellas actúan además como claves
ajenas. Si la relación tiene atributos los ponemos en esta tabla.

2.5.1 Transformación del modelo “Universidad”
Se muestran en negrita las claves primarias.
Publicación (Número, Título)
EnCongreso(Número, Título, Tipo, FechaInicio, FechaFin, Lugar, País, Editorial)
• Clave ajena: La pareja (Número,Título) es clave ajena sobre Publicación(Número,título)
EnRevista(Número, Título, Nombre, Volumen, Editorial, PaginaInicio, PaginaFin)
• Clave ajena: La pareja (Número,Título) es clave ajena sobre Publicación(Número,título)
Línea (CódigoLínea, Nombre)
Descriptor (Nombre)
EntraEn(CódigoLínea, NombreDescriptor)
• Clave ajena: CódigoLínea es clave ajena sobre Línea(Código)
22

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

• Clave ajena: NombreDescriptor es clave ajena sobre Descriptor(Nombre)
Cubre(Numero, Título, CodigoLinea)
• Clave ajena: La pareja (Número,Título) es clave ajena sobre Publicación(Número,título)
• Clave ajena: El atributo CodigoLinea es clave ajena sobre Linea(Codigo)
Profesor (Nombre, apellidos, Despacho, Tlf)
Doctor (Nombre, apellidos)
NoDoctor (Nombre, apellidos, Nombre, apellidos)
• Clave ajena: La segunda pareja (nombre,apellidos) es clave ajena sobre Doctor(Nombre,
apellidos). Solo es clave ajena por ser una relación 1:n
Produce (Nombre, apellidos, número, título, código)
• Clave ajena: La pareja (nombre,apellidos) es clave ajena sobre Profesor(Nombre, apellidos).
• Clave ajena: La pareja (número, título) es clave ajena sobre Publicación (número, título)
• Clave ajena: El atributo Código es clave ajena sobre Línea(Código)
Proyecto (CódigoProyecto, Nombre, Acrónimo, Presupuesto, programa, FechaInicio, Fechafin,
Descripción, Nombre, apellidos)
• Clave ajena: La pareja (nombre,apellidos) es clave ajena sobre Doctor(Nombre, apellidos).
Solo es clave ajena por ser una relación 1:n. Por favor, téngase en cuenta que Doctor es la
entidad que intervenía en la relación Y NO LA ENTIDAD PROFESOR.
Participa (Nombre, apellidos, CodigoProyecto)
• Clave ajena: La pareja (nombre,apellidos) es clave ajena sobre Profesor(Nombre, apellidos).
• Clave ajena: El atributo CódigoProyecto es clave ajena sobre Proyecto(CodigoProyecto)

2.5.2 Transformación del modelo “Ajedrez”
Partida (CódigoPartida, FechaInicio, Duración)
Movimiento (CodigoPartida, Numero, CasillaOrigen, CasillaDestino)
• Clave ajena: CodigoPartida es clave ajena sobre Partida(CodigoPartida)
• Inciso: Según la regla de transformación 1:n, codigo partida debe ser ajena. Sin embargo una
regla anterior nos ha dicho que debe formar parte de la clave primaria.
Federacion(Nombre, Pais)
Jugador (Nombre, apellidos, NumeroDeFederado, DireccionPostal, DireccionElectronica, NombreFederacion)
• NombreFederacion es clave ajena sobre Federacion(Nombre)
Enfrenta
es
una
relación
m:n.
Se
convierte
en
tabla.
frenta(CodigoPartida,Nombre,Ap,Fecha,Vencedor, NombreBlancas, ApBlancas)

En-

• CodigoPartida es ajena sobre Partidas(CodigoPartida)
• La pareja (Nombre, Apellidos) es clave ajena sobre Jugador(Nombre, Apellidos)
• La pareja (NombreBlancas,ApellidoBlancas) es ajena sobre Jugador(Nombre,Apellidos)
2.5. Transformación de modelos E/R en modelos relacionales

23
Bases de datos, Versión 1.1

• A tener en cuenta: esta tabla ilustra que un diseño mejor habría sido tener dos relaciones
como “Se enfrenta con blancas” y “Se enfrenta con negras”. Aún así, habría que programar
Torneo (NombreTorneo, NombreFed, Periodicidad,Cuantia)
• NombreFed es clave ajena sobre Federación(Nombre)
Edición (Numero, NombreTorneo,NombreFed, Nombre,Apellidos)
• La
pareja
(NombreTorneo,NombreFed)
neo(NombreTorneo,NombreFed)

es

clave

ajena

sobre

Tor-

• La pareja (Nombre,Apellidos) es clave ajena sobre Jugador(Nombre,Apellidos)
En este punto debemos reformar la tabla partida y dejarla así
• Partida (CódigoPartida, FechaInicio, Duración, NumeroEdicion, NombreTorneo, NombreFederacion)
◦ El trío (NumEdicion, NombreTorneo, NombreFederacion) es clave ajena sobre Edicion(NumEdicion,NombreTorneo,NombreFederacion)

2.5.3 Transformación del modelo “Fincas”
Resuelto en la pizarra

2.6 Normalización
Cuando se elabora un diseño de tablas, puede ocurrir que aún siga existiendo mucha redundancia.
Al diseñar tablas se debe examinar la redundancia que pueda existir en ellas. Estas redundancias suelen
ser visibles a simple vista: Dado un CP se puede deducir la Población. Estas redundancias adoptan un
nombre muy concreto: “Dependencias funcionales” o tambien “implicaciones”.
A veces, las dependencias funcionales implican varios campos en conjunto. Supongamos una tabla como
esta
Jugador (Nombre,ap, país)
Cuando en una dependencia hay varios atributos se le llama “dependencia funcional completa”.
Para eliminar una dependencia crearemos una tabla separada de la tabla inicial.
En la nueva tabla pondremos estos campos: el implicante y los implicados
La clave de la nueva tabla es el implicante (o los implicantes, si hay varios)
En la tabla vieja se borran todos los implicados y el implicante se convierte en clave ajena sobre
la nueva tabla.
Recordemos un par de conceptos
Clave primaria: es un atributo (o pareja, o trío) que sabemos que no se va a repetir.
Clave candidata: es un atributo (o pareja) que PODRÍA ACTUAR COMO PRIMARIA pero no
lo hemos elegido.
Transitividad: supone que si “A implica B” y “B implica C”, automáticamente sabremos que “A
implica C”.

24

Capítulo 2. Diseño de bases de datos
Bases de datos, Versión 1.1

2.6.1 Primera forma normal (1FN)
Una tabla está en 1FN si en cada atributo se prohíbe insertar más de un valor.

2.6.2 Segunda forma normal (2FN)
Una tabla está en segunda forma normal si todos los campos tienen dependencia completa respecto a la
clave.
Supongamos una base de datos con una tabla como esta
Compras(CodigoProveedor, CodigoProducto, NombreProducto, Cantidad).
En esta tabla es fácil observar que hay una dependencia funcional pero no completa con respecto a la
clave (CodigoProveedorProducto) sino parcial, de la forma “CodigoProducto implica Nombre”.

2.6.3 Tercera forma normal
Una tabla está en 3FN si está en 2FN y además no hay dependencias transitivas.

2.6. Normalización

25
Bases de datos, Versión 1.1

26

Capítulo 2. Diseño de bases de datos
CAPÍTULO 3

Diseño físico

3.1 Introducción
En general hemos seguido un proceso lógico en la creación de bases de datos.
Tema 1: posibilidades
Tema 2: Diseño
• Análisis
• Diseño E/R
• Pasar a un diseño relacional
• Normalización.

3.2 BBDD en Access
3.2.1 Interfaz “Vista de tabla”
Access crea automáticamente un campo llamado ID que actuará como clave primaria. Este campo ID
usará un tipo llamado “Autonumérico”
Dicho campo es un número entero
Se incrementa automáticamente cuando pasamos a otra fila.

3.2.2 Tipos de datos
Access maneja los siguientes tipos de datos
Texto
Acepta letras, números y símbolos pero solo acepta conjuntos de longitud pequeña (255 símbolos máximo)

27
Bases de datos, Versión 1.1

Memo
Acepta textos largos.
Fecha
Permite manejar datos relacionados con las fechas y con sus intervalos.
Numéricos
Se reservan para datos para los cuales se deseen hacer operaciones matemáticas.
Los tipos numéricos pueden concretarse aún más:
Byte: acepta números en el rango 0-255
Enteros cortos: números entre -32767 y 32768
Entero largo: a nivel interno usa 32 bits (-2^32 hasta 2^32)
Decimal: acepta decimales al nivel que le indiquemos
Simple: acepta negativos y decimales de precisión variable
Doble: acepta negativos y decimales muchísimo más grandes y con mucha más precisión decimal
En general la regla es: “cuanto más corto es el campo más rápido se procesa pero menos precisión
nos ofrece”
Sí/No
Reservado para valores lógicos (True/False)

3.2.3 Formato de datos
Se puede controlar la apariencia que tendrán los datos en pantalla, por ejemplo, una fecha puede
mostrarse como 13-2-85 o 13/2/1985
Formato de la fecha
En el formato de la fecha se deben usar tres símbolos básicos para manejar el día, el mes y el año,que
son respectivamente d, m y a
d-m-aa: Escribe algo como “1-3-81”
d-m-aaaa: Escribe algo como “1-3-1981”
d-mmm-aaaa: Escribe algo como “1-Mar-1981”
dd-mmm-aaaa: Escribe la fecha “01-Mar-1981”
dd-mm-aaaa: Escribe la fecha “01-03-1981”
dd/mm/aaaa: Escribe la fecha “01/03/1981”
dd/mmmm/aaaa: Escribe la fecha “01/Marzo/1981”
28

Capítulo 3. Diseño físico
Bases de datos, Versión 1.1

hh:nn:ss dd/mmmm/aaaa: Escribe la fecha “01/Marzo/1981”
Formato de cadenas
El único símbolo de interés es @
@@-@@ Coge los dos primeros símbolos y los separa de los dos segundos por un guión.
“Desde “@@” hacia “@@
Formato de números
Para modificar la presentación de los números se utiliza el símbolo 0.
000,00: “Extraer un número de 3 cifras, si no lo hay se rellena con ceros, y despues extraer dos
decimales. Mostrar eso en pantalla”

3.2.4 Máscaras de entrada
Hemos dicho que el formato cambia la forma de mostrar las cosas en pantalla (pero no cambia como
se almacenan por dentro). Sin embargo a veces es importante intentar evitar que se almacenen datos
incorrectos.
Para indicar a Access las máscaras de entrada, usaremos estos códigos
0: Es obligatorio insertar una cifra en esa posición
L: Es obligatorio insertar una letra en esa posición
9: Es optativo insertar algo, pero si se hace que sea una cifra
?: Es optativo insertar algo, pero si se hace que sea una letra
A: Es obligatorio insertar algo aquí y puede ser una letra o un número.
a: Es optativo insertar algo aquí y puede ser una letra o un número.
Ejercicio: ¿como sería la máscara que permite a la gente insertar su DNI con o sin letra?
Solución: 90000000?
Ejercicio: ¿como sería la máscara de entrada de un campo login que puede tener 3-4 letras seguidas de
4-5 números?
Solución: la solución sería ?LLL00009 (se recomienda dejar los elementos optativos en las “esquinas”).
Ejercicio: ¿como sería la máscara de entrada de un campo password, donde se obliga a que la clave tenga
entre 8 y 12 símbolos que pueden ser letras o números?
Solución: AAAAAAAAaaaa

3.2.5 Título
El título es lo que se mostrará en los formularios. Se puede dejar en blanco.

3.2. BBDD en Access

29
Bases de datos, Versión 1.1

3.2.6 Valor predeterminado
Es un valor que Access puede insertar automáticamente para casos de tablas donde la mayor parte de
registros tienen el mismo valor.

3.2.7 Regla de validación
Es más potente que una máscara de entrada, ya que permite indicar condiciones que los datos deben
cumplir antes de ser insertados

3.2.8 Texto de validación
Es el texto que aparecerá cuando la regla no se cumple.

3.2.9 Requerido
Nos indica si es obligatorio que haya dentro del campo o si por el contrario puede estar vacío.

3.2.10 Indexado
Indica si el campo deberá estar en un índice de la base de datos.
Un índice es un archivo de la base de datos que el programa puede utilizar para hacer búsquedas más
deprisa. No fabricaremos un índice para todos los campos ya que el proceso puede ser lento y ocupar
mucho espacio.
Puede ser la primera y mejor opción cuando los usuarios se quejan de que las búsquedas son lentas.

3.2.11 Compresión Unicode
Permite seguir utilizando un solo byte por símbolo a pesar de que utilicemos Unicode (que utiliza de 2
a 4 bytes por símbolo)

3.2.12 Modo IME
IME significa Input Method Editor, y especifica los diversos sistemas existentes para introducir símbolos. Es relevante solamente en casos como el uso de lenguajes asiáticos y similares.

3.2.13 Oraciones IME
Permite controlar como Access va a procesar las frases en otros idiomas.

3.2.14 Etiquetas inteligentes
Permite que Access procese de una forma especial diversos campos. Para ello debemos saber como
funciona el vocabulario XML de Microsoft

30

Capítulo 3. Diseño físico
Bases de datos, Versión 1.1

3.2.15 Alineación
Controla como aparecerá el texto: alineado a la derecha, a la izquierda, distribuido (justificado).
Los puntos del 11 al 15 no entran en examen.

3.3 Claves ajenas
Access denomina a este concepto “Relaciones”. Para indicar que un campo es clave ajena sobre otro, se
deberá acudir a este menú y arrastrar la clave ajena sobre la primaria.
Se denomina integridad referencial a la capacidad del SGBD de obligar a que los datos de una tabla
existan previamente en otra.
Cuando se conectan campos y la clave ajena es autonumérica se está cometiendo un error, ya que Access
intentaría cambiar los valores sin ceñirse a la clave primaria.
Al crear una clave ajena se pueden hacer cumplir dos condiciones extrar
1. Actualización en cascada: si alguien cambia la clave primaria, el que se marcó como clave ajena
cambiará automáticamente
2. Borrado en cascada: si alguien borra el registro de la clave primaria, los registros asociados en la
clave ajena se borrarán también. No siempre es necesario hacer esto.

3.4 MySQL
3.4.1 Comandos básicos
Mostrar las bases de datos en el servidor: show databases;
Utilizar una BD a partir de un instante dado: use cdcol;
Mostrar las tablas de una base de datos: show tables;
Mostrar las descripciones detalladas de las tablas: desc user;

3.4.2 Creación de bases de datos y tablas
El comando para crear una base de datos: create database <nombre>. Sin embargo la creación de una
tabla es un proceso complejo.
create table publicacion
(
numero int,
titulo char(60)
);
create table <nombre>
(
<campo1> <tipo de datos> ,
<campo2> <tipo de datos> ,
...

3.3. Claves ajenas

31
Bases de datos, Versión 1.1

<campo20> <tipo de datos>
);

3.4.3 Tipos de datos en MySQL
Los tipos pueden ser
Numéricos: pueden ser unsigned o no
• Enteros: no aceptan decimales
◦ TINYINT: -128,+127 O 0-255
◦ SMALLINT: -32768,32767 O 0-65535
◦ INT -2100 millones, 2100 millones o 0-4200 millones
◦ BIGINT: -2^63, 2^63 o 0-2^64
• Decimales: sí aceptan parte fraccionarios
◦ DECIMAL (c, d): la c indica el total de cifras, y la d indica cuantas de ellas serán
decimales. Así, DECIMAL (10,2) nos da un número con 10 cifras en total y dos de
ellas decimales, es decir, que tenemos 8 cifras para la parte entera.
◦ FLOAT: hasta 8 decimales
◦ DOUBLE: hasta 12 decimales
Cadenas
• CHAR(x): la x indica la longitud máxima de la cadena. Reserva el espacio aunque no se
utilice. Son más rápidos de procesar pero gastan más espacio.
• VARCHAR(x): la x indica un máximo que no se puede sobrepasar pero si no se usa ese
máximo el resto del espacio está libre. Son más lentos de procesar pero ahorran espacio.
Fechas
• DATE: almacena fechas en formato ‘aaaa-mm-dd’
• TIME: almacena tiempos en formato ‘hh:mm:ss:fraccion’
• DATETIME: almacena fechas junto con las horas en formato predefinido ‘aa-mm-dd
hh:mm:ss’
• TIMESTAMP: es una marca de tiempo gestionada por el SGBD y no se puede modificar
directamente.
BLOB: Binary Large OBjects.

3.4.4 Claves en MySQL
En MySQL se pueden definir indicaciones de como se va a comportar un campo:
Clave primaria: es un conjunto de campos cuyo valor no se puede repetir. Además, las claves
primarias suponen crear automáticamente un índice.

32

Capítulo 3. Diseño físico
Bases de datos, Versión 1.1

use ... ;
drop table empleado;
create table empleado
(
dni char(10),
nombre varchar(60),
apellidos varchar(120),
primary key (dni)
);

insert into empleado values
(
"5678123W", "Juan", "Ramirez Diaz"
);
insert into empleado values
(
"1234567Z", "Angel", "Sanchez Gomez"
);

insert into empleado values
("5678123W", "Tomas", "Perez Perez");
select * from empleado;

Una alternativa sería utilizar como clave primaria un conjunto de campos
create table empleado
(
dni char(10),
nombre varchar(60),
apellidos varchar(120),
primary key (nombre, apellidos)
);
insert into empleado values
(
"10X", "Juan", "Gomez Gomez"
);
insert into empleado values
(
"10X", "Angel", "Gomez Gomez"
);
insert into empleado values
(
"20Z", "Juan", "Gomez Gomez"
);

Clave ajena
create table empleado
(
dni char(10),

3.4. MySQL

33
Bases de datos, Versión 1.1

nombre varchar(60),
apellidos varchar(120),
primary key (nombre, apellidos)
);
create table sueldos
(
dni char(10),
sueldo decimal(6,2),
primary key (dni),
foreign key (dni) references empleado (dni)
);
insert into sueldos values ("99Q", 950.45);
insert into sueldos values ("1234567Z", 950.45);
insert into sueldos values ("5678123W", 1430.91);

3.4.5 Resolución del modelo de tablas “Universidad”
create table publicacion
(
titulo varchar(100),
numero smallint,
primary key (titulo, numero)
);
create table encongreso
(
titulo varchar(100),
numero smallint,
fechainicio date,
fechafin date,
primary key (titulo, numero),
foreign key (titulo, numero)
references
publicacion (titulo,numero)
);

create table enrevista(
titulo varchar(100),
numero smallint,
nombre varchar(50),
volumen smallint,
editorial varchar(30),
paginainicio smallint,
paginafinal smallint,
primary key (titulo,numero),
foreign key (titulo,numero)
references publicacion(titulo,numero)
);
create table lineas
(
codigolinea smallint unsigned,
nombre varchar(200),

34

Capítulo 3. Diseño físico
Bases de datos, Versión 1.1

primary key (codigolinea)
);
create table descriptor
(
nombre varchar(220),
primary key (nombre)
);
/* Ojo: esta definición estaría mal
porque los tipos de datos no coinciden.
-O codigolinea arriba es un int, o aqui
lo cambiamos para que sea smallint unsigned
-O nombre lo ponemos aqui como varchar(200)
o arriba ponemos varchar(80)*/
create table entraen
(
codigolinea int,
nombredescriptor varchar(80),
primary key (codigolinea, nombredescriptor),
);

create table entraen
(
codigolinea smallint unsigned,
nombredescriptor varchar(220),
primary key (codigolinea, nombredescriptor),
foreign key(codigolinea)
references lineas(codigolinea),
foreign key (nombredescriptor)
references descriptor(nombre)
);
create table cubre
(
numero smallint,
titulo varchar(100),
codigolinea smallint unsigned,
primary key (numero, titulo, codigolinea),
foreign key (titulo, numero)
references publicacion(titulo, numero),
foreign key (codigolinea)
references lineas(codigolinea)
);
create table profesor
(
nombre varchar(80),
apellidos varchar(140),
despacho smallint unsigned,
tlf
varchar(25),
primary key (nombre, apellidos)
);
create table doctor

3.4. MySQL

35
Bases de datos, Versión 1.1

(
nombre varchar(80),
apellidos varchar(140),
primary key (nombre, apellidos),
foreign key (nombre, apellidos)
references profesor(nombre, apellidos)
);
create table nodoctor
(
nombre_nodoctor varchar(80),
apellidos_nodoctor varchar(140),
nombre_doctor varchar(80),
apellidos_doctor varchar(140),
primary key (nombre_nodoctor, apellidos_nodoctor),
foreign key (nombre_nodoctor, apellidos_nodoctor)
references profesor(nombre, apellidos),
foreign key (nombre_doctor, apellidos_doctor)
references doctor(nombre, apellidos)
);
create table produce
(
nombre varchar(80),
apellidos varchar(140),
titulo varchar(100),
numero smallint,
codigo smallint unsigned,
primary key
(nombre, apellidos, titulo, numero, codigo),
foreign key (nombre, apellidos)
references profesor(nombre, apellidos),
foreign key (titulo, numero)
references publicacion(titulo, numero),
foreign key (codigo)
references lineas(codigolinea)
);
create table proyecto
(
codigo int,
nombre varchar(150),
acronimo varchar(15),
primary key (codigo)
);
create table participa
(
nombre varchar(80),
apellidos varchar(140),
codigoproyecto int,
primary key
(nombre,apellidos,codigoproyecto),
foreign key (codigoproyecto)
references proyecto(codigo),
foreign key (nombre,apellidos)
references profesor(nombre,apellidos)

36

Capítulo 3. Diseño físico
Bases de datos, Versión 1.1

);

3.4.6 Resolución del modelo “Ajedrez”
create database ajedrez;
use ajedrez;
create table partida
(
codigo int,
fechainicio date,
duracion_minutos smallint unsigned,
primary key (codigo)
);
create table movimiento
(
codigopartida int,
numero int,
casillaorigen char(2),
casilladestino char(2),
primary key (codigopartida, numero),
foreign key (codigopartida)
references partida(codigo)
);
create index ind_casilla_origen
on movimiento(casillaorigen);
create table federacion
(
nombre varchar(120),
pais varchar(80),
primary key (nombre)
) tablespace ts_disco_lento;
create table jugador
(
nombre varchar(80),
apellidos varchar(140),
email varchar(120),
dir_postal varchar(200),
num_federado int,
nombre_federacion varchar(120),
primary key (nombre,apellidos),
foreign key (nombre_federacion)
references federacion(nombre)
) tablespace ts_disco_lento;

3.5 Tablespaces y undo files
Los “undo files” son archivos utilizados por el SGBD para anotar los hechos que van teniendo lugar
(por ejemplo, al sacar dinero de un cajero). Si algo va mal, el SGBD puede utilizar dichos ficheros para

3.5. Tablespaces y undo files

37
Bases de datos, Versión 1.1

deshacer operaciones por completo.
Para crear un log en la base de datos que se almacene en un archivo “logs” en un directorio cualquiera
podemos hacer lo siguiente. Además, es obligatorio elegir un sistema interno a utilizar al almacenar los
datos. Hoy en día, el “engine” InnoDB es el más actual.
create logfile group logs_ajedrez
add undofile "D:oscarlogs"
engine=innodb;

create tablespace ts_disco_lento
add datafile "d:oscarlento"
use logfile group logs_ajedrez
engine=InnoDB;

38

Capítulo 3. Diseño físico
CAPÍTULO 4

Consultas SQL

4.1 Introducción
Las consultas, las sentencias SELECT se apoyan sobre dos conceptos matemáticos denominados
Algebra relacional
Cálculo relacional

4.2 La sentencia SELECT
La sentencia SELECT permite extraer datos de las tablas en base a condiciones muy diversas.
La operación más básica que podemos hacer es extraer todo lo que hay en una tabla.
select
select
select
select

*
*
*
*

from
from
from
from

proveedores;
partes;
proyectos;
suministra;

4.3 Condiciones
Muy a menudo no necesitaremos mostrar todos los datos de la tabla, sino solo algunos que se especificarán mediante condiciones.
Si por ejemplo, deseáramos mostrar solo los proveedores cuya ciudad sede está en París haríamos algo
como esto.
select * from proveedores
where ciudad="Paris";

Otra posible consulta sería “mostrar todos los proveedores cuyo estado tiene el codigo 10”
select * from proveedores
where estado=10;

39
Bases de datos, Versión 1.1

Las condiciones pueden ser muy complejas, y se pueden construir utilizando los operadores AND y OR.
Por ejemplo, “mostrar todos los proveedores cuya ciudad es Londres y su estado es 10”.
select * from proveedores
where ciudad="Londres"
and estado=10;

Mostrar las partes cuyo peso es mayor de 15.
select * from partes
where peso>19;

No es obligatorio mostrar todos los campos, se pueden mostrar solamente algunos de ellos indicando su
nombre. Por ejemplo, “mostrar el nombre de proveedor y la ciudad de los proveedores cuyo estado sea
20”.
select nombreprov, ciudad
from proveedores
where estado=20;

¿Qué mostrará la siguiente consulta?
select nombreprov
from proveedores
where estado<=10
and
estado>=20;

La respuesta es que no se muestra nada. La condición está mal escrita ya que no puede haber un número
que sea menor de 10 y a la vez mayor de 20.
Mostrar los nombres de proveedores cuyo estado sea 10 y su ciudad Paris o Londres.
Un primer intento sería este .. code-block:: mysql
select nombreprov from proveedores where estado=10 and (ciudad=”Paris” or ciudad=”Londres”);
Sin embargo, no funciona correctamente. La propia pregunta es ambigua
Una posibilidad es que la pregunta fuera así “Mostrar los nombres de proveedores cuyo estado sea
10 y (su ciudad Paris o Londres).”
La otra posibilidad es que la pregunta fuera así “Mostrar los nombres de proveedores cuyo (estado
sea 10 y su ciudad Paris) o Londres.”
Es importante recordar que cuando en una condición hay tres o más elementos de comparación puede
que sea necesario utilizar paréntesis.
Mostrar las partes rojas o verdes que pesen 17 o más.
Esta pregunta debe aclararse antes de resolverse.
Mostrar las partes siempre que pesen 17 o más y que luego cumplan una de estas dos: tener color
rojo o tener color verde.
“Mostrar las partes (rojas o verdes) que pesen 17 o más.”
Mostrar las partes que siendo verdes pesen 17 o más o si no que simplemente sean rojas.

40

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

“Mostrar las partes rojas o (verdes que pesen 17 o más).”
Normalmente, se suele asumir la primera pregunta, que se resuelve así
select * from partes
where peso>=17
and
(color="Rojo" or color="Verde");
select * from partes
where
(color="Rojo" or color="Verde")
and peso>=17;

4.4 Consultas con agregados
Se denomina agregado a alguna función de tipo estadístico aplicada a un subconjunto de los datos de
una tabla.

4.4.1 Recuento
La función COUNT nos dice cuantas filas cumplen una cierta condición. No es obligatorio poner dicha
condición.
select count(*) from partes;

Si deseáramos una condición como por ejemplo “hacer el recuento de partes cuyo color sea Azul”
select count(*) from partes
where color="Azul";

¿Cuantas partes hay que no sean rojas?
select count(*) from partes
where color<>"Rojo";

¿Cuantos proveedores hay cuya ciudad sea Londres?
select count(*)
from proveedores
where ciudad="Londres";

¿Cuantas partes hay que sean rojas y pesen más de 16?
select count(*) from partes
where peso>16
and color="Rojo";

¿Cuantos proyectos hay en Madrid?
select count(*) from proyectos
where ciudad="Madrid";

4.4. Consultas con agregados

41
Bases de datos, Versión 1.1

4.4.2 Promedio
Esta función calcula la media aritmética de las filas que cumplan una cierta condición. Tampoco es
obligatorio poner la condición. La función promedio en SQL es AVG(*)
¿Cual es el peso medio de las partes?
select avg(peso) from partes;

¿Cual es la media de peso de la partes azules?
select avg(peso) from partes
where color="Azul";

4.4.3 Máximos y mínimos
Son operaciones que nos devuelven el valor más grande o más pequeño de entre los que cumplan una
condición.
Estas funciones en SQL son
MAX(campo-numérico)
MIN(campo-numérico)
¿Cual es peso más grande de alguna parte?
select max(peso) from partes;

¿Cual es el peso más pequeño de alguna parte?

4.4.4 Sumas
La operación SUM(campo-numérico) efectúa la suma de ese campo para las filas que cumplan una cierta
condición.
¿Cuantas partes en total ha suministrado el proveedor v1?
select sum(cantidad)
from suministra
where numprov="v1";

¿Cuantas partes ha recibido el proyecto y1?
select sum(cantidad)
from suministra
where numproyecto="y1";

¿Cuantas partes p2 ha suministrado el proveedor v2?
select sum(cantidad)
from suministra
where numparte="p2"
and numprov="v2";

42

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

4.4.5 Múltiples agregados
A veces no se hará una sola operación matemática sino muchas. En ese caso es muy importante indicar
a SQL en base a qué debe hacer los resultados, o lo que es lo mismo como agrupar antes de hacer las
operaciones.
En SQL se indicarán los grupos sobre los cuales se va a hacer cada operación mediante la cláusula
GROUP BY (campo). Además, al hacer un “group by” es obligatorio también seleccionar el campo por
el que se hacen los grupos.
La respuesta a una pregunta como:”¿Cual es la media de peso de las partes por color?”
select avg(peso), color
from partes
group by (color);

¿Cual es la media de los pesos en función del nombre de parte?
select avg(peso), nombreparte
from partes
group by (nombreparte);

¿Cuantos proveedores hay en cada ciudad?
select count(*), ciudad
from proveedores
group by (ciudad);

¿Cual es la media de suministros por cada proveedor?
select avg(cantidad), numprov
from suministra
group by (numprov);

¿Cual es la media de pesos de las piezas rojas o verdes?
select avg(peso), color
from partes
where color="Rojo"
or color="Verde"
group by (color);

4.4.6 Condiciones de los agregados
Los agregados pueden llevar sus propias condiciones:
NO VAN CON EL WHERE
Van por separado utilizando HAVING
El HAVING debe ir despues del GROUP BY
“Mostrar cuantos proveedores hay por ciudad, pero solo cuando haya dos o más”
La primera parte de este ejercicio es igual que el anterior. Sacamos cuantos proveedores hay por ciudad
select count(*), ciudad
from proveedores
group by (ciudad);

4.4. Consultas con agregados

43
Bases de datos, Versión 1.1

Si ahora deseamos mostrar solo aquellos cuyo recuento sea mayor o igual que 2 debemos añadir una
cláusula HAVING como esta
select count(*), ciudad
from proveedores
group by (ciudad)
having count(*)>=2;

El WHERE es una condición que se aplica antes de hacer los cálculos. Sin embargo, si una vez hechos
los cálculos no deseamos mostrarlos todos deberemos utilizar el HAVING.
“Mostrar cuantos tornillos hay en total”
Al hacer esta consulta se pueden cometer varios errores, como por ejemplo este, que muestra todas las
partes
select count(*), nombreparte from partes
group by nombreparte;

Esto no es exactamente un error, sino más bien una trampa: se hizo el recuento a mano y se hizo trampa
Error: En este caso se ha confundido el where con el having
select count(*), nombreparte from partes
group by nombreparte having nombreparte="Tornillo";

Pregunta: ¿Podríamos quitar el group by? Respuesta: aunque en este caso sí podríamos no se debe hacer.
Cuando nos pidan una operación matemática por grupos, debemos poner group by
select count(*), nombreparte from partes
where nombreparte="Tornillo"
group by nombreparte

4.5 Consultas multitabla
En ocasiones la información que nos pidan puede que esté dispersa por distintas tablas. SQL ofrece un
mecanismo para “conectar” tablas y así poder hacer las comparaciones que nos pidan.
Por ejemplo, si nos piden el nombre de las partes suministradas en una cantidad >=500 descubriremos
que
El nombreparte está en la tabla partes
La cantidad esta en la tabla suministra
Las tablas partes y suministra tienen un campo en común, el campo numparte
Utilizando una cláusula denominada “inner join” SQL puede establecer las correspondencias correctas
entre dos o más tablas.
Cruce de datos entre las tablas partes y suministra basándonos en que el campo numparte de suministra
debe ser igual que el numparte de suministra
De aqui sacamos solamente los campos que nos piden

44

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

4.6 Algunos ejercicios resueltos
1. Deseamos saber los numeros de proveedor que realizan suministros
select numprov from suministra;

2. Deseamos saber los numeros de proveedor que realizan suministros pero sin que se muestren
repetidos
select distinct numprov from suministra;

3. Sumar las cantidades que se han suministrado (¿cuantas piezas se han suministrado?)
select sum(cantidad) from suministra;

4. Se desea ver la suma de las distintas cantidades de partes suministradas
select sum(cantidad),numparte from suministra
group by numparte;

5. Se desea saber las cantidades totales que ha suministrado cada proveedor
select sum(cantidad),numprov from suministra
group by numprov;

6. Cantidades totales suministradas por v1 y v4
select sum(cantidad), numprov from suministra
where numprov=’v1’ or numprov=’v4’
group by (numprov);

7. Mostrar los numeros de parte suministrados en una cantidad total mayor o igual que 1000
select sum(cantidad), numparte
from suministra
group by (numparte)
having sum(cantidad)>=1000;

8. Mostrar la suma de las partes suministradas por v1, v2, o v3 en una cantidad mayor de 550
select sum(cantidad),numparte
from suministra
where numprov=’v1’ or numprov=’v2’ or numprov=’v3’
group by (numparte)
having sum(cantidad)>550;

9. Mostrar cuantos proveedores hay en Londres
select count(*) from proveedores
where ciudad=’Londres’;

10. ¿Cuantas partes rojas hay?
select count(*) from partes
where color="Rojo";

11. ¿Qué colores están repetidos en las partes?

4.6. Algunos ejercicios resueltos

45
Bases de datos, Versión 1.1

select count(*),color from partes
group by color
having count(*)>=2;

4.7 Subconsultas
Al hacer consultas hemos observado que hay cláusulas que permiten establecer condiciones.
Al hacer las condiciones es posible que necesitemos hacer una “subpregunta” y que la sentencia SELECT quede algo así
select ....
from ...
where campo>(select max(cantidad) from suministra)

Supongamos una pregunta como la siguiente: “¿Cuales son los nombres de parte que pesan lo mismo
que la parte más pesada?”
Podemos sacar el peso maximo con esta consulta
select max(peso) from partes;
select nombreparte from partes
where peso>=(select max(peso) from partes);

¿Qué nombres de parte pesan más que la media?
Se saca la media
select avg(peso) from partes;
select *
from partes
where peso>=(select avg(peso) from partes);

Dentro de las subconsultas, aparte de las comparaciones típicas como >, >=, <>, <=, <, etc... existen
otros elementos para hacer comparaciones
EXISTS: nos dará las filas donde exista alguna fila que cumpla la condición
ALL: la condición deben cumplirla todas las filas
12. ¿Qué nombres de parte corresponden a una pieza azul o almacenada en París?
select nombreparte from partes
where color="Azul" or ciudad="Paris"

13. ¿Qué colores tienen las distintas partes que no sean tornillos?
select * from partes
where nombreparte<>"Tornillo";

14. ¿Cuantos proveedores hay que no tengan su almacén en Atenas?
select count(*) from proveedores
where ciudad<>"Atenas";

15. ¿Qué nombres de parte se suministran en una cantidad mayor o igual de 400?

46

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

select nombreparte,cantidad
from partes inner join suministra
on partes.numparte=suministra.numparte
where cantidad>=400;

16. ¿Qué proveedores suministran partes en una cantidad <300?
Por un lado, el nombre de proveedor está en la tabla proveedores, que podemos ver haciendo esta consulta
select * from proveedores;

numprov
v1
v2
v3
v4
v5

nombreprov
Smith
Jones
Blake
Clarke
Adams

estado
20
10
30
20
30

ciudad
Londres
Paris
Paris
Londres
Atenas

Sin embargo, las cantidades de suministro están en la tabla suministra que podemos ver ejecutando esta
consulta
select * from suministra;

numprov
v1
v1
v2
v2
v2
v2
v2
v2
v2
v2
v3
v3
v4
v4
v5
v5
v5
v5
v5
v5
v5
v5
v5

numparte
p1
p1
p3
p3
p3
p3
p3
p3
p3
p5
p3
p4
p6
p6
p1
p2
p2
p3
p4
p5
p5
p6
p6

numproyecto
y1
y4
y1
y2
y3
y4
y5
y6
y7
y2
y1
y2
y3
y7
y4
y2
y4
y4
y4
y4
y5
y2
y4

cantidad
200
700
400
200
300
500
600
400
600
100
200
500
300
300
100
200
100
200
800
400
500
200
500

Como la información está dispersada, necesitamos cruzar las tablas con un inner join teniendo en cuenta
que tienen un campo igual, en este caso el campo numprov. Podemos “hacer el cruce” haciendo un inner
join con esta consulta
select * from proveedores inner join suministra
on proveedores.numprov=suministra.numprov;

4.7. Subconsultas

47
Bases de datos, Versión 1.1

Cuyo resultado es que se cruzan los datos correctamente y se obtiene una tabla como esta
numprov
v1
v1
v2
v2
v2
v2
v2
v2
v2
v2
v3
v3
v4
v4
v5
v5
v5
v5
v5
v5
v5
v5
v5

numparte
p1
p1
p3
p3
p3
p3
p3
p3
p3
p5
p3
p4
p6
p6
p1
p2
p2
p3
p4
p5
p5
p6
p6

numproyecto
y1
y4
y1
y2
y3
y4
y5
y6
y7
y2
y1
y2
y3
y7
y4
y2
y4
y4
y4
y4
y5
y2
y4

cantidad
200
700
400
200
300
500
600
400
600
100
200
500
300
300
100
200
100
200
800
400
500
200
500

numprov
v1
v1
v2
v2
v2
v2
v2
v2
v2
v2
v3
v3
v4
v4
v5
v5
v5
v5
v5
v5
v5
v5
v5

nombreprov
Smith
Smith
Jones
Jones
Jones
Jones
Jones
Jones
Jones
Jones
Blake
Blake
Clarke
Clarke
Adams
Adams
Adams
Adams
Adams
Adams
Adams
Adams
Adams

estado
20
20
10
10
10
10
10
10
10
10
30
30
20
20
30
30
30
30
30
30
30
30
30

Si ponemos la condición que nos falta el ejercicio se resuelve correctamente
select nombreprov,cantidad
from proveedores inner join suministra
on proveedores.numprov=suministra.numprov
where cantidad<300
order by nombreprov desc;

17. ¿Cuantos proveedores suministran partes en una cantidad <300?
Para orientarnos, extraemos las filas en
las que la cantidad es menor de 300
select numprov from suministra where cantidad<300;
Si hacemos el recuento, observaremos que hay
9 filas, pero proveedores reales solo están v1, v2, v3 y v5.
select count(numprov)
from suministra
where cantidad<300;
Si ponemos distinct, no nos repetirá los proveedores
select distinct numprov
from suministra
where cantidad<300;
Por tanto la solución pasa por hacer el recuento

48

Capítulo 4. Consultas SQL

ciudad
Londres
Londres
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Londres
Londres
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Bases de datos, Versión 1.1

de los distintos numprov
select count(distinct numprov)
from suministra
where cantidad<300;

18. ¿Qué nombre tienen las partes suministradas en una cantidad total de 550 o más?
select sum(cantidad), partes.numparte,nombreparte
from suministra
inner join partes
on suministra.numparte=partes.numparte
group by (partes.numparte)
having sum(cantidad)>=550;

19. ¿Qué nombres de parte suministran los distintos proveedores?
select nombreprov, nombreparte
from proveedores inner join suministra
on suministra.numprov=proveedores.numprov
inner join partes
on partes.numparte=suministra.numparte;

20. Queremos saber los proveedores que están ubicados en el mismo sitio que alguna parte.
Examinemos la tabla partes
numparte
p1
p2
p3
p4
p5
p6

nombreparte
Tuerca
Perno
Tornillo
Tornillo
Leva
Engranaje

color
Rojo
Verde
Azul
Rojo
Azul
Rojo

peso
12
17
17
14
12
19

ciudad
Londres
Paris
Roma
Londres
Paris
Londres

Examinemos la tabla proveedores
numprov
v1
v2
v3
v4
v5

nombreprov
Smith
Jones
Blake
Clarke
Adams

estado
20
10
30
20
30

ciudad
Londres
Paris
Paris
Londres
Atenas

Se puede comprobar que no nos piden para nada datos de la tabla suministra. Lo único que se necesita
es emparejar las filas donde las ciudades sean iguales.
select nombreprov,nombreparte,partes.ciudad
from partes
inner join proveedores
on partes.ciudad=proveedores.ciudad;

21. ¿Como se llaman las piezas que se suministran en la cantidad máxima?
select nombreparte,max(cantidad) from suministra
inner join partes
on suministra.numparte=partes.numparte
where cantidad=(select max(cantidad) from suministra);

4.7. Subconsultas

49
Bases de datos, Versión 1.1

22. ¿Que numeros de proveedores suministran por encima de la media de suministros?
select numprov, cantidad
from suministra
where cantidad >
(
select avg(cantidad) from suministra
);
Cuidado: si nos dijeran "suministran una cantidad
total que esté por encima de la media", deberíamos
sumar las cantidades por proveedor y compararlas con la media.
select sum(cantidad), numprov
from suministra
group by numprov
having sum(cantidad)>
(
select avg(cantidad) from suministra
);

23. Números de parte suministradas en una cantidad media mayor de 450
select avg(cantidad),numparte
from suministra
group by numparte
having avg(cantidad)>450;

24. ¿Cual es el peso medio de las partes?
select avg(peso) from partes;

25. Obtener el nombre de los provedores, el nombre de parte que suministran y la cantidad en que
suministran
select nombreprov, nombreparte,cantidad
from proveedores
inner join suministra
on
suministra.numprov=proveedores.numprov
inner join partes
on
suministra.numparte=partes.numparte

26. Obtener las parejas de proveedores que NO están en la misma ciudad
select
prov1.numprov, prov1.ciudad,
prov2.numprov, prov2.ciudad
from proveedores as prov1
inner join proveedores as prov2
where prov1.ciudad<>prov2.ciudad;

27. Mostrar suministros donde el proveedor y la parte hayan resultado ser de una ciudad distinta
select suministra.numprov, suministra.numparte,
proveedores.ciudad, partes.ciudad
from suministra
inner join proveedores

50

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

on proveedores.numprov=suministra.numprov
inner join partes
on partes.numparte=suministra.numparte
where
proveedores.ciudad<>partes.ciudad;

28. ¿Cuantos proveedores suministran partes rojas o que pesen 12 gramos o más?
Trozo 1: partes rojas
select numparte from partes where color="Rojo"

Trozo 2: partes que pesan 12 o mas
select numparte from partes where peso>12;

Partes que cumplen alguna de las dos cosas
Los proveedores que hacen suministros están en el campo numprov de la tabla suministra
select numprov from suministra;

29. ¿Cuantas piezas se han suministrado de cada ciudad de piezas?
select sum(cantidad),ciudad from partes
inner join suministra
on suministra.numparte=partes.numparte
group by (ciudad);

30. ¿De qué ciudad de proveedor ha salido la cantidad más grande de suministros?.
Esta pregunta podría entenderse de dos formas “Obtener la cantidad más grande suministrada y la ciudad
del proveedor correspondiente”
En primer lugar necesitamos cruzar “proveedores” y suministra

4.7. Subconsultas

51
Bases de datos, Versión 1.1

v1
v1
v2
v2
v2
v2
v2
v2
v2
v2
v3
v3
v4
v4
v5
v5
v5
v5
v5
v5
v5
v5
v5

p1
p1
p3
p3
p3
p3
p3
p3
p3
p5
p3
p4
p6
p6
p1
p2
p2
p3
p4
p5
p5
p6
p6

y1
y4
y1
y2
y3
y4
y5
y6
y7
y2
y1
y2
y3
y7
y4
y2
y4
y4
y4
y4
y5
y2
y4

200
700
400
200
300
500
600
400
600
100
200
500
300
300
100
200
100
200
800
400
500
200
500

v1
v1
v2
v2
v2
v2
v2
v2
v2
v2
v3
v3
v4
v4
v5
v5
v5
v5
v5
v5
v5
v5
v5

Smith
Smith
Jones
Jones
Jones
Jones
Jones
Jones
Jones
Jones
Blake
Blake
Clarke
Clarke
Adams
Adams
Adams
Adams
Adams
Adams
Adams
Adams
Adams

20
20
10
10
10
10
10
10
10
10
30
30
20
20
30
30
30
30
30
30
30
30
30

Londres
Londres
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Londres
Londres
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas

Una primera aproximación sería esta consulta
select max(cantidad),ciudad from
suministra inner join proveedores
on
suministra.numprov=proveedores.numprov;

Sin embargo esto no funciona porque cualquier operación de agregado no involucra a ninguna fila. De
hecho esa consulta nos devuelve un máximo correcto pero no nos devuelve la ciudad asociada, sino la
primera que encuentra.
Hay que encontrar otra forma de expresar esta consulta
select ciudad
from proveedores inner join suministra
on
suministra.numprov=proveedores.numprov
where cantidad=
(
select max(cantidad) from suministra
);

La otra forma de entender la pregunta sería
“Sumar las cantidades por proveedor y decir la ciudad del proveedor con la cantidad máxima”
Una primera aproximación sería esta
select ciudad from
suministra inner join proveedores
on
suministra.numprov=proveedores.numprov
group by (proveedores.numprov)

52

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

having sum(cantidad)>=
ALL
(
select sum(cantidad)
from suministra
group by (numprov)
)
;

31. ¿Qué ciudad de parte tiene la mayor media de suministros?
Cruzamos suministra y partes
select * from suministra
inner join partes
on
suministra.numparte=partes.numparte

Por otra lado, sacamos la media por partes de la tabla suministra
select avg(cantidad) from suministra
group by numparte;

Si mezclamos la primera parte con la segunda
select ciudad from suministra
inner join partes
on
suministra.numparte=partes.numparte
group by partes.numparte
having avg(cantidad)>=
ALL
(
select avg(cantidad) from suministra
group by numparte
);

32.Obtener todos los detalles de todos los proyectos
select nombreprov, nombreparte,nombreproyecto,cantidad
from suministra
inner join proyectos
on
suministra.numproyecto=proyectos.numproyecto
inner join partes
on
suministra.numparte=partes.numparte
inner join proveedores
on
suministra.numprov=proveedores.numprov
;

33. Obtener todos los detalles de todos los proyectos ubicados en Londres.
select nombreprov, nombreparte,nombreproyecto,cantidad
from suministra
inner join proyectos
on
suministra.numproyecto=proyectos.numproyecto

4.7. Subconsultas

53
Bases de datos, Versión 1.1

inner join partes
on
suministra.numparte=partes.numparte
inner join proveedores
on
suministra.numprov=proveedores.numprov
where proyectos.ciudad="Londres"
;

34. Obtener los códigos de proveedor que suministran al proyecto Y1.
select numprov from suministra
where numproyecto=’y1’;

35. Obtener los datos de los proyectos que usan partes en cantidades comprendidas entre 300 y 750.
select distinct proyectos.*
from suministra
inner join proyectos
on
suministra.numproyecto=proyectos.numproyecto
where
( cantidad>=300 ) and ( cantidad<=750 )
order by proyectos.numproyecto
;

36. Obtener las combinaciones posibles parte-color
Este ejercicio requiere tener dos copias de la misma tabla. Será necesario utilizar los alias para combinar la tabla partes consigo misma.
select distinct p1.nombreparte, p2.color
from partes as p1
inner join
partes as p2;

37. Obtener los colores de las partes que se han suministrado por V1.
select partes.color from suministra
inner join
partes
on partes.numparte=suministra.numparte
where numprov=’v1’;

38. Obtener la cantidad total de partes P1 usadas por parte de V1.
Datos del proveedor v1
select * from suministra
where numprov=’v1’;

Suma de todas las partes de v1
select sum(cantidad)
from suministra
where
numprov=’v1’
and
numparte=’p1’;

54

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

39. Obtener las parejas de nombres de ciudad tales que un proveedor ubicado en la primera ciudad
suministra a algún proyecto ubicado en la segunda ciudad.
select proveedores.ciudad, proyectos.ciudad
from suministra
inner join proveedores
on
suministra.numprov=proveedores.numprov
inner join proyectos
on
suministra.numproyecto=proyectos.numproyecto;

40. Obtener los códigos de parte suministrados a los proyectos ubicados en la misma ciudad del
proveedor.
select suministra.numparte
from suministra
inner join proyectos
on
suministra.numproyecto=proyectos.numproyecto
inner join proveedores
on
suministra.numprov=proveedores.numprov
where
proveedores.ciudad=proyectos.ciudad;

41. Obtener los códigos de proyecto a los que suministra un proveedor que no está en la misma ciudad.
select suministra.numproyecto
from suministra
inner join proveedores
on
proveedores.numprov=suministra.numprov
inner join proyectos
on
proyectos.numproyecto=suministra.numproyecto
where
proyectos.ciudad<>proveedores.ciudad;

42. Obtener las parejas de partes suministradas por el mismo proveedor.
select distinct s1.numparte,s2.numparte
from suministra as s1
inner join suministra as s2
on
s1.numprov=s2.numprov;

43. Obtener los códigos de parte suministrados a cualquier proyecto que esté ubicado en Londres
select numparte from suministra
inner join proyectos
on
suministra.numproyecto=proyectos.numproyecto
where
proyectos.ciudad="Londres";

44. Obtener los códigos de proyecto que usan al menos una parte suministrada por el proveedor V1

4.7. Subconsultas

55
Bases de datos, Versión 1.1

En primer lugar seleccionamos las partes suministradas por v1
select numparte from suministra
where numprov=’v1’;

En segundo lugar queremos saber los proyectos cuyas partes sean alguna de las que hemos extraído
antes.
select numproyecto from suministra
where numparte in
(
select numparte from suministra
where numprov=’v1’
);

45. Obtener los códigos de proveedor que suministran al menos una parte roja.
Seleccionamos las partes cuyo color es rojo
select numparte from partes where color="Rojo";

Ahora, en la tabla suministra sacamos las filas donde la parte sea alguna de las extraídas antes
select numprov from suministra
where numparte in
(
select numparte from partes
where color="Rojo"
);

Una solución distinta
select numprov from suministra
inner join partes
on suministra.numparte=partes.numparte
where partes.color="Rojo";

46. Obtener los códigos de proyecto cuya ciudad es la primera en la lista de ciudades.
Seleccionamos la ciudad más pequeña
select min(ciudad) from proyectos;
select * from proyectos
where ciudad in
(
select min(ciudad) from proyectos
);

Otra forma de hacerlo con inner join’s sería la siguiente
select p1.numproyecto,p1.ciudad from proyectos as p1
inner join proyectos as p2
on
p1.numproyecto=p2.numproyecto
where p1.ciudad=
(
select min(ciudad) from proyectos
);

56

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

47. Obtener los códigos de proyecto a los que se suministra la parte P1 en una cantidad promedio
igual o superior a la cantidad más grande que se suministra al proyecto Y1.
Extraemos la cantidad más grande del proyecto “y1”
select max(cantidad) from suministra
where numproyecto="y1";

Al haber una condición para el promedio deberemos poner algo como esto
select numproyecto,avg(cantidad) from suministra
where numparte=’p1’
group by numproyecto
having avg(cantidad)>=
(
select max(cantidad) from suministra
where numproyecto="y1"
);

48. Obtener los códigos de proveedor de los que suministran la parte P1 a algún proyecto en una
cantidad superior a la cantidad promedio de la parte P1 para ese proyecto.
Podemos empezar intentando sacar la media de partes p1 para cada proyecto
select numproyecto, avg(cantidad) from suministra
where numparte=’p1’
group by numproyecto;

Extraemos las filas de la tabla suministra donde la parte sea p1
select numprov from suministra as s1
where numparte=’p1’
and cantidad >
(
select avg(cantidad) from suministra as s2
where numparte=’p1’
and
s2.numproyecto=s1.numproyecto
group by numproyecto
);

49. Obtener los códigos de proyecto a los que ningún proveedor de Londres suministra una parte roja.
Primero averiguamos los proveedores de Londres que suministran partes rojas.
select suministra.numprov
from suministra
inner join partes
on partes.numparte=suministra.numparte
inner join proveedores
on proveedores.numprov=suministra.numprov
where
proveedores.ciudad="Londres"
and
partes.color="Rojo";

Ahora examinamos la tabla suministra y comprobamos que el proveedor no esté en el conjunto devuelto
por la consulta anterior

4.7. Subconsultas

57
Bases de datos, Versión 1.1

select * from suministra
where numprov
not in
(
select suministra.numprov
from suministra
inner join partes
on partes.numparte=suministra.numparte
inner join proveedores
on proveedores.numprov=suministra.numprov
where
proveedores.ciudad="Londres"
and
partes.color="Rojo"
);

50. ¿Hay algún proveedor que suministre la misma parte a TODOS los proyectos?
Para conseguir la solución a este problema se deben utilizar algunas características de los cuantificadores.
Replanteamos la pregunta
“se desea saber los proveedores donde para todos los proyectos existe una misma parte suministrada”
o más desarrollado
“proveedores (de la tabla suministra) donde para todo proyecto (de la tabla proyectos) existe un suministro donde el codigo de proveedor es dicho proveedor y la parte es la misma parte que mirábamos en
suministra”
select numprov from suministra as s1
where not exists
(
select numproyecto from proyectos
where numproyecto not in
(
select numproyecto from suministra as s2
where
s1.numparte=s2.numparte
and
s1.numprov=s2.numprov
)

);

51. Obtener los códigos de proyecto que usan todas las partes suministradas por el proveedor v1
“Obtener los códigos de proyecto donde para toda parte de la tabla suministra existe una parte suministrada por v1”
Obtener el conjunto de parte suministradas por v1.
select numparte from suministra
where numprov=’v1’;

Las filas de la tabla suministra donde para toda parte de v1 existe alguna fila asociada

58

Capítulo 4. Consultas SQL
Bases de datos, Versión 1.1

select numprov from suministra as s1
where not exists
(
select numparte from suministra as s2
where numprov=’v1’
and not exists
(
select numparte,numproyecto
from suministra as s3
where
s2.numparte=s3.numparte
and s1.numproyecto=s3.numproyecto
)
);

52. (Para nota) Obtener los pares de proveedores V1 y V2 que suministren EXACTAMENTE el mismo conjunto de partes.
La pregunta podría replantearse como
“obtener parejas de proveedores donde para toda parte de un proveedor de la primera tabla existe otro
proveedor distinto tal que la parte es la misma que la parte del primero”.

4.8 Actualización y borrado
Una vez que se han insertado datos, estos no son inmutables. Pueden cambiarse valores de las filas o
incluso pueden borrarse las filas.
Estas operaciones se hacen con las sentencias UPDATE y DELETE.
Para cambiar valores se hace lo siguiente
UPDATE <TABLA> SET <CAMPO>=VALOR WHERE <CONDICION>
Por ejemplo, si quisiéramos hacer que en la tabla partes se cambiara la ciudad Londres por Madrid
haríamos algo como esto
UPDATE partes SET ciudad="Madrid"
WHERE ciudad="Londres";

Poner en la tabla partes el peso a 30 en todas las partes cuyo peso sea mayor que 16;
update partes set peso=30
where peso>16;

Poner a “Amarillo” el color de las partes de Paris
update partes set color="Amarillo"
where ciudad="Paris";

Para borrar datos
DELETE FROM <TABLA> WHERE <CONDICION>
Borrar todas las partes cuyo peso es 12
delete from partes where peso=12;

4.8. Actualización y borrado

59
Bases de datos, Versión 1.1

60

Capítulo 4. Consultas SQL
CAPÍTULO 5

Programación

5.1 Introducción
Los elementos de los lenguajes de programación son muy similares entre sí y el cambio de lenguaje
solamente supone la modificación de ciertos hábitos.
En el entorno de las bases de datos se pueden encontrar programas que actúen mediante dos mecanismos
distintos. Estos dos mecanismos se definen como
Procedimientos almacenados: residen en el propio servidor de bases de datos.
Programas externos: utilizando algún mecanismo los programas externos se comunican con el
servidor para intercambiar datos mediante un lenguaje de programación cualquiera.
Entre los mecanismos de comunicación más utilizados encontramos ODBC (Open DataBases Communication). Este estándar especifica claramente a servidores y cliente como tienen que dar o pedir datos.
Una versión modificada de ODBC es JDBC que ha modernizado el estándar pero solo sirve para programas Java.

5.2 Procedimientos almacenados
5.2.1 Carga de programas
Para cargar código almacenado en un fichero SQL externo se utiliza lo siguiente
. d:oscart5prueba1.sql

5.2.2 Variables
Una variable es una posición de memoria con nombre. Normalmente las variables conllevan un tipo que
restringe lo que podemos almacenar en ella.
En MySQL las variables se declaran con la palabra clave DECLARE.
Los tipos utilizables con las variables son los mismos que tiene MySQL.

61
Bases de datos, Versión 1.1

5.2.3 Declaración de procedimientos
Los procedimientos en MySQL actúan igual que las funciones en Java con las diferencias en la sintaxis.
El primer problema que aparece en los procedimientos MySQL viene dado por el hecho de que los
procedimientos a veces interfieren con el delimitador ”;”. Para evitarlo, debemos avisar a MySQL de
que durante un tiempo cambiaremos de delimitador, para ello se usa la siguiente sentencia
Dentro de “código” podrán ir sentencias que terminarán de forma normal, con el punto y coma ”;”
El problema viene dado porque el intérprete de MySQL intenta procesar todo lo que haya hasta llegar
a un punto y coma. Si no cambiásemos el delimitador, se ejecutaría la definición del procedimiento sin
haber encontrado un “end” y todo fallaría.
Ejercicio: crear un procedimiento que acepte una cantidad c y que seleccione todos los suministros cuyo
campo cantidad sea mayor que c
delimiter //

create procedure mayores (cant int)
begin
select * from suministra
where cantidad>cant;
end
//
delimiter ;

Ejercicio: crear un programa que acepte un color co y una ciudad ci y que busque todas las partes cuyo
color sea ese co pasado y la ciudad ese ci pasado. Co y ci son parámetros y NO LLEVAN COMILLAS
delimiter //
create procedure Color_parte
(color_pasado varchar(20),
ciudad_pasada varchar(20) )
begin
select * from partes
where color=color_pasado
and
ciudad=ciudad_pasada;
end
//
delimiter ;

Ejercicio: crear un procedimiento que permita sumar la cantidad de partes suministradas cuyo color sea
el mismo que un cierto color pasado
drop procedure suministradas_color;
delimiter //
create procedure suministradas_color
( color_pasado varchar(20) )
begin
select sum(cantidad)

62

Capítulo 5. Programación
Bases de datos, Versión 1.1

from suministra
inner join partes
on
suministra.numparte=partes.numparte
where color=color_pasado;
end
//

delimiter ;
call suministradas_color("Rojo");
call suministradas_color("Gris");

Ejercicio: crear un procedimiento que reciba dos cosas
Color_pasado
Nombre_prov_pasado
El procedimiento deberá decirnos cuantas partes de ese color suministra ese nombre de proveedor.
Ejercicio: crear un procedimiento que reciba dos cosas
Nombre_parte_pasada
Cantidad_pasada
El procedimiento deberá decirnos cuantas partes con ese nombre han sido suministradas en una cantidad
mayor o igual que la cantidad pasada
drop procedure mayores_que;
delimiter //
create procedure mayores_que(
nombre_parte_pasada varchar(11),
cantidad_pasada int)
begin
select * from suministra inner join partes
on suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and
cantidad>cantidad_pasada;
end
//
delimiter ;

5.3 Sentencias básicas
5.3.1 Decisiones con IF
La sintaxis de un IF es prácticamente igual a la de Java

5.3. Sentencias básicas

63
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd
Bbdd

Más contenido relacionado

La actualidad más candente

Bases de datos distribuidas heterogéneas
Bases de datos distribuidas heterogéneasBases de datos distribuidas heterogéneas
Bases de datos distribuidas heterogéneasJuan Anaya
 
Solucion bd (1)
Solucion bd (1)Solucion bd (1)
Solucion bd (1)calamilla
 
Tipos de atributos y tipos de relaciones
Tipos de atributos y tipos de relacionesTipos de atributos y tipos de relaciones
Tipos de atributos y tipos de relacionesbasilioj
 
Programacion orientada a objetos - unidad 3 herencia
Programacion orientada a objetos - unidad 3 herenciaProgramacion orientada a objetos - unidad 3 herencia
Programacion orientada a objetos - unidad 3 herenciaJosé Antonio Sandoval Acosta
 
Diagrama de clases
Diagrama de clasesDiagrama de clases
Diagrama de clasesjmachado614
 
Analisis de la independencia logica fisica de datos en un sistema de bases de...
Analisis de la independencia logica fisica de datos en un sistema de bases de...Analisis de la independencia logica fisica de datos en un sistema de bases de...
Analisis de la independencia logica fisica de datos en un sistema de bases de...Maria Garcia
 
Herencia - Programación Orientada a Objetos
Herencia - Programación Orientada a ObjetosHerencia - Programación Orientada a Objetos
Herencia - Programación Orientada a ObjetosMario Villaseñor
 
Programación Orientada a Objetos - constructores y destructores
Programación Orientada a Objetos - constructores y destructoresProgramación Orientada a Objetos - constructores y destructores
Programación Orientada a Objetos - constructores y destructoresAlvaro Enrique Ruano
 
Preparando el entorno de la base de datos Oracle 11g Administration I-Z052-03
Preparando el entorno de la base de datos Oracle 11g Administration I-Z052-03Preparando el entorno de la base de datos Oracle 11g Administration I-Z052-03
Preparando el entorno de la base de datos Oracle 11g Administration I-Z052-03Alexander Calderón
 
Aplicando Uwe - Un ejemplo didactico
Aplicando Uwe - Un ejemplo didacticoAplicando Uwe - Un ejemplo didactico
Aplicando Uwe - Un ejemplo didacticomillernegro
 
2...2 expresiones regulares, cerradura, fractales, automata
2...2 expresiones regulares, cerradura, fractales, automata2...2 expresiones regulares, cerradura, fractales, automata
2...2 expresiones regulares, cerradura, fractales, automataJacqui Venegas
 
Codigo para crear la base de datos
Codigo para crear la base de datosCodigo para crear la base de datos
Codigo para crear la base de datosAlvaro Cardona
 
Ejemplo de uno a uno
Ejemplo de uno a unoEjemplo de uno a uno
Ejemplo de uno a unorafita07zr
 

La actualidad más candente (20)

Bases de datos distribuidas heterogéneas
Bases de datos distribuidas heterogéneasBases de datos distribuidas heterogéneas
Bases de datos distribuidas heterogéneas
 
Solucion bd (1)
Solucion bd (1)Solucion bd (1)
Solucion bd (1)
 
Transacciones
TransaccionesTransacciones
Transacciones
 
Tipos de atributos y tipos de relaciones
Tipos de atributos y tipos de relacionesTipos de atributos y tipos de relaciones
Tipos de atributos y tipos de relaciones
 
Uml a java
Uml a javaUml a java
Uml a java
 
Programacion orientada a objetos - unidad 3 herencia
Programacion orientada a objetos - unidad 3 herenciaProgramacion orientada a objetos - unidad 3 herencia
Programacion orientada a objetos - unidad 3 herencia
 
Diagrama de clases
Diagrama de clasesDiagrama de clases
Diagrama de clases
 
Analisis de la independencia logica fisica de datos en un sistema de bases de...
Analisis de la independencia logica fisica de datos en un sistema de bases de...Analisis de la independencia logica fisica de datos en un sistema de bases de...
Analisis de la independencia logica fisica de datos en un sistema de bases de...
 
Herencia - Programación Orientada a Objetos
Herencia - Programación Orientada a ObjetosHerencia - Programación Orientada a Objetos
Herencia - Programación Orientada a Objetos
 
Programación Orientada a Objetos - constructores y destructores
Programación Orientada a Objetos - constructores y destructoresProgramación Orientada a Objetos - constructores y destructores
Programación Orientada a Objetos - constructores y destructores
 
Preparando el entorno de la base de datos Oracle 11g Administration I-Z052-03
Preparando el entorno de la base de datos Oracle 11g Administration I-Z052-03Preparando el entorno de la base de datos Oracle 11g Administration I-Z052-03
Preparando el entorno de la base de datos Oracle 11g Administration I-Z052-03
 
Complejidad de algoritmos
Complejidad de algoritmos Complejidad de algoritmos
Complejidad de algoritmos
 
Aplicando Uwe - Un ejemplo didactico
Aplicando Uwe - Un ejemplo didacticoAplicando Uwe - Un ejemplo didactico
Aplicando Uwe - Un ejemplo didactico
 
Segmentacion de memoria
Segmentacion de memoriaSegmentacion de memoria
Segmentacion de memoria
 
2...2 expresiones regulares, cerradura, fractales, automata
2...2 expresiones regulares, cerradura, fractales, automata2...2 expresiones regulares, cerradura, fractales, automata
2...2 expresiones regulares, cerradura, fractales, automata
 
Greenfoot 1
Greenfoot 1Greenfoot 1
Greenfoot 1
 
Codigo para crear la base de datos
Codigo para crear la base de datosCodigo para crear la base de datos
Codigo para crear la base de datos
 
Java Threads (Hilos en Java)
Java Threads (Hilos en Java)Java Threads (Hilos en Java)
Java Threads (Hilos en Java)
 
Computo movil ejercicio clases resuelto
Computo movil ejercicio clases resueltoComputo movil ejercicio clases resuelto
Computo movil ejercicio clases resuelto
 
Ejemplo de uno a uno
Ejemplo de uno a unoEjemplo de uno a uno
Ejemplo de uno a uno
 

Destacado

Presentación amparo
Presentación amparoPresentación amparo
Presentación amparoMiguel Rivera
 
politiques et école - www.vos-pps.fr
politiques et école - www.vos-pps.frpolitiques et école - www.vos-pps.fr
politiques et école - www.vos-pps.frvospps
 
Brochure Mactac 2013 - Solutions adhésives applications
Brochure Mactac 2013 - Solutions adhésives applicationsBrochure Mactac 2013 - Solutions adhésives applications
Brochure Mactac 2013 - Solutions adhésives applicationsMactac Europe
 
2. sergio rojas andersen. epidemiologia en el edomex
2. sergio rojas andersen. epidemiologia en el edomex2. sergio rojas andersen. epidemiologia en el edomex
2. sergio rojas andersen. epidemiologia en el edomexMiguel Rivera
 
Falla amistat 2013
Falla amistat 2013Falla amistat 2013
Falla amistat 2013manelvil
 
Les monstres diaporama 6e a
Les monstres diaporama 6e aLes monstres diaporama 6e a
Les monstres diaporama 6e acdiclgmathieu
 
éClairage industriel
éClairage industrieléClairage industriel
éClairage industrielIHMEX Trading
 
Présentation d'un programme d'éducation positive au cycle 3
Présentation d'un programme d'éducation positive au cycle 3Présentation d'un programme d'éducation positive au cycle 3
Présentation d'un programme d'éducation positive au cycle 3Laure_Reynaud
 
Humo de segunda mano en espacios públicos y privados
Humo de segunda mano en espacios públicos y privadosHumo de segunda mano en espacios públicos y privados
Humo de segunda mano en espacios públicos y privadosMiguel Rivera
 
Webquest como estrategia de enseñanza y aprendizaje
Webquest como estrategia de enseñanza y aprendizajeWebquest como estrategia de enseñanza y aprendizaje
Webquest como estrategia de enseñanza y aprendizajeProyecto AVA
 

Destacado (20)

Glossaire Digital (1/4)
Glossaire Digital (1/4)Glossaire Digital (1/4)
Glossaire Digital (1/4)
 
EXTREMADURA
EXTREMADURAEXTREMADURA
EXTREMADURA
 
Presentación amparo
Presentación amparoPresentación amparo
Presentación amparo
 
La_Croix_1337843
La_Croix_1337843La_Croix_1337843
La_Croix_1337843
 
politiques et école - www.vos-pps.fr
politiques et école - www.vos-pps.frpolitiques et école - www.vos-pps.fr
politiques et école - www.vos-pps.fr
 
Brochure Mactac 2013 - Solutions adhésives applications
Brochure Mactac 2013 - Solutions adhésives applicationsBrochure Mactac 2013 - Solutions adhésives applications
Brochure Mactac 2013 - Solutions adhésives applications
 
2. sergio rojas andersen. epidemiologia en el edomex
2. sergio rojas andersen. epidemiologia en el edomex2. sergio rojas andersen. epidemiologia en el edomex
2. sergio rojas andersen. epidemiologia en el edomex
 
Falla amistat 2013
Falla amistat 2013Falla amistat 2013
Falla amistat 2013
 
Les monstres diaporama 6e a
Les monstres diaporama 6e aLes monstres diaporama 6e a
Les monstres diaporama 6e a
 
La révolte
La révolteLa révolte
La révolte
 
Juego de Futbol Americano
Juego de Futbol AmericanoJuego de Futbol Americano
Juego de Futbol Americano
 
éClairage industriel
éClairage industrieléClairage industriel
éClairage industriel
 
Présentation d'un programme d'éducation positive au cycle 3
Présentation d'un programme d'éducation positive au cycle 3Présentation d'un programme d'éducation positive au cycle 3
Présentation d'un programme d'éducation positive au cycle 3
 
Mapas Mentales Curso OG
Mapas Mentales Curso OGMapas Mentales Curso OG
Mapas Mentales Curso OG
 
Humo de segunda mano en espacios públicos y privados
Humo de segunda mano en espacios públicos y privadosHumo de segunda mano en espacios públicos y privados
Humo de segunda mano en espacios públicos y privados
 
Question 1 (2)
Question 1 (2)Question 1 (2)
Question 1 (2)
 
Dossier de présentation
Dossier de présentation Dossier de présentation
Dossier de présentation
 
Rezotour
RezotourRezotour
Rezotour
 
Kamishibai
KamishibaiKamishibai
Kamishibai
 
Webquest como estrategia de enseñanza y aprendizaje
Webquest como estrategia de enseñanza y aprendizajeWebquest como estrategia de enseñanza y aprendizaje
Webquest como estrategia de enseñanza y aprendizaje
 

Similar a Bbdd

Programacion de una tienda virtual en Grails
Programacion de una tienda virtual en GrailsProgramacion de una tienda virtual en Grails
Programacion de una tienda virtual en GrailsGabriel Bermudez
 
Administracion de datos
Administracion de datosAdministracion de datos
Administracion de datosUsein Gonzalez
 
Analisis comparativo
Analisis comparativoAnalisis comparativo
Analisis comparativoYoung Hyun
 
Analisis comparativo my-sql-oracle
Analisis comparativo my-sql-oracleAnalisis comparativo my-sql-oracle
Analisis comparativo my-sql-oracleBryand Guns
 
Smdb Equipo11
Smdb Equipo11Smdb Equipo11
Smdb Equipo11antori
 
Smdb Equipo11
Smdb Equipo11Smdb Equipo11
Smdb Equipo11antori
 
kupdf.net_bases-de-datos.pdf
kupdf.net_bases-de-datos.pdfkupdf.net_bases-de-datos.pdf
kupdf.net_bases-de-datos.pdfDnyNone
 
Electrónica digital: DIseño e implementacion de la plataforma Boole-Weblab-De...
Electrónica digital: DIseño e implementacion de la plataforma Boole-Weblab-De...Electrónica digital: DIseño e implementacion de la plataforma Boole-Weblab-De...
Electrónica digital: DIseño e implementacion de la plataforma Boole-Weblab-De...SANTIAGO PABLO ALBERTO
 
INSTITUTO_TECNOLOGICO_DE_MORELIA_PROGRAM.pdf
INSTITUTO_TECNOLOGICO_DE_MORELIA_PROGRAM.pdfINSTITUTO_TECNOLOGICO_DE_MORELIA_PROGRAM.pdf
INSTITUTO_TECNOLOGICO_DE_MORELIA_PROGRAM.pdfAnaLpez275
 
Programación Orientada a Eventos Java
Programación Orientada a Eventos JavaProgramación Orientada a Eventos Java
Programación Orientada a Eventos JavaJosé Mendoza
 
Sistema de Computación Distribuida Peer to Peer
Sistema de Computación Distribuida Peer to PeerSistema de Computación Distribuida Peer to Peer
Sistema de Computación Distribuida Peer to PeerTensor
 
Peer to Peer
Peer to PeerPeer to Peer
Peer to PeerTensor
 

Similar a Bbdd (20)

Programacion de una tienda virtual en Grails
Programacion de una tienda virtual en GrailsProgramacion de una tienda virtual en Grails
Programacion de una tienda virtual en Grails
 
Administracion de datos
Administracion de datosAdministracion de datos
Administracion de datos
 
Comparacion smdb
Comparacion smdbComparacion smdb
Comparacion smdb
 
Analisis comparativo
Analisis comparativoAnalisis comparativo
Analisis comparativo
 
Analisis comparativo my-sql-oracle
Analisis comparativo my-sql-oracleAnalisis comparativo my-sql-oracle
Analisis comparativo my-sql-oracle
 
Smdb Equipo11
Smdb Equipo11Smdb Equipo11
Smdb Equipo11
 
Smdb Equipo11
Smdb Equipo11Smdb Equipo11
Smdb Equipo11
 
Smdb Equipo11
Smdb Equipo11Smdb Equipo11
Smdb Equipo11
 
kupdf.net_bases-de-datos.pdf
kupdf.net_bases-de-datos.pdfkupdf.net_bases-de-datos.pdf
kupdf.net_bases-de-datos.pdf
 
Smdb Equipo11
Smdb Equipo11Smdb Equipo11
Smdb Equipo11
 
978 84-9839-226-5
978 84-9839-226-5978 84-9839-226-5
978 84-9839-226-5
 
Electrónica digital: DIseño e implementacion de la plataforma Boole-Weblab-De...
Electrónica digital: DIseño e implementacion de la plataforma Boole-Weblab-De...Electrónica digital: DIseño e implementacion de la plataforma Boole-Weblab-De...
Electrónica digital: DIseño e implementacion de la plataforma Boole-Weblab-De...
 
Capitulo 4
Capitulo 4Capitulo 4
Capitulo 4
 
INSTITUTO_TECNOLOGICO_DE_MORELIA_PROGRAM.pdf
INSTITUTO_TECNOLOGICO_DE_MORELIA_PROGRAM.pdfINSTITUTO_TECNOLOGICO_DE_MORELIA_PROGRAM.pdf
INSTITUTO_TECNOLOGICO_DE_MORELIA_PROGRAM.pdf
 
Programación Orientada a Eventos Java
Programación Orientada a Eventos JavaProgramación Orientada a Eventos Java
Programación Orientada a Eventos Java
 
Diseno bases datos
Diseno bases datosDiseno bases datos
Diseno bases datos
 
Sistema de Computación Distribuida Peer to Peer
Sistema de Computación Distribuida Peer to PeerSistema de Computación Distribuida Peer to Peer
Sistema de Computación Distribuida Peer to Peer
 
Peer to Peer
Peer to PeerPeer to Peer
Peer to Peer
 
Sistemas manejadores de base de datos
Sistemas manejadores de base de datosSistemas manejadores de base de datos
Sistemas manejadores de base de datos
 
Sistemas manejadores de base de datos
Sistemas manejadores de base de datosSistemas manejadores de base de datos
Sistemas manejadores de base de datos
 

Más de Gabriela Bartoli (12)

Ejercicios para examen
Ejercicios para examenEjercicios para examen
Ejercicios para examen
 
Normalizacion base de datos
Normalizacion base de datosNormalizacion base de datos
Normalizacion base de datos
 
Introducciona a las bd
Introducciona a las bdIntroducciona a las bd
Introducciona a las bd
 
Apunte 1
Apunte 1Apunte 1
Apunte 1
 
Entrevista
EntrevistaEntrevista
Entrevista
 
Carrera de pymes
Carrera de pymesCarrera de pymes
Carrera de pymes
 
Edgar morin
Edgar morinEdgar morin
Edgar morin
 
Frankensteineducador
FrankensteineducadorFrankensteineducador
Frankensteineducador
 
Tutorial cómo crear un blog en blogger
Tutorial cómo crear un blog en bloggerTutorial cómo crear un blog en blogger
Tutorial cómo crear un blog en blogger
 
Consignas
ConsignasConsignas
Consignas
 
Usopdfcreator
UsopdfcreatorUsopdfcreator
Usopdfcreator
 
CóMo Crear Un Blog En Blogger 2
CóMo Crear Un Blog En Blogger 2CóMo Crear Un Blog En Blogger 2
CóMo Crear Un Blog En Blogger 2
 

Bbdd

  • 1. Bases de datos Versión 1.1 Óscar Gómez Curso 2012-2013
  • 2.
  • 3. Índice general 1. Introducción 1.1. Historia de las bases de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2. Historia del software libre GNU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3. Un repaso al resto del libro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 3 3 2. Diseño de bases de datos 2.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . 2.2. Modelado de datos . . . . . . . . . . . . . . . . . . . . . 2.3. Modelos E/R . . . . . . . . . . . . . . . . . . . . . . . . 2.4. Problemas . . . . . . . . . . . . . . . . . . . . . . . . . 2.5. Transformación de modelos E/R en modelos relacionales . 2.6. Normalización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 . 5 . 6 . 6 . 11 . 22 . 24 3. Diseño físico 3.1. Introducción . . . . . . 3.2. BBDD en Access . . . . 3.3. Claves ajenas . . . . . . 3.4. MySQL . . . . . . . . . 3.5. Tablespaces y undo files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 27 27 31 31 37 . . . . . . . . 39 39 39 39 41 44 45 46 59 . . . . . . . . . . 4. Consultas SQL 4.1. Introducción . . . . . . . . 4.2. La sentencia SELECT . . . 4.3. Condiciones . . . . . . . . 4.4. Consultas con agregados . . 4.5. Consultas multitabla . . . . 4.6. Algunos ejercicios resueltos 4.7. Subconsultas . . . . . . . . 4.8. Actualización y borrado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5. Programación 61 5.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 5.2. Procedimientos almacenados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 5.3. Sentencias básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 I
  • 4. 5.4. 5.5. 5.6. Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Funciones MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Solución al examen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 6. Administración 6.1. Introducción . . . . . . . . . . . . 6.2. Aspectos básicos de las contraseñas 6.3. El sistema de privilegios . . . . . . 6.4. El sistema de concesiones . . . . . 6.5. Usuarios con restricciones . . . . . 6.6. Vistas . . . . . . . . . . . . . . . . 6.7. Recuperando la clave de root . . . . 6.8. Copias de seguridad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 79 79 80 82 82 83 85 85 7. Access 89 7.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 7.2. El entorno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 8. BBDD Objeto relacionales 8.1. Introducción . . . . . . . . . . . . . . 8.2. Instalación de PostgreSQL . . . . . . . 8.3. Uso de Postgres en una máquina virtual 8.4. Funcionamiento básico de Postgres . . 8.5. Comandos de Postgres . . . . . . . . . 8.6. Creación de tipos de datos . . . . . . . 8.7. Soporte documental . . . . . . . . . . 8.8. Sistemas de información geográfica . . 9. Índices y tablas II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 91 91 91 92 92 96 98 99 103
  • 5. Bases de datos, Versión 1.1 Contents: Índice general 1
  • 6. Bases de datos, Versión 1.1 2 Índice general
  • 7. CAPÍTULO 1 Introducción 1.1 Historia de las bases de datos 1.2 Historia del software libre GNU 1.3 Un repaso al resto del libro 3
  • 8. Bases de datos, Versión 1.1 4 Capítulo 1. Introducción
  • 9. CAPÍTULO 2 Diseño de bases de datos 2.1 Introducción En general, la construcción de una casa se considera un proyecto de envergadura. Dado que no se puede permitir que cada uno de los participantes en el proyecto siga su propio ritmo o haga lo que crea conveniente, se asume que habrá un arquitecto que diseña una estructura y realiza los cálculos necesarios para que todo se construya correctamente. En las bases de datos ocurre lo mismo: determinados negocios necesitarán una infraestructura de información muy sofisticada por lo que puede ser conveniente disponer de unos “planos” que permitan la comunicación entre los distintos miembros que participan en un proyecto de desarrollo de un programa informático. Además, muy a menudo ocurre que transcurrido un tiempo, el usuario del programa desea hacer mejoras o ampliaciones pero por desgracia, la estructura de una base de datos o de un programa no son tan visibles como los muros de una casa. La existencia de los planos o diagramas que expliquen como se hizo una base de datos pueden ser de gran ayuda para tales mejoras. Es de esperar que un cliente con visión de futuro exija una cierta documentación de como se hizo un programa. Por otro lado, un problema habitual para los desarrolladores informáticos es la necesidad de conocer un poco el “dominio de conocimiento”. Es decir, si se necesita construir una base de datos que almacene información sobre impuestos, es muy probable que primero se necesite conocer un poco más como funciona ese mundo. El conocimiento que se obtenga junto a los requisitos que tenga el cliente deberían plasmarse de alguna forma en un documento. Al igual que la construcción de una casa requiere la elaboración de planos y cálculos el diseño de una estructura de almacenamiento de datos requiere que exista un mecanism Los diagramas como “planos” de una BBDD. Se utilizarán para que despues todo el mundo pueda entender qué hay dentro de la BBDD por si se necesita modificar algo. Un problema fundamental es el dominio de conocimiento. Como informáticos debemos intentar adquirir el conocimiento del cliente para reflejarlo en una BD. En esencia debemos intentar extraer la información RELEVANTE Otro problema de gran importancia es la ambigüedad. Se debe concretar al máximo el significado de cada palabra o término específico. En suma, un informático va a construir un modelo del conocimiento del cliente. La primera labor a la hora de construir una BD es modelar la información. 5
  • 10. Bases de datos, Versión 1.1 Las reuniones, el proceso de desambigüación etc... deben plasmarse en una especificación de requisitos. Un ejemplo de especificación es el estándar IEEE 830, que ofrece una plantilla que podemos rellenar. Una vez hecha la especificación, se procederá a la realización del diseño, modelo, plano... 2.2 Modelado de datos Al hacer un modelo, plano o diagrama de datos, se hacen abstracciones • Hay que reseñar que no seremos expertos en el campo de aplicación. • Es muy importante utilizar un lenguaje estándar. • Los distintos SGBD (Sistemas Gestores de Bases de Datos) son muy distintos entre sí ◦ Por ejemplo, tenemos SGBD monolíticos: se caracterizan por utilizar un solo programa de uso y administración de los datos. ◦ También existen los SGBD basados en un modelo cliente/servidor. Los SGBD cliente/servidor hacen que los datos estén gestionados por un solo programa llamado servidor. A dichos datos pueden acceder montones de clientes. • Debido a estas diferencias el proceso de crear tablas necesita pasar por varias fases. ◦ Primero se debe hacer el llamado modelo conceptual. Este modelo consiste en hacer los diagramas que reflejan los requisitos. ◦ Despues haremos el llamado diseño lógico que consiste en crear una estructura de tablas y claves. ◦ Por último se debe hacer el diseño físico que consiste en pasar el diseño lógico a un lenguaje SQL de un SGBD. 2.3 Modelos E/R El modelo E/R se remonta al año 1970, cuando Peter Chen observó lo complejo que era diseñar una base de datos. Decidió crear un lenguaje común de símbolos que facilitara la comunicación. 2.3.1 Entidades Se denomina entidad a cualquier elemento sobre el cual se desea almacenar información. Aunque las entidades suelen corresponderse con los sustantivos, no todos los sustantivos merecen ser entidades que aparezcan en el modelo. Las entidades pueden ser fuertes o débiles: Una entidad fuerte es aquella que existe por sí sola. Una entidad débil es aquella que requiere que otra entidad exista antes que ella. Supongamos una situación como “empleado realiza viajes”. No se puede almacenar nada sobre un viaje si previamente no existe un empleado que lo realice. En la debilidad hay dos posibilidades: 6 Capítulo 2. Diseño de bases de datos
  • 11. Bases de datos, Versión 1.1 Dependencia en existencia: una entidad es débil con dependencia en existencia si antes de poder “existir” o “almacenarse” requiere que otra entidad exista primero. Dependencia en identificación: la entidad débil no tiene clave propia sino que necesita la de otra entidad. 2.3.2 Ocurrencia de entidades En general una misma entidad puede ocurrir muchas veces, se dice que una entidad puede tener “varias instancias”. Una entidad “Coche” puede tener infinitas instancias como “Seat Ibiza CR-2785-X”, “Renault 21 8765-CWG”, ... 2.3.3 Interrelaciones Son asociaciones entre entidades. En general se corresponden con los verbos. Se representan por medio de un rombo con el nombre dentro. Las interrelaciones pueden ser entre distintos conjuntos de entidades Interrelación binaria: se da entre dos entidades. Interrelación ternaria: se da entre tres entidades que participan de forma simultánea en una asociación. Interrelación n-aria. Interrelaciones reflexivas: se dan entre una entidad y sí misma. El principal ejemplo se da en la sentencia “unos empleados son jefes de otros”. 2.3.4 Participación o “cardinalidad” En las bases de datos se debe reflejar el hecho de que las entidades puedan aparecer 0 veces, 1 vez, muchas veces. En el diagrama, se ponen las cardinalidades junto a la entidad y con el mínimo y el máximo. Para abreviar,a veces se ponen los máximos encima de la relación y tendremos entonces relaciones como esta: “Uno a uno” o 1:1 “Uno a muchos” o 1:n “Muchos a muchos” o m:n Ejercicios: hacer el diagrama E/R con entidades, debilidades, interrelaciones y cardinalidades de los siguientes supuestos. Hombre se casa con mujer en sociedad monógama Hombre se casa con mujer en sociedad polígama masculina Hombre se casa con mujer en sociedad polígama mixta Pescador pesca pez Arquitecto diseña casa 2.3. Modelos E/R 7
  • 12. Bases de datos, Versión 1.1 Piezas forman producto • Téngase en cuenta que producto no es débil. Esto se debe a que podemos almacenar un producto en la base de datos indicando un hecho:”el producto P1 está hecho de los tornillos T1, T2 y T3”. Este hecho se puede almacenar aunque no tengamos físicamente los tornillos. A la hora de comprobar la “debilidad” de una entidad se debe ver si podemos almacenar los hechos o no, sin pensar en productos o piezas físicos. Turista visita hotel Jugador juega equipo Político gobierna país. Autor publica libro en una editorial • Podría verse la solución a esto como tres relaciones 1. Autor escribe libro 2. Libro es editado por editorial 3. Editorial publica libro • O como una relación ternaria: “Autor publica libro en editorial” • En resumen, ante las dudas debemos fabricar un diagrama que recoja las posibles asociaciones: supongamos que conocemos los siguientes hechos ◦ Cervantes escribe Quijote ◦ Cervantes escribe Novelas Ejemplares ◦ Iván López escribe Bases de datos ◦ M.J Castellanos escribe Bases de datos ◦ Ed. Anagrama publica Quijote ◦ Ed. Anagrama publica Novelas ejemplares ◦ Ed. Garceta publica Bases de datos ◦ Ed. Garceta publica Lazarillo • Si en las distintas asociaciones encontramos que hay asociaciones rígidas que no pueden cambiar, deberemos usar una interrelación ternaria: Cervantes escribe Quijote es un hecho que no puede variar. Es cierto que la otra asociación sí puede cambiar: por ejemplo, mañana Ed. Anagrama publica Bases de datos. Aunque esto es un hecho flexible la relación “AutorLibro” no puede cambiarse. 2.3.5 Atributos Se denomina atributos a propiedades de las entidades que tienen la importancia suficiente para almacenar datos sobre ellas y que por tanto aparecerán en el diagrama E/R. Los atributos suelen tener un dominio: es decir un conjunto de valores del cual toman su información. Un detalle sutil pero importante es que en ocasiones los atributos no son de las entidades, sino de las relaciones. Ej: pensemos en el diseño E/R de un enunciado como este: “un mecanico repara un coche en una cierta fecha del año”. La información de un conjunto cualquiera de mecánicos podría ser la siguiente 8 Capítulo 2. Diseño de bases de datos
  • 13. Bases de datos, Versión 1.1 DNI 10 20 30 Nombre Juan Luis Angel Ap1 Sanz Sanz Diaz Ap2 Alcolea Ruiz Diaz Es evidente que no podemos poner la fecha de reparación en la entidad Mecánico: un mecánico solo podría reparar coches una vez en su vida, ya cada mecánico solo aparece una vez en la tabla. Por otro lado, supongamos la siguiente información sobre un conjunto de coches. Matric. 2211-ZW 4324-EE 5421-AA Marca Seat Renault VW Modelo Ibiza 21 Bora La fecha de reparación tampoco es de la entidad Coche: si lo hiciéramos así un coche solo podría repararse una vez en la vida (recordemos que cada coche solo aparece una vez en la tabla). A veces, hay atributos que se comportan de una forma especial y esto se recoge en el diseño E/R Atributos opcionales: pueden aparecer o no. Atributos monovaluados: solo toman un valor (o como mucho dos, por exclusión). Atributos compuestos: por ejemplo, el campo “Dirección”. Atributos derivados: son aquellos que pueden obtenerse o calcularse a partir de otros. Por ejemplo, el campo “Edad” puede obtenerse a partir de “Fecha de nacimiento”. 2.3.6 Entidades débiles Ya hemos dicho que hay entidades que muestran “debilidad” en base a dos características Dependencia en existencia: por ejemplo la entidad “Transacción” es débil con respecto a “Cuenta Corriente”. En este caso, la interrelación llevará una letra E, para indicar este tipo de dependencia. Dependencia de identificación: en este caso, la relación utiliza una I para señalar la dependencia. Ejercicio:¿Qué tipo de relación existe entre estas entidades? 1. Toro y Ganadería: Toro es débil (dependencia en identificación) con respecto a Ganadería. 2. Una empresa tiene un párking y desea almacenar qué empleados aparcan vehículos y los datos sobre los mismos. 2.3.7 Ejercicio de modelado Enunciado Analiza el siguiente enunciado y transfórmalo en DOS diagramas E/R. ¿Qué características reflejan uno u otro modelo?: Una serie de empresas con CIF, Nombre y Dirección desean ofrecer beneficios a sus clientes. Estos beneficios tienen un código, una descripción y una limitación. Para obtener dichos beneficios se emiten una serie de cupones que tienen un código y una fecha de vencimiento 2.3. Modelos E/R 9
  • 14. Bases de datos, Versión 1.1 Solución No hay una solución correcta a partir de lo que nos dicen. Podemos pensar en dos posible situaciones 1. Las empresas son libres de ofrecer beneficios, modificarlos y hacer cambios cuando lo deseen. 2. Los beneficios solo los inserta un administrador y las empresas deben ceñirse a la lista de posibilidades que les ofrecemos Esto da lugar a que el ejemplo a) sea un modelo en el que se da libertad mientras que el modelo b) sea más rígido, lo que a su vez condiciona el modelo Podemos por tanto contemplar dos soluciones a partir de las tres entidades Empresa, Beneficio y Cupón 1. Dos relaciones binarias Relación “Empresa ofrece Beneficio” Relación “Beneficio Se Plasma En Cupón” 2. Una sola relación ternaria “Empresa con Beneficio con Cupón” Imaginemos las tres tablas, Empresa, Beneficio y Cupón. CIF E1 E2 Nombre ACME XYZ Sport Direccion C/ Guadiana C/ Rio Codigo B1 B2 Desc. 10 % desc. 5 % desc Codigo C1 C2 Limit. Excepto rebajas LaJ Fecha venc 31-12-2011 20-12-2011 A la hora de insertar en la tabla Beneficios puede que si damos libertad acaben apareciendo filas iguales Codigo B1 B2 B3 B4 B5 Desc. 10 % desc. 5 % desc 5 % desc 5 % desc 15 % desc. Limit. Excepto rebajas LaJ LaJ LaJ Solo S y D En este caso, B2, B3 y B4 corresponden a los beneficios que ofrecen distintas empresas, dando la casualidad de que sus descripciones son iguales. Hay quien considera eso un problema, pero no lo es, sino que es una consecuencia de la libertad que tienen las empresas para actuar. 2.3.8 Herencia En ocasiones hay objetos que comparten muchas propiedades y características. Supongamos el ejemplo de una base de datos para la DGT. Para cada coche puede haber un dueño, pero este dueño puede ser una persona física o jurídica. Si construyéramos dos entidades separadas “Persona” y “Empresa” descubriríamos que tienen cosas en común. Para ahorrar esfuerzos se puede poner una sola entidad general que “ofrece” los atributos, y dichos atributos son “heredados” por las entidades hija. 10 Capítulo 2. Diseño de bases de datos
  • 15. Bases de datos, Versión 1.1 Cuando hay una herencia es posible que una instancia pueda ser de dos entidades a la vez. Por ejemplo, pensemos en las entidades “Personal Contratado” y las entidades “Estudiante” y “Trabajador”. ¿Puede una persona ser estudiante y trabajador a la vez? SÍ . Por lo tanto esta herencia no es disjunta, pero la de “Persona” y “Empresa” sí es disjunta. Las herencias disjuntas se marcan con una “d” en el triángulo. 2.3.9 Relaciones exclusivas A veces dos entidades pueden ir relacionadas por dos o más conexiones. En determinadas situaciones interesa restringir el número de conexiones posibles. Por ejemplo, cuando una entidad “Cliente” se conecta con una entidad “Piso” puede hacerlo por medio de varias relaciones como “Vende”, “Alquila”, “Hace leasing”. Si por ejemplo la ley obligase a que solo podamos tener un tipo de relación, se pondrá un arco en las relaciones. 2.4 Problemas 2.4.1 Problema 1: Comunidades de vecinos Una firma de abogados dedicada a la administración de fincas desea tener una base de datos para gestionar la información de sus clientes. La firma tiene varios abogados y cada uno de ellos ejerce de administrador de una o más comunidades de vecinos, por lo que cobra unos honorarios anuales. Una comunidad es gestionada por un único administrador (nombre, DNI y número de colegiado). Las funciones de un administrador consisten en llevar la contabilidad de la comunidad, gestionar los recibos y realizar los pagos a las distintas compañías (luz, agua...) De las empresas que cada comunidad tiene contratadas se guarda su nombre, dirección, teléfono y una persona de contacto. Además puede interesar tener agrupadas a las compañías por sectores (sector de seguridad, sector de suministros básicos). De cada comunidad se almacena un código, su nombre, calle, código postal y población. Cada comunidad consta de una serie de propiedades que pueden ser de tres tipos (vivienda particular, local y oficina). Cada propiedad se caracteriza por un número de portal, planta y letra, un nombre y apellidos del propietario, un porcentaje de participación en los gastos de la comunidad así como los datos de la cuenta bancaria en la que el propietario desea se le domicilie el pago de los recibos. Si el propietario no habita en su propiedad se necesitan sus datos (nombre, apellidos, dirección y teléfono) y los datos de su inquilino (nombre apellidos y teléfono). Si la vivienda es particular se guarda el número de habitaciones. Si es un local se almacena el tipo de local y el horario. Si es una oficina se guarda la actividad a la que se dedica. Cada comunidad tiene un presidente (nombre, apellidos y propiedad de la que son dueños) y varios vocales que tratan con el administrador los asuntos que hay que tratar. Cada comunidad tiene una cuenta en un banco y todo banco tiene un código y un nombre comercial. De las cuentas se almacena el código de cuenta (que consta de un código de sucursal, dos dígitos de control y un número de cuenta) y un saldo. Para identificar la cuenta hay que añadir el código del banco al código de cuenta. Se almacenan dos tipos de apuntes: 2.4. Problemas 11
  • 16. Bases de datos, Versión 1.1 El banco emite los recibos, pero el administrador guarda información sobre dichos recibos como el número de recibo, fecha, importe y si se ha podido cobrar o no. Esta última información se necesitará para llevar un registro de impagados. En cuanto a los apuntes sobre gastos se tienen los importes que cobran las empresas contratadas por cada comunidad. Las compañías cobran sus recibos (número, fecha e importe) cargándolo en la cuenta de la comunidad 2.4.2 Solución al problema 1 0. Leer el enunciado completo 1. Leer otra vez examinando cuidadosamente los elementos siguientes 1.1. Sustantivos: entidades/atributos 1.1.1. Abogado/administrador 1.1.2. Finca/propiedad 1.1.2.1. Num de portal 1.1.2.2. Planta y letra 1.1.2.3. ¿Nombre y ap del propietario? Esta frase nos dice que el nombre y el apellido del propietario deben estar aqui. Sin embargo, si luego resulta que necesito una entidad Propietario, ya no podremos poner a esa entidad estos atributos. Si resulta que luego necesitamos esta entidad habremos descubierto que “Propiedad” es débil por identificación. 1.1.2.4. Porcentaje de particip. 1.1.2.5. Datos cuenta bancaria 1.1.3. Comunidad de vecinos 1.1.3.1. Nombre 1.1.3.2. Calle 1.1.3.3. CP 1.1.3.4. Población 1.1.4. Honorarios 1.1.5. Funciones 1.1.6. Pagos 1.1.7. Compañía 1.1.8. Empresa 1.1.8.1. Nombre 1.1.8.2. Dirección 1.1.8.3. Teléfono 1.1.8.4. Persona de contacto 12 Capítulo 2. Diseño de bases de datos
  • 17. Bases de datos, Versión 1.1 1.1.9. Sector 1.1.10. Tipos 1.1.10.1. Viv. particular Num. habitaciones 1.1.10.2. Local Tipo Horario 1.1.10.3. Oficina Actividad 1.1.11. Propietario 1.1.1. Nombre 1.1.2. Apellidos 1.1.3. Dirección 1.1.4. Teléfono Al leer que un propietario tiene que aparecer como entidad, descubrimos que “Propiedad” va a ser débil, como supusimos. 1.1.12. Inquilino 1.1.12.1. Nombre 1.1.12.2. Apellidos 1.1.13. Presidente 1.1.13.1. Nombre 1.1.13.2. Apellidos 1.1.13.3. Propiedad que poseen 1.1.14. Vocales 1.1.15. Cuenta 1.1.15.1. Código de cuenta 1.1.15.2. DC 1.1.15.3. Número de cuenta 1.1.15.4. Código de banco Como nos dicen que se necesita el código del banco para poder “identificar” esta entidad, hemos descubierto que esta entidad es débil 1.1.16. Banco 1.1.16.1. Codigo de banco 1.1.16.2. Nombre comercial 2.4. Problemas 13
  • 18. Bases de datos, Versión 1.1 1.1.17. Apunte 1.1.17.1. Recibo (cobramos a prop) Número de recibo Fecha Importe ¿Se pagó? 1.1.17.2. Pago (pagamos luz..) Número de recibo Importe Fecha 1.2. Verbos: relaciones 1.2.1 “Abogado” administra “Comunidad” 1.2.2 “Abogado” cobra “Honorarios” (¡¡MAL!!, los honorarios no llegarán a ser entidad) 1.2.3 “Comunidad” es gestionada por “Abogado” es lo mismo que “administra” 1.2.4 “Administrador” realiza funciones 1.2.5 “Comunidad” contrata “Empresa” 1.2.6 “Comunidad” consta de “Propiedades” 1.2.7 “Propiedad” paga a través de “Cuenta” 1.2.8 “Comunidad” tiene “Presidente” 1.2.9 “Comunidad” posee “Vocales” 1.2.10 “Comunidad” opera con “Cuenta” 1.2.11 “Banco” emite “Recibo” 2.4.3 Problema 2: Ajedrez La federación de ajedrez desea disponer de una base de datos de todas las partidas que se celebren bajo su auspicio. Toda partida viene caracterizada por una fecha de inicio, una duración en horas, los jugadores que se enfrentaron y si eligieron blancas o negras Dos jugadores pueden enfrentarse solo una vez por día, aunque pueden hacerlo muchas veces en días distintos. Se anota cada movimiento de la partida: número de movimiento, casilla de origen y casilla de destino. Si se borra una partida se deben borrar los movimientos Las partidas no pueden ser aplazadas De los jugadores se recogen sus nombres, apellidos, dirección postal y electrónica, la federación a la que pertenecen y el número de federado (que es único en cada federación) 14 Capítulo 2. Diseño de bases de datos
  • 19. Bases de datos, Versión 1.1 Solo hay una federación por país con un nombre, país al que pertenece, telefono de contacto y fecha de fundación Una federación no se clausura hasta que no se reasignan sus jugadores a otra federación. Las partidas pueden darse o no dentro de un torneo. Los torneos tienen un nombre, periodicidad, fecha de creación y son organizados por una federación En cada edición de un torneo (número ordinal) se registran todos los enfrentamientos y el nombre del ganador. También se anotan la fecha de inicio, la cuantía del premio y el jugador que lo gana Si desaparece una federación, desaparecen los torneos y por ende, sus ediciones Aunque un jugador desaparezca, sus partidas no deben desaparecer 2.4.4 Solución al problema 2 (ajedrez) Entidades Federación • Atributo:nombre • Atributo:país Partida • Atributo:fecha de inicio • Atributo:duración • Atributo:¿blancas? Jugador • Atributo:nombre • Atributo:apellidos • Atributo:dirección postal • Atributo:dirección electrónica • Atributo:num de federado Movimiento • Atributo:número • Atributo:casilla origen • Atributo:casilla destino Torneo: es una entidad débil ya que nos dicen “Si desaparece una federación, desaparecen los torneos y por ende, sus ediciones”. Por tanto, no puede haber torneo en la BD sin que haya una federación que lo organice. • Atributo:nombre • Atributo:periodicidad • Atributo:fecha 2.4. Problemas 15
  • 20. Bases de datos, Versión 1.1 • Atributo:ganador • Atributo:fecha inicio • Atributo:periodicidad • Atributo:cuantía del premio Relaciones Se necesita una relación para conectar los jugadores con partida: “Partida enfrenta jugadores”. El enfrentamiento tiene atributos • También podríamos considerar que hay una sola relación reflexiva “Jugador Se Enfrenta Con Jugador”. Esta relación tendría atributos como “fecha de inicio”, “duración”, etc... “Partida Consta De Movimiento”: aquí se descubre que Movimiento es débil, no puede almacenarse un movimiento sin que esté “dentro de una partida” “Jugador Pertenece A Federación”. Hay dos posibilidades de relación • “Federación organiza Torneo que Consta De Partidas”: relación ternaria • “Federación organiza Torneo y Torneo Consta De Partidas”: dos binarias • Dado que se permite que las partidas estén o no dentro de un torneo es más apropiados que el modelo permita cierta libertad para lo cual es más apropiado utilizar las dos binarias. 2.4.5 Problema 3: Formación El departamento de formación de una empresa desea construir una BD para planificar y gestionar la formación de sus empleados. Los supuestos semánticos que deben recogerse son los siguientes: La empresa organiza cursos internos de formación de los que se desea conocer el código de curso, el nombre, una descripción, el número de horas de duración y el coste del curso. Un curso puede tener como prerrequisito haber realizado otro(s) previamente, y, a su vez, la realización de un curso puede ser prerrequisito de otros. Un curso que es prerrequisito de otro puede serlo de forma obligatoria u opcional. Un mismo curso tiene diferentes ediciones, es decir, se imparte en distintos lugares,fechas y con diversos horarios (intensivo, mañana o tarde). En una misma fecha de inicio sólo puede impartirse una edición de un curso. Los cursos se imparten por personal de la propia empresa. Un curso puede tener varios docentes pero una edición sólo tiene un profesor. De los empleados se desea almacenar su código de empleado, nombre y apellidos,dirección, teléfono, NIF, fecha de nacimiento, nacionalidad, sexo, firma y salario,así como si está o no capacitado para impartir cursos. Un mismo empleado puede ser docente en una edición de un curso y alumno en otra edición, pero nunca puede ser ambas cosas a la vez (en una misma edición de un curso o lo imparte o lo recibe) 16 Capítulo 2. Diseño de bases de datos
  • 21. Bases de datos, Versión 1.1 2.4.6 Solución al problema 3 (Formación) Entidades Curso • Código de curso (clave) • Nombre • Descripción • Duración (número de horas) • coste Edición (débil con respecto a curso) • Lugar • Fecha: clave • Horario Empleado • Nombre • Ap • Dirección • Tlf • Dni: clave • Nacionalidad • Firma • Sexo • Salario • Capacitado Relaciones “Curso Es Prerrequisito De Curso”: muchos a muchos “Curso Celebra Ediciones”: edición es débil con respecto a curso “Empleado Imparte Edición”. “Empleado Sigue Edición” Nos dicen que no se puede hacer las dos cosas a la vez en una edición, o una u otra. 2.4. Problemas 17
  • 22. Bases de datos, Versión 1.1 2.4.7 Problema 4: viveros Se desea diseñar una Base de Datos para gestionar los empleados y productos a la venta de una cadena de viveros dedicados a la venta de diversos productos relacionados con la jardinería. Los supuestos que hay que recoger en la BD son los siguientes: La cadena de viveros dispone de varios viveros en la provincia de Madrid identificados por un código de tienda y de los que se almacenará un teléfono, una dirección y un responsable que será uno de los empleados que trabaja en el vivero (es necesario almacenar durante qué períodos de tiempo ha sido responsable cada empleado). Los productos que se venden tienen asignado un código de producto y nos interesa guardar el precio y el stock que hay de cada producto en cada uno de los viveros y pueden ser de tres tipos: plantas de las que se guardará su nombre, y una breve descripción de los cuidados que requiere; accesorios de jardinería y artículos de decoración. Estos productos se distribuyen en zonas dentro de cada vivero cada una de ellas identificadas por un nombre dentro de cada vivero (zona exterior regadío, interior climatizada, zona de caja, etc.). Se desea conocer el stock de cada producto de acuerdo a las zonas del vivero.Los empleados estarán asignados a una determinada zona en un vivero la cual podrá cambiar a lo largo del tiempo (se guardará histórico de ello) y además, los empleados puedenmo verse de un vivero a otro según las necesidades en distintos períodos de tiempo. De los empleados se quiere conocer su DNI, su nombre y un teléfono de contacto.En cuanto al proceso de venta de los distintos productos, sólo se almacenarán los pedidos que realizan los clientes pertenecientes al Club VIP que es una promoción especial que permite a los clientes obtener descuentos según las cuantías de sus compras. De estos clientes se almacena su DNI, su nombre, dirección, teléfono y la fecha de incorporación al club así como los datos de sus pedidos que incluyen un número de pedido, la fecha de realización, los productos adquiridos junto con las unidades y el descuento realizado; por último, también se incluye el precio de los portes en caso de que se hayan contratado. De cada cliente se almacenarán todos los pedidos que haya realizado hasta la fecha.En cuanto a estos pedidos de clientes pertenecientes al Club VIP interesa también guardar quién fue el empleado que lo gestionó y en qué vivero se realizó el pedido teniendo en cuenta que un pedido en un determinado vivero lo gestiona un único empleado Solución al problema 4 (Viveros) Entidades: Empleado • DNI • Nombre • Número de contacto Producto • Código • Precio • Stock (más tarde se descubre que stock NO ES UN ATRIBUTO DE PRODUCTO sino de una relación) Planta es una entidad hija de Producto 18 Capítulo 2. Diseño de bases de datos
  • 23. Bases de datos, Versión 1.1 • Nombre • Cuidados Accesorio de jardinería (hija de producto) Artículo Viveros • Código • Teléfono • Dirección • ¿Responsable? No, esto es una relación Zona • Nombre (clave) Pedido • Número: clave • Fecha • Unidades, precio de portes y descuento son atributos de una relación cuyo nombre todavía no conocemos. Cliente: habrá “Normales” y “Club VIP” • DNI • Dirección • Teléfono • Fecha de incorporación (solamente para el club VIP) Relaciones: “Empleado es Responsable De Vivero” tiene unos atributos de fecha de inicio y fin. “Producto Se Distribuye en Zona”. Esto implica que hay un atributo en esta relacion llamado Stock. “Empleado Trabaja en Zona” A la hora de almacenar el hecho de que un pedido consta de varios productos vamos a descubrir que la relación ternaria no es la mejor opción ya que nos obligaría a que en un pedido solo apuntásemos un producto VIP1 VIP1 VIP1 Ped1 Ped1 Ped1 Rosas Tijeras Semillas Técnicamente, esta relación ternaria es capaz de guardar el hecho de que el cliente VIP1, en su pedido 1 compró “Rosas, Tijeras y Semillas”, sin embargo este modelo ternario nos está obligando a repetir datos. Como conclusión la relación “Cliente hace pedido que consta de Artículos” no es la mejor opción, sino que desglosaremos esto en dos binarias “Vip Realiza Pedido” (esto implica que Pedido es débil) 2.4. Problemas 19
  • 24. Bases de datos, Versión 1.1 “Pedido consta de Productos”. Hay una relación a cuatro entre “Pedido” “Cliente VIP”, “Vivero” y “Empleado” Problema 2.4.8 Problema 5: Universidad El Departamento de Informática de la universidad necesita una base de datos para almacenar la información concerniente a los proyectos de investigación tanto actuales como pasados en los que trabajan los profesores y así poder llevar a cabo una gestiónmás eficiente. La información que se desea almacenar corresponde a los siguientes supuestossemánticos. En el departamento los profesores participan en proyectos de investigación caracterizados por un código de referencia único, por un nombre, un acrónimo, un presupuesto total, el programa de I+D que lo financia, una fecha de inicio y una fecha de finalización y una breve descripción de los objetivos del proyecto. En los proyectos trabajan profesores del departamento durante un período de tiempo, esdecir, una fecha de inicio y una fecha de fin, pudiendo ocurrir que un profesor trabaje en elmismo proyecto en varias épocas (f_ini, f_fin) diferentes. Un profesor se identifica por su nombre y apellidos y se caracteriza por su despacho y teléfono y puede trabajar en varios proyectos simultáneamente y en un proyecto de investigación trabajan varios profesores. De todos los profesores que trabajan en el proyecto hay uno que es el investigador principal deproyecto que interesa conocer. Es importante tener en cuenta que el profesor investigador del proyecto nunca varía a lo largo de la vida del proyecto de investigación. Los profesores pueden ser doctores o no doctores, de tal manera que un profesor nodoctor siempre tiene a un único profesor doctor como supervisor en un momento determinado,interesando almacenar los supervisores y períodos de tiempo de la supervisión que ha tenido undeterminado profesor no doctor. En relación con la participación de los profesores en proyectosde investigación, el investigador principal de un proyecto siempre tiene que ser un doctor.Por otro lado, los proyectos de investigación producen una serie de publicaciones sobrelas que también interesa guardar información. Una publicación se caracteriza por un número en secuencia dentro de cada proyecto de investigación y se guardará el título y los profesores que la han escrito; las publicaciones son de dos tipos, publicaciones en congresos y publicaciones en revista; de las primeras se almacenará el nombre del congreso, su tipo (nacional ointernacional), la fecha de inicio y de fin, el lugar de celebración, país y la editorial que hapublicado las actas del congreso (si es que se han publicado); de las publicaciones en revista interesa saber el nombre de la revista, la editorial, el volumen, el número y las páginas de inicio y fin. No solamente interesa conocer los profesores que han participado en las publicaciones de los proyectos de investigación sino también las líneas de publicación que cubren estas publicaciones. Una línea de investigación se identifica por un código, un nombre (por ejemplo,recuperación de información multilingüe, bases de datos espacio-temporales, etc.) y un conjunto de descriptores (por ejemplo, la línea de investigación bases de datos temporales puede tener como descriptores Bases de Datos, SGBD Relacional, Dimensión temporal). Los profesores tendrán asociados en la BD las líneas de investigación en las quetrabajan incluso podría ocurrir que hubiera profesores que no tuvieran ninguna línea asignada.Así, tanto los profesores doctores como los no doctores pueden escribir publicaciones sobre una o más líneas de investigación y nos interesa saber sobre qué línea de investigación ha escrito un determinado 20 Capítulo 2. Diseño de bases de datos
  • 25. Bases de datos, Versión 1.1 profesor en una publicación, teniendo en cuenta que un profesor queparticipa en una publicación sólo escribe en el ámbito de una línea de investigación y que una determinada publicación puede cubrir varias líneas de investigación Solución: entidades Proyecto • código de referencia único • un nombre • un acrónimo • un presupuesto total • el programa de I+D que lo financia • una fecha de inicio y una fecha de finalización • y una breve descripción Profesor • Nombre y apellidos. • Despacho y teléfono. • ¿Investigador principal hijo de Profesor? Es mala idea porque usaríamos una entidad para algo que aparecerá una sola vez. • “Doctor” y “No doctor” sí pueden ser entidades hija. Publicación. • Número • Título • Profesores que lo escriben (esto será una relación) • “En congreso” y “En revista” serán entidades hija. ◦ En congreso tiene los atributos: Tipo, nombre, fecha de inicio, de fin, lugar de celebración, país y editorial. ◦ En revista tiene los atributos: nombre de revista, el volumen, editorial, páginas de inicio y fin. Línea • Código • Nombre Descriptores: • Nombre 2.4. Problemas 21
  • 26. Bases de datos, Versión 1.1 Solución: relaciones “Profesor Participa en Proyecto” “Profesor dirige proyecto”, esta relación contiene el hecho de que un proyecto tiene 1 y solo 1 “investigador principal”. “Doctor supervisa a No Doctor” “Doctor dirige proyecto”, esta relación sustituye a la anterior “Profesor dirige proyecto”. “Proyecto produce publicación”. En realidad, más adelante descubriremos que el Profesor debe intervenir en esta relación dando lugar a una relación ternaria “Proyecto produce publicación en la que interviene profesor” 2.5 Transformación de modelos E/R en modelos relacionales Toda entidad se convierte en tabla. Toda entidad débil se convierte en tabla. La clave de esta tabla será la mezcla de la clave del débil más la clave del fuerte. En una herencia, la entidad padre se convierte de forma normal. Las hijas heredan la clave del padre (y en las hijas será además clave ajena). En las relaciones se trabaja de la siguiente forma • Si la relación es 1:1 ambas entidades se convierten a tablas Y UNA DE ELLAS TOMA LA CLAVE DE LA OTRA que actuará solo como clave ajena • Si la relación es 1:N el que tiene el N toma la clave del que tiene el 1, que actuará como parte de la clave primaria además de ser clave ajena. Si además la relación tuviera atributos, estos atributos van en el que tiene el N. • Si la relación es M:N LA RELACIÓN SE CONVIERTE EN TABLA. La clave de esa tabla es la mezcla de las claves de los participantes. Todas ellas actúan además como claves ajenas. Si la relación tiene atributos los ponemos en esta tabla. 2.5.1 Transformación del modelo “Universidad” Se muestran en negrita las claves primarias. Publicación (Número, Título) EnCongreso(Número, Título, Tipo, FechaInicio, FechaFin, Lugar, País, Editorial) • Clave ajena: La pareja (Número,Título) es clave ajena sobre Publicación(Número,título) EnRevista(Número, Título, Nombre, Volumen, Editorial, PaginaInicio, PaginaFin) • Clave ajena: La pareja (Número,Título) es clave ajena sobre Publicación(Número,título) Línea (CódigoLínea, Nombre) Descriptor (Nombre) EntraEn(CódigoLínea, NombreDescriptor) • Clave ajena: CódigoLínea es clave ajena sobre Línea(Código) 22 Capítulo 2. Diseño de bases de datos
  • 27. Bases de datos, Versión 1.1 • Clave ajena: NombreDescriptor es clave ajena sobre Descriptor(Nombre) Cubre(Numero, Título, CodigoLinea) • Clave ajena: La pareja (Número,Título) es clave ajena sobre Publicación(Número,título) • Clave ajena: El atributo CodigoLinea es clave ajena sobre Linea(Codigo) Profesor (Nombre, apellidos, Despacho, Tlf) Doctor (Nombre, apellidos) NoDoctor (Nombre, apellidos, Nombre, apellidos) • Clave ajena: La segunda pareja (nombre,apellidos) es clave ajena sobre Doctor(Nombre, apellidos). Solo es clave ajena por ser una relación 1:n Produce (Nombre, apellidos, número, título, código) • Clave ajena: La pareja (nombre,apellidos) es clave ajena sobre Profesor(Nombre, apellidos). • Clave ajena: La pareja (número, título) es clave ajena sobre Publicación (número, título) • Clave ajena: El atributo Código es clave ajena sobre Línea(Código) Proyecto (CódigoProyecto, Nombre, Acrónimo, Presupuesto, programa, FechaInicio, Fechafin, Descripción, Nombre, apellidos) • Clave ajena: La pareja (nombre,apellidos) es clave ajena sobre Doctor(Nombre, apellidos). Solo es clave ajena por ser una relación 1:n. Por favor, téngase en cuenta que Doctor es la entidad que intervenía en la relación Y NO LA ENTIDAD PROFESOR. Participa (Nombre, apellidos, CodigoProyecto) • Clave ajena: La pareja (nombre,apellidos) es clave ajena sobre Profesor(Nombre, apellidos). • Clave ajena: El atributo CódigoProyecto es clave ajena sobre Proyecto(CodigoProyecto) 2.5.2 Transformación del modelo “Ajedrez” Partida (CódigoPartida, FechaInicio, Duración) Movimiento (CodigoPartida, Numero, CasillaOrigen, CasillaDestino) • Clave ajena: CodigoPartida es clave ajena sobre Partida(CodigoPartida) • Inciso: Según la regla de transformación 1:n, codigo partida debe ser ajena. Sin embargo una regla anterior nos ha dicho que debe formar parte de la clave primaria. Federacion(Nombre, Pais) Jugador (Nombre, apellidos, NumeroDeFederado, DireccionPostal, DireccionElectronica, NombreFederacion) • NombreFederacion es clave ajena sobre Federacion(Nombre) Enfrenta es una relación m:n. Se convierte en tabla. frenta(CodigoPartida,Nombre,Ap,Fecha,Vencedor, NombreBlancas, ApBlancas) En- • CodigoPartida es ajena sobre Partidas(CodigoPartida) • La pareja (Nombre, Apellidos) es clave ajena sobre Jugador(Nombre, Apellidos) • La pareja (NombreBlancas,ApellidoBlancas) es ajena sobre Jugador(Nombre,Apellidos) 2.5. Transformación de modelos E/R en modelos relacionales 23
  • 28. Bases de datos, Versión 1.1 • A tener en cuenta: esta tabla ilustra que un diseño mejor habría sido tener dos relaciones como “Se enfrenta con blancas” y “Se enfrenta con negras”. Aún así, habría que programar Torneo (NombreTorneo, NombreFed, Periodicidad,Cuantia) • NombreFed es clave ajena sobre Federación(Nombre) Edición (Numero, NombreTorneo,NombreFed, Nombre,Apellidos) • La pareja (NombreTorneo,NombreFed) neo(NombreTorneo,NombreFed) es clave ajena sobre Tor- • La pareja (Nombre,Apellidos) es clave ajena sobre Jugador(Nombre,Apellidos) En este punto debemos reformar la tabla partida y dejarla así • Partida (CódigoPartida, FechaInicio, Duración, NumeroEdicion, NombreTorneo, NombreFederacion) ◦ El trío (NumEdicion, NombreTorneo, NombreFederacion) es clave ajena sobre Edicion(NumEdicion,NombreTorneo,NombreFederacion) 2.5.3 Transformación del modelo “Fincas” Resuelto en la pizarra 2.6 Normalización Cuando se elabora un diseño de tablas, puede ocurrir que aún siga existiendo mucha redundancia. Al diseñar tablas se debe examinar la redundancia que pueda existir en ellas. Estas redundancias suelen ser visibles a simple vista: Dado un CP se puede deducir la Población. Estas redundancias adoptan un nombre muy concreto: “Dependencias funcionales” o tambien “implicaciones”. A veces, las dependencias funcionales implican varios campos en conjunto. Supongamos una tabla como esta Jugador (Nombre,ap, país) Cuando en una dependencia hay varios atributos se le llama “dependencia funcional completa”. Para eliminar una dependencia crearemos una tabla separada de la tabla inicial. En la nueva tabla pondremos estos campos: el implicante y los implicados La clave de la nueva tabla es el implicante (o los implicantes, si hay varios) En la tabla vieja se borran todos los implicados y el implicante se convierte en clave ajena sobre la nueva tabla. Recordemos un par de conceptos Clave primaria: es un atributo (o pareja, o trío) que sabemos que no se va a repetir. Clave candidata: es un atributo (o pareja) que PODRÍA ACTUAR COMO PRIMARIA pero no lo hemos elegido. Transitividad: supone que si “A implica B” y “B implica C”, automáticamente sabremos que “A implica C”. 24 Capítulo 2. Diseño de bases de datos
  • 29. Bases de datos, Versión 1.1 2.6.1 Primera forma normal (1FN) Una tabla está en 1FN si en cada atributo se prohíbe insertar más de un valor. 2.6.2 Segunda forma normal (2FN) Una tabla está en segunda forma normal si todos los campos tienen dependencia completa respecto a la clave. Supongamos una base de datos con una tabla como esta Compras(CodigoProveedor, CodigoProducto, NombreProducto, Cantidad). En esta tabla es fácil observar que hay una dependencia funcional pero no completa con respecto a la clave (CodigoProveedorProducto) sino parcial, de la forma “CodigoProducto implica Nombre”. 2.6.3 Tercera forma normal Una tabla está en 3FN si está en 2FN y además no hay dependencias transitivas. 2.6. Normalización 25
  • 30. Bases de datos, Versión 1.1 26 Capítulo 2. Diseño de bases de datos
  • 31. CAPÍTULO 3 Diseño físico 3.1 Introducción En general hemos seguido un proceso lógico en la creación de bases de datos. Tema 1: posibilidades Tema 2: Diseño • Análisis • Diseño E/R • Pasar a un diseño relacional • Normalización. 3.2 BBDD en Access 3.2.1 Interfaz “Vista de tabla” Access crea automáticamente un campo llamado ID que actuará como clave primaria. Este campo ID usará un tipo llamado “Autonumérico” Dicho campo es un número entero Se incrementa automáticamente cuando pasamos a otra fila. 3.2.2 Tipos de datos Access maneja los siguientes tipos de datos Texto Acepta letras, números y símbolos pero solo acepta conjuntos de longitud pequeña (255 símbolos máximo) 27
  • 32. Bases de datos, Versión 1.1 Memo Acepta textos largos. Fecha Permite manejar datos relacionados con las fechas y con sus intervalos. Numéricos Se reservan para datos para los cuales se deseen hacer operaciones matemáticas. Los tipos numéricos pueden concretarse aún más: Byte: acepta números en el rango 0-255 Enteros cortos: números entre -32767 y 32768 Entero largo: a nivel interno usa 32 bits (-2^32 hasta 2^32) Decimal: acepta decimales al nivel que le indiquemos Simple: acepta negativos y decimales de precisión variable Doble: acepta negativos y decimales muchísimo más grandes y con mucha más precisión decimal En general la regla es: “cuanto más corto es el campo más rápido se procesa pero menos precisión nos ofrece” Sí/No Reservado para valores lógicos (True/False) 3.2.3 Formato de datos Se puede controlar la apariencia que tendrán los datos en pantalla, por ejemplo, una fecha puede mostrarse como 13-2-85 o 13/2/1985 Formato de la fecha En el formato de la fecha se deben usar tres símbolos básicos para manejar el día, el mes y el año,que son respectivamente d, m y a d-m-aa: Escribe algo como “1-3-81” d-m-aaaa: Escribe algo como “1-3-1981” d-mmm-aaaa: Escribe algo como “1-Mar-1981” dd-mmm-aaaa: Escribe la fecha “01-Mar-1981” dd-mm-aaaa: Escribe la fecha “01-03-1981” dd/mm/aaaa: Escribe la fecha “01/03/1981” dd/mmmm/aaaa: Escribe la fecha “01/Marzo/1981” 28 Capítulo 3. Diseño físico
  • 33. Bases de datos, Versión 1.1 hh:nn:ss dd/mmmm/aaaa: Escribe la fecha “01/Marzo/1981” Formato de cadenas El único símbolo de interés es @ @@-@@ Coge los dos primeros símbolos y los separa de los dos segundos por un guión. “Desde “@@” hacia “@@ Formato de números Para modificar la presentación de los números se utiliza el símbolo 0. 000,00: “Extraer un número de 3 cifras, si no lo hay se rellena con ceros, y despues extraer dos decimales. Mostrar eso en pantalla” 3.2.4 Máscaras de entrada Hemos dicho que el formato cambia la forma de mostrar las cosas en pantalla (pero no cambia como se almacenan por dentro). Sin embargo a veces es importante intentar evitar que se almacenen datos incorrectos. Para indicar a Access las máscaras de entrada, usaremos estos códigos 0: Es obligatorio insertar una cifra en esa posición L: Es obligatorio insertar una letra en esa posición 9: Es optativo insertar algo, pero si se hace que sea una cifra ?: Es optativo insertar algo, pero si se hace que sea una letra A: Es obligatorio insertar algo aquí y puede ser una letra o un número. a: Es optativo insertar algo aquí y puede ser una letra o un número. Ejercicio: ¿como sería la máscara que permite a la gente insertar su DNI con o sin letra? Solución: 90000000? Ejercicio: ¿como sería la máscara de entrada de un campo login que puede tener 3-4 letras seguidas de 4-5 números? Solución: la solución sería ?LLL00009 (se recomienda dejar los elementos optativos en las “esquinas”). Ejercicio: ¿como sería la máscara de entrada de un campo password, donde se obliga a que la clave tenga entre 8 y 12 símbolos que pueden ser letras o números? Solución: AAAAAAAAaaaa 3.2.5 Título El título es lo que se mostrará en los formularios. Se puede dejar en blanco. 3.2. BBDD en Access 29
  • 34. Bases de datos, Versión 1.1 3.2.6 Valor predeterminado Es un valor que Access puede insertar automáticamente para casos de tablas donde la mayor parte de registros tienen el mismo valor. 3.2.7 Regla de validación Es más potente que una máscara de entrada, ya que permite indicar condiciones que los datos deben cumplir antes de ser insertados 3.2.8 Texto de validación Es el texto que aparecerá cuando la regla no se cumple. 3.2.9 Requerido Nos indica si es obligatorio que haya dentro del campo o si por el contrario puede estar vacío. 3.2.10 Indexado Indica si el campo deberá estar en un índice de la base de datos. Un índice es un archivo de la base de datos que el programa puede utilizar para hacer búsquedas más deprisa. No fabricaremos un índice para todos los campos ya que el proceso puede ser lento y ocupar mucho espacio. Puede ser la primera y mejor opción cuando los usuarios se quejan de que las búsquedas son lentas. 3.2.11 Compresión Unicode Permite seguir utilizando un solo byte por símbolo a pesar de que utilicemos Unicode (que utiliza de 2 a 4 bytes por símbolo) 3.2.12 Modo IME IME significa Input Method Editor, y especifica los diversos sistemas existentes para introducir símbolos. Es relevante solamente en casos como el uso de lenguajes asiáticos y similares. 3.2.13 Oraciones IME Permite controlar como Access va a procesar las frases en otros idiomas. 3.2.14 Etiquetas inteligentes Permite que Access procese de una forma especial diversos campos. Para ello debemos saber como funciona el vocabulario XML de Microsoft 30 Capítulo 3. Diseño físico
  • 35. Bases de datos, Versión 1.1 3.2.15 Alineación Controla como aparecerá el texto: alineado a la derecha, a la izquierda, distribuido (justificado). Los puntos del 11 al 15 no entran en examen. 3.3 Claves ajenas Access denomina a este concepto “Relaciones”. Para indicar que un campo es clave ajena sobre otro, se deberá acudir a este menú y arrastrar la clave ajena sobre la primaria. Se denomina integridad referencial a la capacidad del SGBD de obligar a que los datos de una tabla existan previamente en otra. Cuando se conectan campos y la clave ajena es autonumérica se está cometiendo un error, ya que Access intentaría cambiar los valores sin ceñirse a la clave primaria. Al crear una clave ajena se pueden hacer cumplir dos condiciones extrar 1. Actualización en cascada: si alguien cambia la clave primaria, el que se marcó como clave ajena cambiará automáticamente 2. Borrado en cascada: si alguien borra el registro de la clave primaria, los registros asociados en la clave ajena se borrarán también. No siempre es necesario hacer esto. 3.4 MySQL 3.4.1 Comandos básicos Mostrar las bases de datos en el servidor: show databases; Utilizar una BD a partir de un instante dado: use cdcol; Mostrar las tablas de una base de datos: show tables; Mostrar las descripciones detalladas de las tablas: desc user; 3.4.2 Creación de bases de datos y tablas El comando para crear una base de datos: create database <nombre>. Sin embargo la creación de una tabla es un proceso complejo. create table publicacion ( numero int, titulo char(60) ); create table <nombre> ( <campo1> <tipo de datos> , <campo2> <tipo de datos> , ... 3.3. Claves ajenas 31
  • 36. Bases de datos, Versión 1.1 <campo20> <tipo de datos> ); 3.4.3 Tipos de datos en MySQL Los tipos pueden ser Numéricos: pueden ser unsigned o no • Enteros: no aceptan decimales ◦ TINYINT: -128,+127 O 0-255 ◦ SMALLINT: -32768,32767 O 0-65535 ◦ INT -2100 millones, 2100 millones o 0-4200 millones ◦ BIGINT: -2^63, 2^63 o 0-2^64 • Decimales: sí aceptan parte fraccionarios ◦ DECIMAL (c, d): la c indica el total de cifras, y la d indica cuantas de ellas serán decimales. Así, DECIMAL (10,2) nos da un número con 10 cifras en total y dos de ellas decimales, es decir, que tenemos 8 cifras para la parte entera. ◦ FLOAT: hasta 8 decimales ◦ DOUBLE: hasta 12 decimales Cadenas • CHAR(x): la x indica la longitud máxima de la cadena. Reserva el espacio aunque no se utilice. Son más rápidos de procesar pero gastan más espacio. • VARCHAR(x): la x indica un máximo que no se puede sobrepasar pero si no se usa ese máximo el resto del espacio está libre. Son más lentos de procesar pero ahorran espacio. Fechas • DATE: almacena fechas en formato ‘aaaa-mm-dd’ • TIME: almacena tiempos en formato ‘hh:mm:ss:fraccion’ • DATETIME: almacena fechas junto con las horas en formato predefinido ‘aa-mm-dd hh:mm:ss’ • TIMESTAMP: es una marca de tiempo gestionada por el SGBD y no se puede modificar directamente. BLOB: Binary Large OBjects. 3.4.4 Claves en MySQL En MySQL se pueden definir indicaciones de como se va a comportar un campo: Clave primaria: es un conjunto de campos cuyo valor no se puede repetir. Además, las claves primarias suponen crear automáticamente un índice. 32 Capítulo 3. Diseño físico
  • 37. Bases de datos, Versión 1.1 use ... ; drop table empleado; create table empleado ( dni char(10), nombre varchar(60), apellidos varchar(120), primary key (dni) ); insert into empleado values ( "5678123W", "Juan", "Ramirez Diaz" ); insert into empleado values ( "1234567Z", "Angel", "Sanchez Gomez" ); insert into empleado values ("5678123W", "Tomas", "Perez Perez"); select * from empleado; Una alternativa sería utilizar como clave primaria un conjunto de campos create table empleado ( dni char(10), nombre varchar(60), apellidos varchar(120), primary key (nombre, apellidos) ); insert into empleado values ( "10X", "Juan", "Gomez Gomez" ); insert into empleado values ( "10X", "Angel", "Gomez Gomez" ); insert into empleado values ( "20Z", "Juan", "Gomez Gomez" ); Clave ajena create table empleado ( dni char(10), 3.4. MySQL 33
  • 38. Bases de datos, Versión 1.1 nombre varchar(60), apellidos varchar(120), primary key (nombre, apellidos) ); create table sueldos ( dni char(10), sueldo decimal(6,2), primary key (dni), foreign key (dni) references empleado (dni) ); insert into sueldos values ("99Q", 950.45); insert into sueldos values ("1234567Z", 950.45); insert into sueldos values ("5678123W", 1430.91); 3.4.5 Resolución del modelo de tablas “Universidad” create table publicacion ( titulo varchar(100), numero smallint, primary key (titulo, numero) ); create table encongreso ( titulo varchar(100), numero smallint, fechainicio date, fechafin date, primary key (titulo, numero), foreign key (titulo, numero) references publicacion (titulo,numero) ); create table enrevista( titulo varchar(100), numero smallint, nombre varchar(50), volumen smallint, editorial varchar(30), paginainicio smallint, paginafinal smallint, primary key (titulo,numero), foreign key (titulo,numero) references publicacion(titulo,numero) ); create table lineas ( codigolinea smallint unsigned, nombre varchar(200), 34 Capítulo 3. Diseño físico
  • 39. Bases de datos, Versión 1.1 primary key (codigolinea) ); create table descriptor ( nombre varchar(220), primary key (nombre) ); /* Ojo: esta definición estaría mal porque los tipos de datos no coinciden. -O codigolinea arriba es un int, o aqui lo cambiamos para que sea smallint unsigned -O nombre lo ponemos aqui como varchar(200) o arriba ponemos varchar(80)*/ create table entraen ( codigolinea int, nombredescriptor varchar(80), primary key (codigolinea, nombredescriptor), ); create table entraen ( codigolinea smallint unsigned, nombredescriptor varchar(220), primary key (codigolinea, nombredescriptor), foreign key(codigolinea) references lineas(codigolinea), foreign key (nombredescriptor) references descriptor(nombre) ); create table cubre ( numero smallint, titulo varchar(100), codigolinea smallint unsigned, primary key (numero, titulo, codigolinea), foreign key (titulo, numero) references publicacion(titulo, numero), foreign key (codigolinea) references lineas(codigolinea) ); create table profesor ( nombre varchar(80), apellidos varchar(140), despacho smallint unsigned, tlf varchar(25), primary key (nombre, apellidos) ); create table doctor 3.4. MySQL 35
  • 40. Bases de datos, Versión 1.1 ( nombre varchar(80), apellidos varchar(140), primary key (nombre, apellidos), foreign key (nombre, apellidos) references profesor(nombre, apellidos) ); create table nodoctor ( nombre_nodoctor varchar(80), apellidos_nodoctor varchar(140), nombre_doctor varchar(80), apellidos_doctor varchar(140), primary key (nombre_nodoctor, apellidos_nodoctor), foreign key (nombre_nodoctor, apellidos_nodoctor) references profesor(nombre, apellidos), foreign key (nombre_doctor, apellidos_doctor) references doctor(nombre, apellidos) ); create table produce ( nombre varchar(80), apellidos varchar(140), titulo varchar(100), numero smallint, codigo smallint unsigned, primary key (nombre, apellidos, titulo, numero, codigo), foreign key (nombre, apellidos) references profesor(nombre, apellidos), foreign key (titulo, numero) references publicacion(titulo, numero), foreign key (codigo) references lineas(codigolinea) ); create table proyecto ( codigo int, nombre varchar(150), acronimo varchar(15), primary key (codigo) ); create table participa ( nombre varchar(80), apellidos varchar(140), codigoproyecto int, primary key (nombre,apellidos,codigoproyecto), foreign key (codigoproyecto) references proyecto(codigo), foreign key (nombre,apellidos) references profesor(nombre,apellidos) 36 Capítulo 3. Diseño físico
  • 41. Bases de datos, Versión 1.1 ); 3.4.6 Resolución del modelo “Ajedrez” create database ajedrez; use ajedrez; create table partida ( codigo int, fechainicio date, duracion_minutos smallint unsigned, primary key (codigo) ); create table movimiento ( codigopartida int, numero int, casillaorigen char(2), casilladestino char(2), primary key (codigopartida, numero), foreign key (codigopartida) references partida(codigo) ); create index ind_casilla_origen on movimiento(casillaorigen); create table federacion ( nombre varchar(120), pais varchar(80), primary key (nombre) ) tablespace ts_disco_lento; create table jugador ( nombre varchar(80), apellidos varchar(140), email varchar(120), dir_postal varchar(200), num_federado int, nombre_federacion varchar(120), primary key (nombre,apellidos), foreign key (nombre_federacion) references federacion(nombre) ) tablespace ts_disco_lento; 3.5 Tablespaces y undo files Los “undo files” son archivos utilizados por el SGBD para anotar los hechos que van teniendo lugar (por ejemplo, al sacar dinero de un cajero). Si algo va mal, el SGBD puede utilizar dichos ficheros para 3.5. Tablespaces y undo files 37
  • 42. Bases de datos, Versión 1.1 deshacer operaciones por completo. Para crear un log en la base de datos que se almacene en un archivo “logs” en un directorio cualquiera podemos hacer lo siguiente. Además, es obligatorio elegir un sistema interno a utilizar al almacenar los datos. Hoy en día, el “engine” InnoDB es el más actual. create logfile group logs_ajedrez add undofile "D:oscarlogs" engine=innodb; create tablespace ts_disco_lento add datafile "d:oscarlento" use logfile group logs_ajedrez engine=InnoDB; 38 Capítulo 3. Diseño físico
  • 43. CAPÍTULO 4 Consultas SQL 4.1 Introducción Las consultas, las sentencias SELECT se apoyan sobre dos conceptos matemáticos denominados Algebra relacional Cálculo relacional 4.2 La sentencia SELECT La sentencia SELECT permite extraer datos de las tablas en base a condiciones muy diversas. La operación más básica que podemos hacer es extraer todo lo que hay en una tabla. select select select select * * * * from from from from proveedores; partes; proyectos; suministra; 4.3 Condiciones Muy a menudo no necesitaremos mostrar todos los datos de la tabla, sino solo algunos que se especificarán mediante condiciones. Si por ejemplo, deseáramos mostrar solo los proveedores cuya ciudad sede está en París haríamos algo como esto. select * from proveedores where ciudad="Paris"; Otra posible consulta sería “mostrar todos los proveedores cuyo estado tiene el codigo 10” select * from proveedores where estado=10; 39
  • 44. Bases de datos, Versión 1.1 Las condiciones pueden ser muy complejas, y se pueden construir utilizando los operadores AND y OR. Por ejemplo, “mostrar todos los proveedores cuya ciudad es Londres y su estado es 10”. select * from proveedores where ciudad="Londres" and estado=10; Mostrar las partes cuyo peso es mayor de 15. select * from partes where peso>19; No es obligatorio mostrar todos los campos, se pueden mostrar solamente algunos de ellos indicando su nombre. Por ejemplo, “mostrar el nombre de proveedor y la ciudad de los proveedores cuyo estado sea 20”. select nombreprov, ciudad from proveedores where estado=20; ¿Qué mostrará la siguiente consulta? select nombreprov from proveedores where estado<=10 and estado>=20; La respuesta es que no se muestra nada. La condición está mal escrita ya que no puede haber un número que sea menor de 10 y a la vez mayor de 20. Mostrar los nombres de proveedores cuyo estado sea 10 y su ciudad Paris o Londres. Un primer intento sería este .. code-block:: mysql select nombreprov from proveedores where estado=10 and (ciudad=”Paris” or ciudad=”Londres”); Sin embargo, no funciona correctamente. La propia pregunta es ambigua Una posibilidad es que la pregunta fuera así “Mostrar los nombres de proveedores cuyo estado sea 10 y (su ciudad Paris o Londres).” La otra posibilidad es que la pregunta fuera así “Mostrar los nombres de proveedores cuyo (estado sea 10 y su ciudad Paris) o Londres.” Es importante recordar que cuando en una condición hay tres o más elementos de comparación puede que sea necesario utilizar paréntesis. Mostrar las partes rojas o verdes que pesen 17 o más. Esta pregunta debe aclararse antes de resolverse. Mostrar las partes siempre que pesen 17 o más y que luego cumplan una de estas dos: tener color rojo o tener color verde. “Mostrar las partes (rojas o verdes) que pesen 17 o más.” Mostrar las partes que siendo verdes pesen 17 o más o si no que simplemente sean rojas. 40 Capítulo 4. Consultas SQL
  • 45. Bases de datos, Versión 1.1 “Mostrar las partes rojas o (verdes que pesen 17 o más).” Normalmente, se suele asumir la primera pregunta, que se resuelve así select * from partes where peso>=17 and (color="Rojo" or color="Verde"); select * from partes where (color="Rojo" or color="Verde") and peso>=17; 4.4 Consultas con agregados Se denomina agregado a alguna función de tipo estadístico aplicada a un subconjunto de los datos de una tabla. 4.4.1 Recuento La función COUNT nos dice cuantas filas cumplen una cierta condición. No es obligatorio poner dicha condición. select count(*) from partes; Si deseáramos una condición como por ejemplo “hacer el recuento de partes cuyo color sea Azul” select count(*) from partes where color="Azul"; ¿Cuantas partes hay que no sean rojas? select count(*) from partes where color<>"Rojo"; ¿Cuantos proveedores hay cuya ciudad sea Londres? select count(*) from proveedores where ciudad="Londres"; ¿Cuantas partes hay que sean rojas y pesen más de 16? select count(*) from partes where peso>16 and color="Rojo"; ¿Cuantos proyectos hay en Madrid? select count(*) from proyectos where ciudad="Madrid"; 4.4. Consultas con agregados 41
  • 46. Bases de datos, Versión 1.1 4.4.2 Promedio Esta función calcula la media aritmética de las filas que cumplan una cierta condición. Tampoco es obligatorio poner la condición. La función promedio en SQL es AVG(*) ¿Cual es el peso medio de las partes? select avg(peso) from partes; ¿Cual es la media de peso de la partes azules? select avg(peso) from partes where color="Azul"; 4.4.3 Máximos y mínimos Son operaciones que nos devuelven el valor más grande o más pequeño de entre los que cumplan una condición. Estas funciones en SQL son MAX(campo-numérico) MIN(campo-numérico) ¿Cual es peso más grande de alguna parte? select max(peso) from partes; ¿Cual es el peso más pequeño de alguna parte? 4.4.4 Sumas La operación SUM(campo-numérico) efectúa la suma de ese campo para las filas que cumplan una cierta condición. ¿Cuantas partes en total ha suministrado el proveedor v1? select sum(cantidad) from suministra where numprov="v1"; ¿Cuantas partes ha recibido el proyecto y1? select sum(cantidad) from suministra where numproyecto="y1"; ¿Cuantas partes p2 ha suministrado el proveedor v2? select sum(cantidad) from suministra where numparte="p2" and numprov="v2"; 42 Capítulo 4. Consultas SQL
  • 47. Bases de datos, Versión 1.1 4.4.5 Múltiples agregados A veces no se hará una sola operación matemática sino muchas. En ese caso es muy importante indicar a SQL en base a qué debe hacer los resultados, o lo que es lo mismo como agrupar antes de hacer las operaciones. En SQL se indicarán los grupos sobre los cuales se va a hacer cada operación mediante la cláusula GROUP BY (campo). Además, al hacer un “group by” es obligatorio también seleccionar el campo por el que se hacen los grupos. La respuesta a una pregunta como:”¿Cual es la media de peso de las partes por color?” select avg(peso), color from partes group by (color); ¿Cual es la media de los pesos en función del nombre de parte? select avg(peso), nombreparte from partes group by (nombreparte); ¿Cuantos proveedores hay en cada ciudad? select count(*), ciudad from proveedores group by (ciudad); ¿Cual es la media de suministros por cada proveedor? select avg(cantidad), numprov from suministra group by (numprov); ¿Cual es la media de pesos de las piezas rojas o verdes? select avg(peso), color from partes where color="Rojo" or color="Verde" group by (color); 4.4.6 Condiciones de los agregados Los agregados pueden llevar sus propias condiciones: NO VAN CON EL WHERE Van por separado utilizando HAVING El HAVING debe ir despues del GROUP BY “Mostrar cuantos proveedores hay por ciudad, pero solo cuando haya dos o más” La primera parte de este ejercicio es igual que el anterior. Sacamos cuantos proveedores hay por ciudad select count(*), ciudad from proveedores group by (ciudad); 4.4. Consultas con agregados 43
  • 48. Bases de datos, Versión 1.1 Si ahora deseamos mostrar solo aquellos cuyo recuento sea mayor o igual que 2 debemos añadir una cláusula HAVING como esta select count(*), ciudad from proveedores group by (ciudad) having count(*)>=2; El WHERE es una condición que se aplica antes de hacer los cálculos. Sin embargo, si una vez hechos los cálculos no deseamos mostrarlos todos deberemos utilizar el HAVING. “Mostrar cuantos tornillos hay en total” Al hacer esta consulta se pueden cometer varios errores, como por ejemplo este, que muestra todas las partes select count(*), nombreparte from partes group by nombreparte; Esto no es exactamente un error, sino más bien una trampa: se hizo el recuento a mano y se hizo trampa Error: En este caso se ha confundido el where con el having select count(*), nombreparte from partes group by nombreparte having nombreparte="Tornillo"; Pregunta: ¿Podríamos quitar el group by? Respuesta: aunque en este caso sí podríamos no se debe hacer. Cuando nos pidan una operación matemática por grupos, debemos poner group by select count(*), nombreparte from partes where nombreparte="Tornillo" group by nombreparte 4.5 Consultas multitabla En ocasiones la información que nos pidan puede que esté dispersa por distintas tablas. SQL ofrece un mecanismo para “conectar” tablas y así poder hacer las comparaciones que nos pidan. Por ejemplo, si nos piden el nombre de las partes suministradas en una cantidad >=500 descubriremos que El nombreparte está en la tabla partes La cantidad esta en la tabla suministra Las tablas partes y suministra tienen un campo en común, el campo numparte Utilizando una cláusula denominada “inner join” SQL puede establecer las correspondencias correctas entre dos o más tablas. Cruce de datos entre las tablas partes y suministra basándonos en que el campo numparte de suministra debe ser igual que el numparte de suministra De aqui sacamos solamente los campos que nos piden 44 Capítulo 4. Consultas SQL
  • 49. Bases de datos, Versión 1.1 4.6 Algunos ejercicios resueltos 1. Deseamos saber los numeros de proveedor que realizan suministros select numprov from suministra; 2. Deseamos saber los numeros de proveedor que realizan suministros pero sin que se muestren repetidos select distinct numprov from suministra; 3. Sumar las cantidades que se han suministrado (¿cuantas piezas se han suministrado?) select sum(cantidad) from suministra; 4. Se desea ver la suma de las distintas cantidades de partes suministradas select sum(cantidad),numparte from suministra group by numparte; 5. Se desea saber las cantidades totales que ha suministrado cada proveedor select sum(cantidad),numprov from suministra group by numprov; 6. Cantidades totales suministradas por v1 y v4 select sum(cantidad), numprov from suministra where numprov=’v1’ or numprov=’v4’ group by (numprov); 7. Mostrar los numeros de parte suministrados en una cantidad total mayor o igual que 1000 select sum(cantidad), numparte from suministra group by (numparte) having sum(cantidad)>=1000; 8. Mostrar la suma de las partes suministradas por v1, v2, o v3 en una cantidad mayor de 550 select sum(cantidad),numparte from suministra where numprov=’v1’ or numprov=’v2’ or numprov=’v3’ group by (numparte) having sum(cantidad)>550; 9. Mostrar cuantos proveedores hay en Londres select count(*) from proveedores where ciudad=’Londres’; 10. ¿Cuantas partes rojas hay? select count(*) from partes where color="Rojo"; 11. ¿Qué colores están repetidos en las partes? 4.6. Algunos ejercicios resueltos 45
  • 50. Bases de datos, Versión 1.1 select count(*),color from partes group by color having count(*)>=2; 4.7 Subconsultas Al hacer consultas hemos observado que hay cláusulas que permiten establecer condiciones. Al hacer las condiciones es posible que necesitemos hacer una “subpregunta” y que la sentencia SELECT quede algo así select .... from ... where campo>(select max(cantidad) from suministra) Supongamos una pregunta como la siguiente: “¿Cuales son los nombres de parte que pesan lo mismo que la parte más pesada?” Podemos sacar el peso maximo con esta consulta select max(peso) from partes; select nombreparte from partes where peso>=(select max(peso) from partes); ¿Qué nombres de parte pesan más que la media? Se saca la media select avg(peso) from partes; select * from partes where peso>=(select avg(peso) from partes); Dentro de las subconsultas, aparte de las comparaciones típicas como >, >=, <>, <=, <, etc... existen otros elementos para hacer comparaciones EXISTS: nos dará las filas donde exista alguna fila que cumpla la condición ALL: la condición deben cumplirla todas las filas 12. ¿Qué nombres de parte corresponden a una pieza azul o almacenada en París? select nombreparte from partes where color="Azul" or ciudad="Paris" 13. ¿Qué colores tienen las distintas partes que no sean tornillos? select * from partes where nombreparte<>"Tornillo"; 14. ¿Cuantos proveedores hay que no tengan su almacén en Atenas? select count(*) from proveedores where ciudad<>"Atenas"; 15. ¿Qué nombres de parte se suministran en una cantidad mayor o igual de 400? 46 Capítulo 4. Consultas SQL
  • 51. Bases de datos, Versión 1.1 select nombreparte,cantidad from partes inner join suministra on partes.numparte=suministra.numparte where cantidad>=400; 16. ¿Qué proveedores suministran partes en una cantidad <300? Por un lado, el nombre de proveedor está en la tabla proveedores, que podemos ver haciendo esta consulta select * from proveedores; numprov v1 v2 v3 v4 v5 nombreprov Smith Jones Blake Clarke Adams estado 20 10 30 20 30 ciudad Londres Paris Paris Londres Atenas Sin embargo, las cantidades de suministro están en la tabla suministra que podemos ver ejecutando esta consulta select * from suministra; numprov v1 v1 v2 v2 v2 v2 v2 v2 v2 v2 v3 v3 v4 v4 v5 v5 v5 v5 v5 v5 v5 v5 v5 numparte p1 p1 p3 p3 p3 p3 p3 p3 p3 p5 p3 p4 p6 p6 p1 p2 p2 p3 p4 p5 p5 p6 p6 numproyecto y1 y4 y1 y2 y3 y4 y5 y6 y7 y2 y1 y2 y3 y7 y4 y2 y4 y4 y4 y4 y5 y2 y4 cantidad 200 700 400 200 300 500 600 400 600 100 200 500 300 300 100 200 100 200 800 400 500 200 500 Como la información está dispersada, necesitamos cruzar las tablas con un inner join teniendo en cuenta que tienen un campo igual, en este caso el campo numprov. Podemos “hacer el cruce” haciendo un inner join con esta consulta select * from proveedores inner join suministra on proveedores.numprov=suministra.numprov; 4.7. Subconsultas 47
  • 52. Bases de datos, Versión 1.1 Cuyo resultado es que se cruzan los datos correctamente y se obtiene una tabla como esta numprov v1 v1 v2 v2 v2 v2 v2 v2 v2 v2 v3 v3 v4 v4 v5 v5 v5 v5 v5 v5 v5 v5 v5 numparte p1 p1 p3 p3 p3 p3 p3 p3 p3 p5 p3 p4 p6 p6 p1 p2 p2 p3 p4 p5 p5 p6 p6 numproyecto y1 y4 y1 y2 y3 y4 y5 y6 y7 y2 y1 y2 y3 y7 y4 y2 y4 y4 y4 y4 y5 y2 y4 cantidad 200 700 400 200 300 500 600 400 600 100 200 500 300 300 100 200 100 200 800 400 500 200 500 numprov v1 v1 v2 v2 v2 v2 v2 v2 v2 v2 v3 v3 v4 v4 v5 v5 v5 v5 v5 v5 v5 v5 v5 nombreprov Smith Smith Jones Jones Jones Jones Jones Jones Jones Jones Blake Blake Clarke Clarke Adams Adams Adams Adams Adams Adams Adams Adams Adams estado 20 20 10 10 10 10 10 10 10 10 30 30 20 20 30 30 30 30 30 30 30 30 30 Si ponemos la condición que nos falta el ejercicio se resuelve correctamente select nombreprov,cantidad from proveedores inner join suministra on proveedores.numprov=suministra.numprov where cantidad<300 order by nombreprov desc; 17. ¿Cuantos proveedores suministran partes en una cantidad <300? Para orientarnos, extraemos las filas en las que la cantidad es menor de 300 select numprov from suministra where cantidad<300; Si hacemos el recuento, observaremos que hay 9 filas, pero proveedores reales solo están v1, v2, v3 y v5. select count(numprov) from suministra where cantidad<300; Si ponemos distinct, no nos repetirá los proveedores select distinct numprov from suministra where cantidad<300; Por tanto la solución pasa por hacer el recuento 48 Capítulo 4. Consultas SQL ciudad Londres Londres Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Londres Londres Atenas Atenas Atenas Atenas Atenas Atenas Atenas Atenas Atenas
  • 53. Bases de datos, Versión 1.1 de los distintos numprov select count(distinct numprov) from suministra where cantidad<300; 18. ¿Qué nombre tienen las partes suministradas en una cantidad total de 550 o más? select sum(cantidad), partes.numparte,nombreparte from suministra inner join partes on suministra.numparte=partes.numparte group by (partes.numparte) having sum(cantidad)>=550; 19. ¿Qué nombres de parte suministran los distintos proveedores? select nombreprov, nombreparte from proveedores inner join suministra on suministra.numprov=proveedores.numprov inner join partes on partes.numparte=suministra.numparte; 20. Queremos saber los proveedores que están ubicados en el mismo sitio que alguna parte. Examinemos la tabla partes numparte p1 p2 p3 p4 p5 p6 nombreparte Tuerca Perno Tornillo Tornillo Leva Engranaje color Rojo Verde Azul Rojo Azul Rojo peso 12 17 17 14 12 19 ciudad Londres Paris Roma Londres Paris Londres Examinemos la tabla proveedores numprov v1 v2 v3 v4 v5 nombreprov Smith Jones Blake Clarke Adams estado 20 10 30 20 30 ciudad Londres Paris Paris Londres Atenas Se puede comprobar que no nos piden para nada datos de la tabla suministra. Lo único que se necesita es emparejar las filas donde las ciudades sean iguales. select nombreprov,nombreparte,partes.ciudad from partes inner join proveedores on partes.ciudad=proveedores.ciudad; 21. ¿Como se llaman las piezas que se suministran en la cantidad máxima? select nombreparte,max(cantidad) from suministra inner join partes on suministra.numparte=partes.numparte where cantidad=(select max(cantidad) from suministra); 4.7. Subconsultas 49
  • 54. Bases de datos, Versión 1.1 22. ¿Que numeros de proveedores suministran por encima de la media de suministros? select numprov, cantidad from suministra where cantidad > ( select avg(cantidad) from suministra ); Cuidado: si nos dijeran "suministran una cantidad total que esté por encima de la media", deberíamos sumar las cantidades por proveedor y compararlas con la media. select sum(cantidad), numprov from suministra group by numprov having sum(cantidad)> ( select avg(cantidad) from suministra ); 23. Números de parte suministradas en una cantidad media mayor de 450 select avg(cantidad),numparte from suministra group by numparte having avg(cantidad)>450; 24. ¿Cual es el peso medio de las partes? select avg(peso) from partes; 25. Obtener el nombre de los provedores, el nombre de parte que suministran y la cantidad en que suministran select nombreprov, nombreparte,cantidad from proveedores inner join suministra on suministra.numprov=proveedores.numprov inner join partes on suministra.numparte=partes.numparte 26. Obtener las parejas de proveedores que NO están en la misma ciudad select prov1.numprov, prov1.ciudad, prov2.numprov, prov2.ciudad from proveedores as prov1 inner join proveedores as prov2 where prov1.ciudad<>prov2.ciudad; 27. Mostrar suministros donde el proveedor y la parte hayan resultado ser de una ciudad distinta select suministra.numprov, suministra.numparte, proveedores.ciudad, partes.ciudad from suministra inner join proveedores 50 Capítulo 4. Consultas SQL
  • 55. Bases de datos, Versión 1.1 on proveedores.numprov=suministra.numprov inner join partes on partes.numparte=suministra.numparte where proveedores.ciudad<>partes.ciudad; 28. ¿Cuantos proveedores suministran partes rojas o que pesen 12 gramos o más? Trozo 1: partes rojas select numparte from partes where color="Rojo" Trozo 2: partes que pesan 12 o mas select numparte from partes where peso>12; Partes que cumplen alguna de las dos cosas Los proveedores que hacen suministros están en el campo numprov de la tabla suministra select numprov from suministra; 29. ¿Cuantas piezas se han suministrado de cada ciudad de piezas? select sum(cantidad),ciudad from partes inner join suministra on suministra.numparte=partes.numparte group by (ciudad); 30. ¿De qué ciudad de proveedor ha salido la cantidad más grande de suministros?. Esta pregunta podría entenderse de dos formas “Obtener la cantidad más grande suministrada y la ciudad del proveedor correspondiente” En primer lugar necesitamos cruzar “proveedores” y suministra 4.7. Subconsultas 51
  • 56. Bases de datos, Versión 1.1 v1 v1 v2 v2 v2 v2 v2 v2 v2 v2 v3 v3 v4 v4 v5 v5 v5 v5 v5 v5 v5 v5 v5 p1 p1 p3 p3 p3 p3 p3 p3 p3 p5 p3 p4 p6 p6 p1 p2 p2 p3 p4 p5 p5 p6 p6 y1 y4 y1 y2 y3 y4 y5 y6 y7 y2 y1 y2 y3 y7 y4 y2 y4 y4 y4 y4 y5 y2 y4 200 700 400 200 300 500 600 400 600 100 200 500 300 300 100 200 100 200 800 400 500 200 500 v1 v1 v2 v2 v2 v2 v2 v2 v2 v2 v3 v3 v4 v4 v5 v5 v5 v5 v5 v5 v5 v5 v5 Smith Smith Jones Jones Jones Jones Jones Jones Jones Jones Blake Blake Clarke Clarke Adams Adams Adams Adams Adams Adams Adams Adams Adams 20 20 10 10 10 10 10 10 10 10 30 30 20 20 30 30 30 30 30 30 30 30 30 Londres Londres Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Londres Londres Atenas Atenas Atenas Atenas Atenas Atenas Atenas Atenas Atenas Una primera aproximación sería esta consulta select max(cantidad),ciudad from suministra inner join proveedores on suministra.numprov=proveedores.numprov; Sin embargo esto no funciona porque cualquier operación de agregado no involucra a ninguna fila. De hecho esa consulta nos devuelve un máximo correcto pero no nos devuelve la ciudad asociada, sino la primera que encuentra. Hay que encontrar otra forma de expresar esta consulta select ciudad from proveedores inner join suministra on suministra.numprov=proveedores.numprov where cantidad= ( select max(cantidad) from suministra ); La otra forma de entender la pregunta sería “Sumar las cantidades por proveedor y decir la ciudad del proveedor con la cantidad máxima” Una primera aproximación sería esta select ciudad from suministra inner join proveedores on suministra.numprov=proveedores.numprov group by (proveedores.numprov) 52 Capítulo 4. Consultas SQL
  • 57. Bases de datos, Versión 1.1 having sum(cantidad)>= ALL ( select sum(cantidad) from suministra group by (numprov) ) ; 31. ¿Qué ciudad de parte tiene la mayor media de suministros? Cruzamos suministra y partes select * from suministra inner join partes on suministra.numparte=partes.numparte Por otra lado, sacamos la media por partes de la tabla suministra select avg(cantidad) from suministra group by numparte; Si mezclamos la primera parte con la segunda select ciudad from suministra inner join partes on suministra.numparte=partes.numparte group by partes.numparte having avg(cantidad)>= ALL ( select avg(cantidad) from suministra group by numparte ); 32.Obtener todos los detalles de todos los proyectos select nombreprov, nombreparte,nombreproyecto,cantidad from suministra inner join proyectos on suministra.numproyecto=proyectos.numproyecto inner join partes on suministra.numparte=partes.numparte inner join proveedores on suministra.numprov=proveedores.numprov ; 33. Obtener todos los detalles de todos los proyectos ubicados en Londres. select nombreprov, nombreparte,nombreproyecto,cantidad from suministra inner join proyectos on suministra.numproyecto=proyectos.numproyecto 4.7. Subconsultas 53
  • 58. Bases de datos, Versión 1.1 inner join partes on suministra.numparte=partes.numparte inner join proveedores on suministra.numprov=proveedores.numprov where proyectos.ciudad="Londres" ; 34. Obtener los códigos de proveedor que suministran al proyecto Y1. select numprov from suministra where numproyecto=’y1’; 35. Obtener los datos de los proyectos que usan partes en cantidades comprendidas entre 300 y 750. select distinct proyectos.* from suministra inner join proyectos on suministra.numproyecto=proyectos.numproyecto where ( cantidad>=300 ) and ( cantidad<=750 ) order by proyectos.numproyecto ; 36. Obtener las combinaciones posibles parte-color Este ejercicio requiere tener dos copias de la misma tabla. Será necesario utilizar los alias para combinar la tabla partes consigo misma. select distinct p1.nombreparte, p2.color from partes as p1 inner join partes as p2; 37. Obtener los colores de las partes que se han suministrado por V1. select partes.color from suministra inner join partes on partes.numparte=suministra.numparte where numprov=’v1’; 38. Obtener la cantidad total de partes P1 usadas por parte de V1. Datos del proveedor v1 select * from suministra where numprov=’v1’; Suma de todas las partes de v1 select sum(cantidad) from suministra where numprov=’v1’ and numparte=’p1’; 54 Capítulo 4. Consultas SQL
  • 59. Bases de datos, Versión 1.1 39. Obtener las parejas de nombres de ciudad tales que un proveedor ubicado en la primera ciudad suministra a algún proyecto ubicado en la segunda ciudad. select proveedores.ciudad, proyectos.ciudad from suministra inner join proveedores on suministra.numprov=proveedores.numprov inner join proyectos on suministra.numproyecto=proyectos.numproyecto; 40. Obtener los códigos de parte suministrados a los proyectos ubicados en la misma ciudad del proveedor. select suministra.numparte from suministra inner join proyectos on suministra.numproyecto=proyectos.numproyecto inner join proveedores on suministra.numprov=proveedores.numprov where proveedores.ciudad=proyectos.ciudad; 41. Obtener los códigos de proyecto a los que suministra un proveedor que no está en la misma ciudad. select suministra.numproyecto from suministra inner join proveedores on proveedores.numprov=suministra.numprov inner join proyectos on proyectos.numproyecto=suministra.numproyecto where proyectos.ciudad<>proveedores.ciudad; 42. Obtener las parejas de partes suministradas por el mismo proveedor. select distinct s1.numparte,s2.numparte from suministra as s1 inner join suministra as s2 on s1.numprov=s2.numprov; 43. Obtener los códigos de parte suministrados a cualquier proyecto que esté ubicado en Londres select numparte from suministra inner join proyectos on suministra.numproyecto=proyectos.numproyecto where proyectos.ciudad="Londres"; 44. Obtener los códigos de proyecto que usan al menos una parte suministrada por el proveedor V1 4.7. Subconsultas 55
  • 60. Bases de datos, Versión 1.1 En primer lugar seleccionamos las partes suministradas por v1 select numparte from suministra where numprov=’v1’; En segundo lugar queremos saber los proyectos cuyas partes sean alguna de las que hemos extraído antes. select numproyecto from suministra where numparte in ( select numparte from suministra where numprov=’v1’ ); 45. Obtener los códigos de proveedor que suministran al menos una parte roja. Seleccionamos las partes cuyo color es rojo select numparte from partes where color="Rojo"; Ahora, en la tabla suministra sacamos las filas donde la parte sea alguna de las extraídas antes select numprov from suministra where numparte in ( select numparte from partes where color="Rojo" ); Una solución distinta select numprov from suministra inner join partes on suministra.numparte=partes.numparte where partes.color="Rojo"; 46. Obtener los códigos de proyecto cuya ciudad es la primera en la lista de ciudades. Seleccionamos la ciudad más pequeña select min(ciudad) from proyectos; select * from proyectos where ciudad in ( select min(ciudad) from proyectos ); Otra forma de hacerlo con inner join’s sería la siguiente select p1.numproyecto,p1.ciudad from proyectos as p1 inner join proyectos as p2 on p1.numproyecto=p2.numproyecto where p1.ciudad= ( select min(ciudad) from proyectos ); 56 Capítulo 4. Consultas SQL
  • 61. Bases de datos, Versión 1.1 47. Obtener los códigos de proyecto a los que se suministra la parte P1 en una cantidad promedio igual o superior a la cantidad más grande que se suministra al proyecto Y1. Extraemos la cantidad más grande del proyecto “y1” select max(cantidad) from suministra where numproyecto="y1"; Al haber una condición para el promedio deberemos poner algo como esto select numproyecto,avg(cantidad) from suministra where numparte=’p1’ group by numproyecto having avg(cantidad)>= ( select max(cantidad) from suministra where numproyecto="y1" ); 48. Obtener los códigos de proveedor de los que suministran la parte P1 a algún proyecto en una cantidad superior a la cantidad promedio de la parte P1 para ese proyecto. Podemos empezar intentando sacar la media de partes p1 para cada proyecto select numproyecto, avg(cantidad) from suministra where numparte=’p1’ group by numproyecto; Extraemos las filas de la tabla suministra donde la parte sea p1 select numprov from suministra as s1 where numparte=’p1’ and cantidad > ( select avg(cantidad) from suministra as s2 where numparte=’p1’ and s2.numproyecto=s1.numproyecto group by numproyecto ); 49. Obtener los códigos de proyecto a los que ningún proveedor de Londres suministra una parte roja. Primero averiguamos los proveedores de Londres que suministran partes rojas. select suministra.numprov from suministra inner join partes on partes.numparte=suministra.numparte inner join proveedores on proveedores.numprov=suministra.numprov where proveedores.ciudad="Londres" and partes.color="Rojo"; Ahora examinamos la tabla suministra y comprobamos que el proveedor no esté en el conjunto devuelto por la consulta anterior 4.7. Subconsultas 57
  • 62. Bases de datos, Versión 1.1 select * from suministra where numprov not in ( select suministra.numprov from suministra inner join partes on partes.numparte=suministra.numparte inner join proveedores on proveedores.numprov=suministra.numprov where proveedores.ciudad="Londres" and partes.color="Rojo" ); 50. ¿Hay algún proveedor que suministre la misma parte a TODOS los proyectos? Para conseguir la solución a este problema se deben utilizar algunas características de los cuantificadores. Replanteamos la pregunta “se desea saber los proveedores donde para todos los proyectos existe una misma parte suministrada” o más desarrollado “proveedores (de la tabla suministra) donde para todo proyecto (de la tabla proyectos) existe un suministro donde el codigo de proveedor es dicho proveedor y la parte es la misma parte que mirábamos en suministra” select numprov from suministra as s1 where not exists ( select numproyecto from proyectos where numproyecto not in ( select numproyecto from suministra as s2 where s1.numparte=s2.numparte and s1.numprov=s2.numprov ) ); 51. Obtener los códigos de proyecto que usan todas las partes suministradas por el proveedor v1 “Obtener los códigos de proyecto donde para toda parte de la tabla suministra existe una parte suministrada por v1” Obtener el conjunto de parte suministradas por v1. select numparte from suministra where numprov=’v1’; Las filas de la tabla suministra donde para toda parte de v1 existe alguna fila asociada 58 Capítulo 4. Consultas SQL
  • 63. Bases de datos, Versión 1.1 select numprov from suministra as s1 where not exists ( select numparte from suministra as s2 where numprov=’v1’ and not exists ( select numparte,numproyecto from suministra as s3 where s2.numparte=s3.numparte and s1.numproyecto=s3.numproyecto ) ); 52. (Para nota) Obtener los pares de proveedores V1 y V2 que suministren EXACTAMENTE el mismo conjunto de partes. La pregunta podría replantearse como “obtener parejas de proveedores donde para toda parte de un proveedor de la primera tabla existe otro proveedor distinto tal que la parte es la misma que la parte del primero”. 4.8 Actualización y borrado Una vez que se han insertado datos, estos no son inmutables. Pueden cambiarse valores de las filas o incluso pueden borrarse las filas. Estas operaciones se hacen con las sentencias UPDATE y DELETE. Para cambiar valores se hace lo siguiente UPDATE <TABLA> SET <CAMPO>=VALOR WHERE <CONDICION> Por ejemplo, si quisiéramos hacer que en la tabla partes se cambiara la ciudad Londres por Madrid haríamos algo como esto UPDATE partes SET ciudad="Madrid" WHERE ciudad="Londres"; Poner en la tabla partes el peso a 30 en todas las partes cuyo peso sea mayor que 16; update partes set peso=30 where peso>16; Poner a “Amarillo” el color de las partes de Paris update partes set color="Amarillo" where ciudad="Paris"; Para borrar datos DELETE FROM <TABLA> WHERE <CONDICION> Borrar todas las partes cuyo peso es 12 delete from partes where peso=12; 4.8. Actualización y borrado 59
  • 64. Bases de datos, Versión 1.1 60 Capítulo 4. Consultas SQL
  • 65. CAPÍTULO 5 Programación 5.1 Introducción Los elementos de los lenguajes de programación son muy similares entre sí y el cambio de lenguaje solamente supone la modificación de ciertos hábitos. En el entorno de las bases de datos se pueden encontrar programas que actúen mediante dos mecanismos distintos. Estos dos mecanismos se definen como Procedimientos almacenados: residen en el propio servidor de bases de datos. Programas externos: utilizando algún mecanismo los programas externos se comunican con el servidor para intercambiar datos mediante un lenguaje de programación cualquiera. Entre los mecanismos de comunicación más utilizados encontramos ODBC (Open DataBases Communication). Este estándar especifica claramente a servidores y cliente como tienen que dar o pedir datos. Una versión modificada de ODBC es JDBC que ha modernizado el estándar pero solo sirve para programas Java. 5.2 Procedimientos almacenados 5.2.1 Carga de programas Para cargar código almacenado en un fichero SQL externo se utiliza lo siguiente . d:oscart5prueba1.sql 5.2.2 Variables Una variable es una posición de memoria con nombre. Normalmente las variables conllevan un tipo que restringe lo que podemos almacenar en ella. En MySQL las variables se declaran con la palabra clave DECLARE. Los tipos utilizables con las variables son los mismos que tiene MySQL. 61
  • 66. Bases de datos, Versión 1.1 5.2.3 Declaración de procedimientos Los procedimientos en MySQL actúan igual que las funciones en Java con las diferencias en la sintaxis. El primer problema que aparece en los procedimientos MySQL viene dado por el hecho de que los procedimientos a veces interfieren con el delimitador ”;”. Para evitarlo, debemos avisar a MySQL de que durante un tiempo cambiaremos de delimitador, para ello se usa la siguiente sentencia Dentro de “código” podrán ir sentencias que terminarán de forma normal, con el punto y coma ”;” El problema viene dado porque el intérprete de MySQL intenta procesar todo lo que haya hasta llegar a un punto y coma. Si no cambiásemos el delimitador, se ejecutaría la definición del procedimiento sin haber encontrado un “end” y todo fallaría. Ejercicio: crear un procedimiento que acepte una cantidad c y que seleccione todos los suministros cuyo campo cantidad sea mayor que c delimiter // create procedure mayores (cant int) begin select * from suministra where cantidad>cant; end // delimiter ; Ejercicio: crear un programa que acepte un color co y una ciudad ci y que busque todas las partes cuyo color sea ese co pasado y la ciudad ese ci pasado. Co y ci son parámetros y NO LLEVAN COMILLAS delimiter // create procedure Color_parte (color_pasado varchar(20), ciudad_pasada varchar(20) ) begin select * from partes where color=color_pasado and ciudad=ciudad_pasada; end // delimiter ; Ejercicio: crear un procedimiento que permita sumar la cantidad de partes suministradas cuyo color sea el mismo que un cierto color pasado drop procedure suministradas_color; delimiter // create procedure suministradas_color ( color_pasado varchar(20) ) begin select sum(cantidad) 62 Capítulo 5. Programación
  • 67. Bases de datos, Versión 1.1 from suministra inner join partes on suministra.numparte=partes.numparte where color=color_pasado; end // delimiter ; call suministradas_color("Rojo"); call suministradas_color("Gris"); Ejercicio: crear un procedimiento que reciba dos cosas Color_pasado Nombre_prov_pasado El procedimiento deberá decirnos cuantas partes de ese color suministra ese nombre de proveedor. Ejercicio: crear un procedimiento que reciba dos cosas Nombre_parte_pasada Cantidad_pasada El procedimiento deberá decirnos cuantas partes con ese nombre han sido suministradas en una cantidad mayor o igual que la cantidad pasada drop procedure mayores_que; delimiter // create procedure mayores_que( nombre_parte_pasada varchar(11), cantidad_pasada int) begin select * from suministra inner join partes on suministra.numparte=partes.numparte where nombreparte=nombre_parte_pasada and cantidad>cantidad_pasada; end // delimiter ; 5.3 Sentencias básicas 5.3.1 Decisiones con IF La sintaxis de un IF es prácticamente igual a la de Java 5.3. Sentencias básicas 63