Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Versin 1.1
scar Gmez
Curso 2012-2013
ndice general
1. Introduccin
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
. 5
. 6
. 6
. 11
. 22
. 24
3. Diseo fsico
3.1. Introduccin . . . . . .
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. Introduccin . . . . . . . .
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. Actualizacin y borrado . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5. Programacin
61
5.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.2. Procedimientos almacenados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.3. Sentencias bsicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
I
5.4.
5.5.
5.6.
Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Funciones MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Solucin al examen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6. Administracin
6.1. Introduccin . . . . . . . . . . . .
6.2. Aspectos bsicos de las contraseas
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. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.2. El entorno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
8. BBDD Objeto relacionales
8.1. Introduccin . . . . . . . . . . . . . .
8.2. Instalacin de PostgreSQL . . . . . . .
8.3. Uso de Postgres en una mquina virtual
8.4. Funcionamiento bsico de Postgres . .
8.5. Comandos de Postgres . . . . . . . . .
8.6. Creacin de tipos de datos . . . . . . .
8.7. Soporte documental . . . . . . . . . .
8.8. Sistemas de informacin geogrfica . .
9. ndices y tablas
II
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
91
91
91
91
92
92
96
98
99
103
Contents:
ndice general
ndice general
CAPTULO 1
Introduccin
Captulo 1. Introduccin
CAPTULO 2
2.1 Introduccin
En general, la construccin 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 disea una estructura y realiza los clculos necesarios
para que todo se construya correctamente. En las bases de datos ocurre lo mismo: determinados negocios necesitarn una infraestructura de informacin muy sofisticada por lo que puede ser conveniente
disponer de unos planos que permitan la comunicacin entre los distintos miembros que participan en
un proyecto de desarrollo de un programa informtico.
Adems, 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 visin de
futuro exija una cierta documentacin de como se hizo un programa.
Por otro lado, un problema habitual para los desarrolladores informticos es la necesidad de conocer un
poco el dominio de conocimiento. Es decir, si se necesita construir una base de datos que almacene
informacin sobre impuestos, es muy probable que primero se necesite conocer un poco ms como
funciona ese mundo. El conocimiento que se obtenga junto a los requisitos que tenga el cliente deberan
plasmarse de alguna forma en un documento.
Al igual que la construccin de una casa requiere la elaboracin de planos y clculos el diseo de una
estructura de almacenamiento de datos requiere que exista un mecanism
Los diagramas como planos de una BBDD. Se utilizarn 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 informticos debemos intentar
adquirir el conocimiento del cliente para reflejarlo en una BD. En esencia debemos intentar extraer
la informacin RELEVANTE
Otro problema de gran importancia es la ambigedad. Se debe concretar al mximo el significado
de cada palabra o trmino especfico.
En suma, un informtico va a construir un modelo del conocimiento del cliente. La primera labor
a la hora de construir una BD es modelar la informacin.
2.3.1 Entidades
Se denomina entidad a cualquier elemento sobre el cual se desea almacenar informacin. 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 dbiles:
Una entidad fuerte es aquella que existe por s sola.
Una entidad dbil es aquella que requiere que otra entidad exista antes que ella.
Supongamos una situacin 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:
Dependencia en existencia: una entidad es dbil con dependencia en existencia si antes de poder
existir o almacenarse requiere que otra entidad exista primero.
Dependencia en identificacin: la entidad dbil no tiene clave propia sino que necesita la de otra
entidad.
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
Interrelacin binaria: se da entre dos entidades.
Interrelacin ternaria: se da entre tres entidades que participan de forma simultnea en una asociacin.
Interrelacin 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.5 Atributos
Se denomina atributos a propiedades de las entidades que tienen la importancia suficiente para almacenar
datos sobre ellas y que por tanto aparecern en el diagrama E/R.
Los atributos suelen tener un dominio: es decir un conjunto de valores del cual toman su informacin.
Un detalle sutil pero importante es que en ocasiones los atributos no son de las entidades, sino de las
relaciones. Ej: pensemos en el diseo E/R de un enunciado como este: un mecanico repara un coche en
una cierta fecha del ao. La informacin de un conjunto cualquiera de mecnicos podra ser la siguiente
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 reparacin en la entidad Mecnico: un mecnico solo
podra reparar coches una vez en su vida, ya cada mecnico solo aparece una vez en la tabla.
Por otro lado, supongamos la siguiente informacin sobre un conjunto de coches.
Matric.
2211-ZW
4324-EE
5421-AA
Marca
Seat
Renault
VW
Modelo
Ibiza
21
Bora
Solucin
No hay una solucin 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 ceirse 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
ms rgido, lo que a su vez condiciona el modelo
Podemos por tanto contemplar dos soluciones a partir de las tres entidades Empresa, Beneficio y Cupn
1. Dos relaciones binarias
Relacin Empresa ofrece Beneficio
Relacin Beneficio Se Plasma En Cupn
2. Una sola relacin ternaria Empresa con Beneficio con Cupn
Imaginemos las tres tablas, Empresa, Beneficio y Cupn.
CIF
E1
E2
Nombre
ACME
XYZ Sport
Direccion
C/ Guadiana
C/ Rio
Codigo
B1
B2
Desc.
10 % desc.
5 % desc
Codigo
C1
C2
Fecha venc
31-12-2011
20-12-2011
Limit.
Excepto rebajas
LaJ
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 caractersticas. Supongamos el ejemplo
de una base de datos para la DGT. Para cada coche puede haber un dueo, pero este dueo puede
ser una persona fsica o jurdica. Si construyramos dos entidades separadas Persona y Empresa
descubriramos que tienen cosas en comn.
Para ahorrar esfuerzos se puede poner una sola entidad general que ofrece los atributos, y dichos
atributos son heredados por las entidades hija.
10
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 tringulo.
2.4 Problemas
2.4.1 Problema 1: Comunidades de vecinos
Una firma de abogados dedicada a la administracin de fincas desea tener una base de datos para gestionar la informacin de sus clientes.
La firma tiene varios abogados y cada uno de ellos ejerce de administrador de una o ms comunidades de
vecinos, por lo que cobra unos honorarios anuales. Una comunidad es gestionada por un nico administrador (nombre, DNI y nmero 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 compaas (luz,
agua...)
De las empresas que cada comunidad tiene contratadas se guarda su nombre, direccin, telfono y una
persona de contacto. Adems puede interesar tener agrupadas a las compaas por sectores (sector de
seguridad, sector de suministros bsicos).
De cada comunidad se almacena un cdigo, su nombre, calle, cdigo postal y poblacin. 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 nmero de portal, planta y letra, un nombre y apellidos
del propietario, un porcentaje de participacin 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, direccin y telfono) y los datos de su inquilino (nombre apellidos y telfono).
Si la vivienda es particular se guarda el nmero 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 dueos) 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 cdigo y un nombre comercial. De las cuentas se almacena el cdigo
de cuenta (que consta de un cdigo de sucursal, dos dgitos de control y un nmero de cuenta) y un
saldo. Para identificar la cuenta hay que aadir el cdigo del banco al cdigo de cuenta.
Se almacenan dos tipos de apuntes:
2.4. Problemas
11
El banco emite los recibos, pero el administrador guarda informacin sobre dichos recibos como
el nmero de recibo, fecha, importe y si se ha podido cobrar o no. Esta ltima informacin 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 compaas cobran sus recibos (nmero, fecha e importe) cargndolo en
la cuenta de la comunidad
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. Direccin
1.1.4. Telfono
Al leer que un propietario tiene que aparecer como entidad, descubrimos que
Propiedad va a ser dbil, 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. Cdigo de cuenta
1.1.15.2. DC
1.1.15.3. Nmero de cuenta
1.1.15.4. Cdigo de banco
Como nos dicen que se necesita el cdigo del banco para poder
identificar esta entidad, hemos descubierto que esta entidad es dbil
1.1.16. Banco
1.1.16.1. Codigo de banco
1.1.16.2. Nombre comercial
2.4. Problemas
13
1.1.17. Apunte
1.1.17.1. Recibo (cobramos a prop)
Nmero de recibo
Fecha
Importe
Se pag?
1.1.17.2. Pago (pagamos luz..)
Nmero de recibo
Importe
Fecha
1.2. Verbos: relaciones
1.2.1 Abogado administra Comunidad
1.2.2 Abogado cobra Honorarios (MAL!!, los honorarios no llegarn 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 travs 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
14
Solo hay una federacin por pas con un nombre, pas al que pertenece, telefono de contacto y
fecha de fundacin
Una federacin no se clausura hasta que no se reasignan sus jugadores a otra federacin.
Las partidas pueden darse o no dentro de un torneo. Los torneos tienen un nombre, periodicidad,
fecha de creacin y son organizados por una federacin
En cada edicin de un torneo (nmero ordinal) se registran todos los enfrentamientos y el nombre
del ganador. Tambin se anotan la fecha de inicio, la cuanta del premio y el jugador que lo gana
Si desaparece una federacin, desaparecen los torneos y por ende, sus ediciones
Aunque un jugador desaparezca, sus partidas no deben desaparecer
2.4. Problemas
15
Atributo:ganador
Atributo:fecha inicio
Atributo:periodicidad
Atributo:cuanta del premio
Relaciones
Se necesita una relacin para conectar los jugadores con partida: Partida enfrenta jugadores. El
enfrentamiento tiene atributos
Tambin podramos considerar que hay una sola relacin reflexiva Jugador Se Enfrenta Con
Jugador. Esta relacin tendra atributos como fecha de inicio, duracin, etc...
Partida Consta De Movimiento: aqu se descubre que Movimiento es dbil, no puede almacenarse un movimiento sin que est dentro de una partida
Jugador Pertenece A Federacin.
Hay dos posibilidades de relacin
Federacin organiza Torneo que Consta De Partidas: relacin ternaria
Federacin organiza Torneo y Torneo Consta De Partidas: dos binarias
Dado que se permite que las partidas estn o no dentro de un torneo es ms apropiados que
el modelo permita cierta libertad para lo cual es ms apropiado utilizar las dos binarias.
16
2.4. Problemas
17
Nombre
Cuidados
Accesorio de jardinera (hija de producto)
Artculo
Viveros
Cdigo
Telfono
Direccin
Responsable? No, esto es una relacin
Zona
Nombre (clave)
Pedido
Nmero: clave
Fecha
Unidades, precio de portes y descuento son atributos de una relacin cuyo nombre todava
no conocemos.
Cliente: habr Normales y Club VIP
DNI
Direccin
Telfono
Fecha de incorporacin (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 relacin ternaria no es la mejor opcin ya que nos obligara a que en un pedido solo apuntsemos un producto
VIP1
VIP1
VIP1
Ped1
Ped1
Ped1
Rosas
Tijeras
Semillas
Tcnicamente, esta relacin 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 conclusin la relacin Cliente hace pedido que consta de Artculos no es la mejor opcin, sino
que desglosaremos esto en dos binarias
Vip Realiza Pedido (esto implica que Pedido es dbil)
2.4. Problemas
19
profesor en una publicacin, teniendo en cuenta que un profesor queparticipa en una publicacin
slo escribe en el mbito de una lnea de investigacin y que una determinada publicacin puede
cubrir varias lneas de investigacin
Solucin: entidades
Proyecto
cdigo de referencia nico
un nombre
un acrnimo
un presupuesto total
el programa de I+D que lo financia
una fecha de inicio y una fecha de finalizacin
y una breve descripcin
Profesor
Nombre y apellidos.
Despacho y telfono.
Investigador principal hijo de Profesor? Es mala idea porque usaramos una entidad para
algo que aparecer una sola vez.
Doctor y No doctor s pueden ser entidades hija.
Publicacin.
Nmero
Ttulo
Profesores que lo escriben (esto ser una relacin)
En congreso y En revista sern entidades hija.
En congreso tiene los atributos: Tipo, nombre, fecha de inicio, de fin, lugar de celebracin, pas y editorial.
En revista tiene los atributos: nombre de revista, el volumen, editorial, pginas de inicio
y fin.
Lnea
Cdigo
Nombre
Descriptores:
Nombre
2.4. Problemas
21
Solucin: relaciones
Profesor Participa en Proyecto
Profesor dirige proyecto, esta relacin contiene el hecho de que un proyecto tiene 1 y solo 1
investigador principal.
Doctor supervisa a No Doctor
Doctor dirige proyecto, esta relacin sustituye a la anterior Profesor dirige proyecto.
Proyecto produce publicacin. En realidad, ms adelante descubriremos que el Profesor debe
intervenir en esta relacin dando lugar a una relacin ternaria Proyecto produce publicacin en
la que interviene profesor
En-
23
A tener en cuenta: esta tabla ilustra que un diseo mejor habra sido tener dos relaciones
como Se enfrenta con blancas y Se enfrenta con negras. An as, habra que programar
Torneo (NombreTorneo, NombreFed, Periodicidad,Cuantia)
NombreFed es clave ajena sobre Federacin(Nombre)
Edicin (Numero, NombreTorneo,NombreFed, Nombre,Apellidos)
La
pareja
(NombreTorneo,NombreFed)
neo(NombreTorneo,NombreFed)
es
clave
ajena
sobre
Tor-
2.6 Normalizacin
Cuando se elabora un diseo de tablas, puede ocurrir que an siga existiendo mucha redundancia.
Al disear 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 Poblacin. 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, pas)
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 tro) que sabemos que no se va a repetir.
Clave candidata: es un atributo (o pareja) que PODRA ACTUAR COMO PRIMARIA pero no
lo hemos elegido.
Transitividad: supone que si A implica B y B implica C, automticamente sabremos que A
implica C.
24
2.6. Normalizacin
25
26
CAPTULO 3
Diseo fsico
3.1 Introduccin
En general hemos seguido un proceso lgico en la creacin de bases de datos.
Tema 1: posibilidades
Tema 2: Diseo
Anlisis
Diseo E/R
Pasar a un diseo relacional
Normalizacin.
27
Memo
Acepta textos largos.
Fecha
Permite manejar datos relacionados con las fechas y con sus intervalos.
Numricos
Se reservan para datos para los cuales se deseen hacer operaciones matemticas.
Los tipos numricos pueden concretarse an ms:
Byte: acepta nmeros en el rango 0-255
Enteros cortos: nmeros 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 precisin variable
Doble: acepta negativos y decimales muchsimo ms grandes y con mucha ms precisin decimal
En general la regla es: cuanto ms corto es el campo ms rpido se procesa pero menos precisin
nos ofrece
S/No
Reservado para valores lgicos (True/False)
3.2.5 Ttulo
El ttulo es lo que se mostrar en los formularios. Se puede dejar en blanco.
29
3.2.9 Requerido
Nos indica si es obligatorio que haya dentro del campo o si por el contrario puede estar vaco.
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 bsquedas ms
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 opcin cuando los usuarios se quejan de que las bsquedas son lentas.
30
3.2.15 Alineacin
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.4 MySQL
3.4.1 Comandos bsicos
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;
31
32
use ... ;
drop table empleado;
create table empleado
(
dni char(10),
nombre varchar(60),
apellidos varchar(120),
primary key (dni)
);
Clave ajena
create table empleado
(
dni char(10),
3.4. MySQL
33
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);
34
3.4. MySQL
35
(
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
);
37
38
CAPTULO 4
Consultas SQL
4.1 Introduccin
Las consultas, las sentencias SELECT se apoyan sobre dos conceptos matemticos denominados
Algebra relacional
Clculo relacional
*
*
*
*
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 especificarn mediante condiciones.
Si por ejemplo, deseramos mostrar solo los proveedores cuya ciudad sede est en Pars haramos algo
como esto.
select * from proveedores
where ciudad="Paris";
Otra posible consulta sera mostrar todos los proveedores cuyo estado tiene el codigo 10
select * from proveedores
where estado=10;
39
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;
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;
La respuesta es que no se muestra nada. La condicin est mal escrita ya que no puede haber un nmero
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 sera 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 condicin hay tres o ms elementos de comparacin puede
que sea necesario utilizar parntesis.
Mostrar las partes rojas o verdes que pesen 17 o ms.
Esta pregunta debe aclararse antes de resolverse.
Mostrar las partes siempre que pesen 17 o ms 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 ms.
Mostrar las partes que siendo verdes pesen 17 o ms o si no que simplemente sean rojas.
40
4.4.1 Recuento
La funcin COUNT nos dice cuantas filas cumplen una cierta condicin. No es obligatorio poner dicha
condicin.
select count(*) from partes;
Si deseramos una condicin como por ejemplo hacer el recuento de partes cuyo color sea Azul
select count(*) from partes
where color="Azul";
41
4.4.2 Promedio
Esta funcin calcula la media aritmtica de las filas que cumplan una cierta condicin. Tampoco es
obligatorio poner la condicin. La funcin promedio en SQL es AVG(*)
Cual es el peso medio de las partes?
select avg(peso) from partes;
4.4.4 Sumas
La operacin SUM(campo-numrico) efecta la suma de ese campo para las filas que cumplan una cierta
condicin.
Cuantas partes en total ha suministrado el proveedor v1?
select sum(cantidad)
from suministra
where numprov="v1";
42
43
Si ahora deseamos mostrar solo aquellos cuyo recuento sea mayor o igual que 2 debemos aadir una
clusula HAVING como esta
select count(*), ciudad
from proveedores
group by (ciudad)
having count(*)>=2;
El WHERE es una condicin que se aplica antes de hacer los clculos. Sin embargo, si una vez hechos
los clculos 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 ms 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: Podramos quitar el group by? Respuesta: aunque en este caso s podramos no se debe hacer.
Cuando nos pidan una operacin matemtica por grupos, debemos poner group by
select count(*), nombreparte from partes
where nombreparte="Tornillo"
group by nombreparte
44
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;
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;
45
4.7 Subconsultas
Al hacer consultas hemos observado que hay clusulas 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 ms 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);
Dentro de las subconsultas, aparte de las comparaciones tpicas como >, >=, <>, <=, <, etc... existen
otros elementos para hacer comparaciones
EXISTS: nos dar las filas donde exista alguna fila que cumpla la condicin
ALL: la condicin deben cumplirla todas las filas
12. Qu nombres de parte corresponden a una pieza azul o almacenada en Pars?
select nombreparte from partes
where color="Azul" or ciudad="Paris"
46
select nombreparte,cantidad
from partes inner join suministra
on partes.numparte=suministra.numparte
where cantidad>=400;
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 estn 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 informacin 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
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
48
ciudad
Londres
Londres
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Paris
Londres
Londres
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
Atenas
18. Qu nombre tienen las partes suministradas en una cantidad total de 550 o ms?
select sum(cantidad), partes.numparte,nombreparte
from suministra
inner join partes
on suministra.numparte=partes.numparte
group by (partes.numparte)
having sum(cantidad)>=550;
20. Queremos saber los proveedores que estn 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
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;
4.7. Subconsultas
49
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
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
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 ms?
Trozo 1: partes rojas
select numparte from partes where color="Rojo"
4.7. Subconsultas
51
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
Sin embargo esto no funciona porque cualquier operacin de agregado no involucra a ninguna fila. De
hecho esa consulta nos devuelve un mximo 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
);
52
having sum(cantidad)>=
ALL
(
select sum(cantidad)
from suministra
group by (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
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
;
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;
54
39. Obtener las parejas de nombres de ciudad tales que un proveedor ubicado en la primera ciudad
suministra a algn 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 cdigos 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 cdigos 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;
43. Obtener los cdigos 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 cdigos de proyecto que usan al menos una parte suministrada por el proveedor V1
4.7. Subconsultas
55
En segundo lugar queremos saber los proyectos cuyas partes sean alguna de las que hemos extrado
antes.
select numproyecto from suministra
where numparte in
(
select numparte from suministra
where numprov=v1
);
45. Obtener los cdigos 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 extradas antes
select numprov from suministra
where numparte in
(
select numparte from partes
where color="Rojo"
);
46. Obtener los cdigos de proyecto cuya ciudad es la primera en la lista de ciudades.
Seleccionamos la ciudad ms pequea
select min(ciudad) from proyectos;
select * from proyectos
where ciudad in
(
select min(ciudad) from proyectos
);
56
47. Obtener los cdigos de proyecto a los que se suministra la parte P1 en una cantidad promedio
igual o superior a la cantidad ms grande que se suministra al proyecto Y1.
Extraemos la cantidad ms grande del proyecto y1
select max(cantidad) from suministra
where numproyecto="y1";
Al haber una condicin 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 cdigos de proveedor de los que suministran la parte P1 a algn 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;
49. Obtener los cdigos de proyecto a los que ningn 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
50. Hay algn proveedor que suministre la misma parte a TODOS los proyectos?
Para conseguir la solucin a este problema se deben utilizar algunas caractersticas de los cuantificadores.
Replanteamos la pregunta
se desea saber los proveedores donde para todos los proyectos existe una misma parte suministrada
o ms 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 mirbamos 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 cdigos de proyecto que usan todas las partes suministradas por el proveedor v1
Obtener los cdigos 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
52. (Para nota) Obtener los pares de proveedores V1 y V2 que suministren EXACTAMENTE el mismo conjunto de partes.
La pregunta podra 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.
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;
59
60
CAPTULO 5
Programacin
5.1 Introduccin
Los elementos de los lenguajes de programacin son muy similares entre s y el cambio de lenguaje
solamente supone la modificacin de ciertos hbitos.
En el entorno de las bases de datos se pueden encontrar programas que acten mediante dos mecanismos
distintos. Estos dos mecanismos se definen como
Procedimientos almacenados: residen en el propio servidor de bases de datos.
Programas externos: utilizando algn mecanismo los programas externos se comunican con el
servidor para intercambiar datos mediante un lenguaje de programacin cualquiera.
Entre los mecanismos de comunicacin ms utilizados encontramos ODBC (Open DataBases Communication). Este estndar especifica claramente a servidores y cliente como tienen que dar o pedir datos.
Una versin modificada de ODBC es JDBC que ha modernizado el estndar pero solo sirve para programas Java.
5.2.2 Variables
Una variable es una posicin 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
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 parmetros 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
Captulo 5. Programacin
from suministra
inner join partes
on
suministra.numparte=partes.numparte
where color=color_pasado;
end
//
delimiter ;
call suministradas_color("Rojo");
call suministradas_color("Gris");
63
IF (<comparacion>) THEN
BEGIN
<sentencias>
END
ELSE
BEGIN
END
END IF;
Ejemplo: crear un procedimiento que extraiga las filas de la tabla suministra que cumplan cierta condicion sobre la cantidad. Si el usuario pasa un simbolo > el procedimiento nos devuelve las filas mayores
que cierta cantidad. Si no pasa un < nos devuelve las filas con una cantidad menor que la pasada
drop procedure selector_v2;
delimiter //
create procedure selector_v2
( operacion char(1), cantidad_pasada int)
begin
if (operacion="<") then
begin
select * from suministra where
cantidad<cantidad_pasada;
end;
else
begin
select * from suministra where
cantidad>cantidad_pasada;
end;
end if;
end;
//
delimiter ;
Ejercicio:crear un procedimiento que dados los parmetros siguientes compruebe cuantas partes con un
cierto nombre tienen una cantidad menor o mayor que una cierta cantidad pasada
nombre_parte_pasado
cantidad_pasada
operacion
drop procedure selector_v3;
delimiter //
create procedure selector_v3
( nombre_parte_pasada varchar(11),
cantidad_pasada int,
operacion varchar(1) )
begin
if (operacion=">") then
begin
select * from suministra inner join
partes on
64
Captulo 5. Programacin
suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and
cantidad>cantidad_pasada;
end;
else
begin
select * from suministra inner join
partes on
suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and
cantidad<cantidad_pasada;
end;
end if;
end;
//
delimiter ;
Ejercicio: ampliar el programa anterior para que soporte bsquedas utilizando los comparadores <,
>, >=, <=, = y <>.
Basndonos en esta sintaxis, una posible solucin al problema anterior sera esta
drop procedure selector_v4;
delimiter //
create procedure selector_v4
( nombre_parte_pasada varchar(11),
cantidad_pasada int,
operacion varchar(1) )
65
begin
case operacion
when ">" then
begin
select * from suministra
inner join partes
on
suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and cantidad>cantidad_pasada;
end;
when ">=" then
begin
select * from suministra
inner join partes
on
suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and cantidad>=cantidad_pasada;
end;
when "<>" then
begin
select * from suministra
inner join partes
on
suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and cantidad<>cantidad_pasada;
end;
when "<" then
begin
select * from suministra
inner join partes
on
suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and cantidad<cantidad_pasada;
end;
when "<=" then
begin
select * from suministra
inner join partes
on
suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and cantidad<=cantidad_pasada;
end;
when "=" then
begin
select * from suministra
inner join partes
on
66
Captulo 5. Programacin
suministra.numparte=partes.numparte
where
nombreparte=nombre_parte_pasada
and cantidad=cantidad_pasada;
end;
else
begin
select ("Operacion no reconocida");
end;
end case;
end;
//
delimiter ;
Ejercicio: crear un programa que acepte un nombre de parte,luego dos ciudades C1 y C2 y luego un
comparador que puede ser AND o OR. El programa debe decirnos las partes que pertenecen a las
dos ciudades o a una de ellas.
drop procedure comparador;
delimiter //
create procedure comparador
( nombre_parte_pasada varchar(11),
c1_pasada varchar(15), c2_pasada varchar(15),
operador varchar(3) )
begin
case operador
when "AND" then
begin
select * from partes as p1, partes as p2
where p1.nombreparte=nombre_parte_pasada
and
p2.nombreparte=nombre_parte_pasada
and (p1.ciudad=c1_pasada
and p2.ciudad=c2_pasada);
end;
when "OR" then
begin
select * from partes as p1, partes as p2
where p1.nombreparte=nombre_parte_pasada
and
p2.nombreparte=nombre_parte_pasada
and (p1.ciudad=c1_pasada
or p2.ciudad=c2_pasada);
end;
else
begin
select ("Escriba OR o AND (maysculas)");
end;
end case;
end
//
delimiter ;
67
Ejercicio resuelto: hacer un programa MySQL que imprima los 10 primeros nmeros pares.
drop procedure pares;
delimiter //
create procedure pares()
begin
declare contador int;
set contador=0;
while (contador<=20) do
select (contador);
set contador=contador+2;
end while;
end;
//
delimiter ;
5.3.4 Cursores
Un cursor es un puntero que apunta a la primera fila del resultado de una consulta. Podemos ir haciendo avanzar el puntero y procesar cada fila por separado. Podemos dejar de procesar filas cuando lo
deseemos, sin que sea obligatorio examinar todos los resultados.
No se puede declarar variables nuevas despues de un cursor. Es decir, esto no es vlido
declare un_cursor cursor for...
declare contador int;
Esto s es vlido
declare contador int;
declare un_cursor cursor for...
68
Captulo 5. Programacin
CLOSE nombre_cursor;
Ejercicio: extraer los proveedores que han recibido las 5 cantidades ms grandes de suministros.
drop procedure mejores_clientes;
delimiter //
create procedure mejores_clientes()
begin
declare contador int;
declare num_prov_sacado varchar(5);
declare cantidad_sacada int;
declare cur1 cursor for
select numprov, cantidad from suministra
order by cantidad desc;
open cur1;
set contador=0;
while (contador<5) do
fetch cur1 into num_prov_sacado, cantidad_sacada;
select (num_prov_sacado);
select (cantidad_sacada);
set contador=contador+1;
end while;
close cur1;
end;
//
delimiter ;
Ejercicio: hacer un programa que saque las 2 partes de ms peso de la tabla partes.
La consulta para este ejercicio sera:
select * from partes order by peso desc;
Y el procedimiento sera
drop procedure mayores_pesos;
delimiter //
create procedure mayores_pesos()
begin
declare contador int;
declare peso_extraido int;
declare ciudad_extraida varchar(15);
declare cur1 cursor for
select ciudad,peso from partes order by peso desc;
open cur1;
set contador=0;
while (contador<2) do
begin
fetch cur1 into ciudad_extraida,
select (ciudad_extraida),(peso_extraido);
set contador=contador+1;
end;
end while;
close cur1;
69
end;
//
delimiter ;
Y la solucin sera
drop procedure suma_filas;
delimiter //
create procedure suma_filas()
begin
declare contador int;
declare suma int;
declare cantidad_extraida int;
declare cur1 cursor for
select cantidad from suministra
order by cantidad asc;
open cur1;
set suma=0;
set contador=0;
while contador<5 do
fetch cur1 into cantidad_extraida;
set suma=suma+cantidad_extraida;
set contador=contador+1;
end while;
close cur1;
select suma;
end;
//
delimiter ;
70
Captulo 5. Programacin
set suma=suma+cantidad_extraida;
set contador=contador+1;
end while;
close cur1;
set suma_devuelta=suma;
end;
//
delimiter ;
Ejercicio: realizar un procedimiento que devuelva en una variable la ciudad del proveedor con una
cantidad total (sumar) de suministros mayor.
La consulta sera algo as
select sum(cantidad),suministra.numprov,
ciudad from suministra
inner join proveedores
on suministra.numprov=proveedores.numprov
group by numprov
having sum(cantidad)>=ALL
(
select sum(cantidad)
from suministra
group by numprov
);
71
delimiter ;
5.4 Funciones
La sintaxis de una funcin es la siguiente
delimiter //
create function <nombre> (parametros) returns string
begin
end;
//
delimiter ;
Ejercicio: construir una funcin que devuelva la suma total de cantidades de la tabla suministra
La consulta sera as:
select sum(cantidad) from suministra;
Y la funcin
drop function suma_suministra;
delimiter //
create function suma_suministra() returns int
begin
declare suma int;
declare cur1 cursor for
select sum(cantidad) from suministra;
open cur1;
fetch cur1 into suma;
close cur1;
return suma;
end;
//
delimiter ;
set @s=suma_suministra();
Hacer una funcin que devuelva el nombre de la pieza y el color en una sola cadena. Se debe devolver
la pieza con un peso mayor.
72
Captulo 5. Programacin
La solucin sera:
delimiter //
create function pieza_mayor_peso()
returns varchar(25)
begin
declare
declare
declare
declare
cadena varchar(25);
nombre_pieza varchar(10);
color_pieza varchar(10);
cur1 cursor for
select nombreparte, color from partes
where peso=(
select max(peso) from partes
);
open cur1;
fetch cur1 into nombre_pieza, color_pieza;
set cadena=CONCAT(nombre_pieza, ":", color_pieza);
return cadena;
close cur1;
end;
//
delimiter ;
Hay una pareja de funciones llamadas LEFT y RIGHT, que nos permiten extraer trozos de las cadenas.
Por ejemplo, la funcin LEFT(peso, 1) nos devuelve la primera letra del campo peso.
Ejercicio: construir una funcin que nos devuelva la pieza de mayor peso con la letra inicial del color
entre parntesis (es decir, se debe devolver algo como Engranaje (R))
Para resolver este ejercicio era necesario utilizar la funcin LEFT (cadena, longitud). Esta funcin nos
devuelve un trozo de la cadena que mide lo que diga el parmetro longitud.
Existe una variante que extrae trozos desde el lado derecho y que se llama RIGHT (cadena, longitud).
drop procedure pieza_pesada_inicial;
delimiter //
create procedure pieza_pesada_inicial()
begin
declare parte_extraida varchar(15);
declare color_extraido varchar(15);
declare cadena varchar(30);
declare inicial varchar(1);
declare cur1 cursor for
select nombreparte, color from partes
where peso=(
select max(peso) from partes
open cur1;
);
73
//
delimiter ;
Ejercicio: construir una funcin que nos devuelva el codigo de proyecto con una cantidad de suministros menor. Por problemas de integracin con otra base de datos necesitamos que se devuelva todo en
maysculas.
Para resolver esto existe una funcin que convierte una cadena a su equivalente en maysculas.
drop function proveedor_minimo;
delimiter //
create function proveedor_minimo () returns varchar(3)
begin
declare num_prov_extraido varchar(3);
declare cur1 cursor for
select numprov from suministra
where cantidad=(
select min(cantidad)
from suministra
);
open cur1;
fetch cur1 into num_prov_extraido;
set num_prov_extraido=UPPER(num_prov_extraido);
close cur1;
return num_prov_extraido;
end;
//
delimiter ;
Ejercicio: crear un procedimiento que acepte una cadena como parmetro. El procedimiento deber
mostrar todas las partes de la tabla partes cuyo nombre contenga la subcadena pasada como parmetro.
Es decir, podemos hacer algo como sto
CALL buscar("To");
En general, la bsqueda de secuencias, cadenas o patrones es algo muy comn pero muy sencillo de
resolver con algunas funciones.
La funcin INSTR() permite comprobar si una cierta subcadena est dentro de una cadena.
Existe un operador llamado LIKE que permite hacer bsquedas difusas.
Por ejemplo, se puede hacer una bsqueda como esta
select * from partes
where nombreparte LIKE "uer%";
74
Captulo 5. Programacin
Ejercicio: se desea crear un procedimiento que permita marcar como obsoletas ciertas partes de la tabla
partes. Para ello, el usuario ejecutar un procedimiento como este
call marcar_obsoleta("To");
Este procedimiento CAMBIAR los nombres de parte de la tabla partes ponindoles un asterisco al
principio. Para resolverlo ser necesario manejar correctamente la condicin de NOT FOUND para un
cursor. Adems, necesitamos un procedimiento principal que construya el patrn y que luego llame al
procedimiento auxiliar que actualiza las filas.
drop procedure marcar_obsoletas;
drop procedure actualizar;
delimiter //
75
end;
//
delimiter ;
Ejercicio: crear un procedimiento que indique la desviacin media de los pesos de las partes.
drop procedure desviaciones_medias;
delimiter //
create procedure desviaciones_medias()
begin
declare terminado boolean;
declare media decimal(8,2);
declare peso_extraido decimal(8,2);
declare desv decimal(8,2);
declare cur1 cursor for
select avg(peso) from partes;
declare cur2 cursor for
select peso from partes;
declare continue handler for not found
set terminado=true;
open cur1;
open cur2;
fetch cur1 into media;
fetch cur2 into peso_extraido;
set terminado=false;
while not terminado do
# Se calcula la desviacion
set desv= abs ( peso_extraido-media );
select desv;
fetch cur2 into peso_extraido;
end while;
close cur1;
close cur2;
end;
//
delimiter ;
Aparte de la funcin ABS, que calcula el valor absoluto se pueden encontrar otras funciones de utilidad
como las siguientes:
CEIL (valor): Redondear el valor hacia arriba.
FLOOR (valor): Redondea hacia abajo.
ROUND (valor, decimales): si hacemos ROUND (3.6576, 2) nos devolvera el valor 3.66
76
Captulo 5. Programacin
Crear una funcin que nos devuelva s si hay la misma cantidad de partes rojas que de proyectos de
Atenas. Si no es as debe devolver no.
drop function cuantos;
delimiter //
create function cuantos() returns varchar(2)
begin
declare cuantos_rojos, cuantos_atenas int;
declare cur1 cursor for
select count(*) from partes where color="Rojo";
declare cur2 cursor for
select count(*) from proyectos
where ciudad="Atenas";
open cur1;
open cur2;
fetch cur1 into cuantos_rojos;
fetch cur2 into cuantos_atenas;
if (cuantos_rojos=cuantos_atenas) then
return "SI";
77
else
return "NO";
end if;
close cur1;
close cur2;
end;
//
delimiter ;
drop procedure insertar_madrid;
1
2
delimiter //
3
4
5
6
7
8
begin
10
11
end;
12
13
//
14
15
delimiter ;
16
78
Captulo 5. Programacin
CAPTULO 6
Administracin
6.1 Introduccin
La administracin de un SGBD suele referirse a un SGBD corporativo.
El administrador de bases de datos o DBA es el responsable de todo lo concerniente a los datos. Puede
haber muchas personas que trabajen con los datos: programadores SQL, programadores Java, programadores web, etc...
Los SGBD corporativos, como MySQL ofrecen muchas posibilidades, casi tantas como un sistema
operativo.
Un problema fundamental en la administracin de un SGBD pasa es asegurar el uso correcto de los
permisos: en lneas generales, los permisos deberan restringirse al mnimo. Adems, para obtener la
mxima seguridad deberamos hacer otras tareas como las siguientes:
Se debe comprobar tambin la seguridad del resto del equipo: seguridad fsica, seguridad del
sistema operativo, etc...
No compartir la clave de root.
Dar solamente los permisos mnimos necesarios, aunque sea ms trabajoso.
No se debe trabajar con claves sin cifrar.
Se deben utilizar cortafuegos.
lo que es potencialmente inseguro, ya que es posible capturar tramas en redes y obtener contraseas.
Si se desea acceder a otro host distinto (tal vez un remoto) se debe hacer lo siguiente:
79
6.2.3 Hashes
Un hash es un clculo que se hace sobre una secuencia de datos que se utiliza para asegurar la integridad
de la secuencia de datos.
Para ver los permisos concedidos al usuario que utilizamos podemos lanzar este comando
show grants;
A partir de ahora debemos recordar que un usuario no es solamente un login, sino tambin un sitio desde
el que se conecta. Estos dos usuario NO SON IGUALES
80
Captulo 6. Administracin
pepito@localhost
pepito@10.9.0.0/255.255.0.0;
pepito@sede-a.empresaacme.com;
Se puede observar que hay dos usuarios llamados root@localhost y root@127.0.0.1. Son usuarios distintos y ambos tienen la clave vaca. No deben tenerse SGBD con la clave de root vaca.
Adems la instalacin por defecto tambin crea un usuario vaco y sin contrasea que permite conectarse
sin clave.
Para borrar un usuario se usa el comando DROP USER
DROP USER @localhost;
Si un cambio no tiene lugar es posible que los cambios no se hayan volcado en el sistema de MySQL.
Podemos forzar a que los cambios tengan efecto usando este comando
FLUSH PRIVILEGES;
Se debe tener en cuenta que para poder conectar a una base de datos remota debemos disponer del
usuario con el host correspondiente.
Qu ocurre si aparentemente podemos entrar como dos posible usuarios distintos?. Supongamos que
nos conectamos desde la IP 10.9.0.200 con el usuario root y en MySQL hay dos usuarios (el % significa
cualquier cosa).
usuario
root
root
host
10.9.0.200
%
password
sesamo
12341234
La regla es que cuando un usuario se conecta y se le pueden aplicar dos o ms reglas se utiliza siempre
la ms restrictiva.
Para crear un usuario debemos especificar su login y su host. El host podra ser %.
create user dam1@10.9.0.0/255.255.0.0
identified by sesamo;
create user dam1@10.9.0.254
identified by 12341234;
create user dam1@ %
identified by 6789;
En ocasiones un usuario puede haber olvidado su clave o simplemente se desea renovar la misma por
una poltica de seguridad.
81
ESTO ES UN ERROR
set password for dam1@10.9.0.0/255.255.0.0 = 12345678;
Aparte de los permisos SELECT, INSERT, UPDATE Y DELETE, CREATE, CREATE INDEX, CREATE VIEW
Ejercicio: disear un esquema de seguridad para dar respuesta a las siguientes necesidades de acceso a
datos.
Se necesita dar acceso a dos usuarios que puedan seleccionar datos de cualquier tabla que exista
en la base de datos proyectos.
De uno de los usuarios sabemos su IP (preguntar al compaero). El otro usuario puede provenir
de cualquier punto de la red 10.9.xxx.xxx.
Existe un usuario admin que puede provenir de cualquier punto de la red 10.9 y que puede hacerlo
todo con cualquier tabla de la base de datos proyectos.
Extra: se desea que el usuario admin tenga a su vez permisos para conceder permisos.
82
Captulo 6. Administracin
6.6 Vistas
Una vista es un trozo extrado de una tabla en base a una consulta. Las vistas pueden utilizarse para
restringir an ms la cantidad de informacin que pueden ver los usuarios.
Antes de crear una vista se debe tener muy clara la consulta que se va a aplicar. Por ejemplo, si deseamos
tener por separado los datos de Paris sin incluir el estado podramos crear una vista como esta:
CREATE VIEW PROV_PARIS AS
SELECT NUMPROV,NOMBREPROV,CIUDAD
FROM PROVEEDORES
WHERE CIUDAD="Paris";
CREATE USER usu_paris@10.9.0.0/255.255.0.0
IDENTIFIED BY paris;
CREATE USER usu_paris@localhost
IDENTIFIED BY paris;
GRANT SELECT ON PROYECTOS.PROV_PARIS
TO usu_paris@10.9.0.0/255.255.0.0;
GRANT SELECT ON PROYECTOS.PROV_PARIS
TO usu_paris@localhost;
Ejercicio: los administradores de la base de datos de proyectos necesitan establecer una configuracin
de seguridad de acuerdo a las siguientes caracteristicas
Existe un usuario admin que puede conectarse desde cualquier punto de la red 10.9 que puede
hacer lo siguiente
Insertar, seleccionar, actualizar y borrar datos de cualquier tabla
Puede crear tambin vistas nuevas
Existe un usuario jefe_londres que puede hacer cualquier cosa con los datos de cualquier tabla
donde la ciudad sea Londres. Puede conectarse desde cualquier sitio.
Existe un usuario usu_continental que puede insertar y seleccionar datos en tablas donde la ciudad
sea Atenas o Paris. Puede conectarse desde cualquier sitio.
Existe un usuario pruebas que puede hacer consultas a cualquier tabla. Solo puede hacerlo el que
tenga cierta IP (la del compaero de al lado)
Solucin:
6.6. Vistas
83
Para el segundo apartado hay que permitir a jefe_londres que manipule las tablas donde la ciudad sea
Londres. Las tablas que cumplen este requisito son proveedores, partes y proyectos.
Este requisito obliga a crear tres vistas separadas para cada una de las tres tablas.
create view partes_londres as
select * from partes
where ciudad=Londres;
create view proveedores_londres as
select * from proveedores
where ciudad=Londres;
create view proyectos_londres as
select * from proyectos
where ciudad=Londres;
create user jefe_londres@ %
identified by londres;
grant all privileges on proyectos.partes_londres,
proyectos.proveedores_londres,
proyectos.proyectos_londres
to jefe_londres@ %;
84
Captulo 6. Administracin
identified by prueba;
grant select on proyectos.* to
pruebas@10.9.0.99
Con esto el servidor de bases de datos arranca, ignorar todas las claves y permisos y se quedar en
segundo plano.
2. En otra consola, volvemos a conectar con mysql, pero ahora no har falta poner clave a root.
mysql -u root
mysql> use mysql;
mysql> select user,host,password from user;
mysql> update user set password=PASSWORD("1234")
where user=root and host=localhost;
3. Una vez hecho el update, podemos parar el proceso mysqld y volver a arrancarlo normalmente
disponiendo de la clave de root recuperada.
85
Otra posibilidad es distinguir las copias de seguridad que se hacen en caliente o en fro.
En fro: el servidor SE PARA y nadie puede registrar datos nuevos o borrar datos viejos.
En caliente: el servidor no se para, an a riesgo de que haya datos que no entren en esta copia
de seguridad y se queden para la siguiente.
Es posible hacer copias de seguridad solo de ciertas tablas. Esto permite ahorrar tiempo en la copia y
adems perturbar menos la carga de trabajo del SGBD.
Si por ejemplo, desesemos copiar solo la tabla partes, basta con indicar su nombre detrs del nombre
de la base de datos
mysqldump -u root -p --single-transaction proyectos partes > copia2.sql
Se podra poner una ruta como C:prov_londres.txt. Si no lo ponemos el archivo se crear en mysqldataproyectos
Supongamos que se pierden los datos de los proveedores de Londres
mysql> delete from proveedores where ciudad=Londres;
86
Captulo 6. Administracin
Usando los comandos mysqlbinlog podemos volcar cualquier archivo de log en un fichero mysql.
87
88
Captulo 6. Administracin
CAPTULO 7
Access
7.1 Introduccin
Access es un SGBD ofimtico. Una caracterstica fundamental de su uso es que es monousuario.
Si se desea un SGBD multiusuario de MS, se necesitar utilizar SQL Server (Express)
Access ofrece un entorno de desarrollo integrado, lo que supone una ventaja en cuanto a la comparacin
con otros productos.
Como curiosidad histrica, Access proviene de un conjunto de bibliotecas llamados JetDB.
Access respeta el estndar ODBC que permite compartir bases de datos para que sean consultadas por
programas que se conecten desde un sitio remoto.
7.2 El entorno
Al arrancar Access se ofrecen un conjunto de plantillas que contienen BD prefabricadas con tablas
ya creadas junto con las claves y las relaciones entre dichas tablas. Esto permite acelerar el tiempo de
desarrollo en ciertos casos, sin embargo en otros se deber asumir el control y crear las tablas, claves y
relaciones desde cero.
Al crear una base de datos en blanco, Access ofrece un diseo inicial de la tabla en la que ya hay un
campo llamado Id de tipo autonumrico.
Un tipo autonumrico es un nmero que se incremente en uno de forma automtica.
Se pueden quitar y poner columnas desde este entorno inicial as como indicar los tipos de los datos de
forma sencilla. Se pueden marcar varios campos como nico, es decir sus valores no se pueden repetir.
Si un campo tiene la marca se requiere es que es obligatorio rellenarlo con algo.
Cuando un nmero se manipula para que muestre ms o menos decimales no se va a modificar el nmero
almacenado.
Access permite indicar que una columna se va a utilizar a menudo para hacer bsquedas. Si algunos
valores se usan mucho la insercin ser ms cmoda.
El botn Relaciones permite establecer relaciones de clave ajena entre las tablas de una base de datos.
89
7.2.1 Ejercicio
Utilizando el entorno de Access, crear la estructura de proveedores, partes y proyectos utilizada en el
tema 4, en el archivo SQL BD Proveedores, partes y proyectos.
90
Captulo 7. Access
CAPTULO 8
8.1 Introduccin
Un objeto es una representacin de una entidad fsica que consta de atributos y mtodos.
La herencia es la capacidad de compartir automticamente atributos y/o mtodos.
En BBDD una relacin es lo mismo que una tabla. El nombre relacin proviene del concepto
matemtico de relacin.
Las bases de datos objeto-relacionales son aquellas capaces de manipular relaciones utilizando conceptos relacionados con la programacin orientada a objetos.
Aparte de todo esto, las bases de datos objeto-relacionales suelen tener otras capacidades interesantes,
como la manipulacin de datos espaciales, textuales e incluso representaciones en XML.
XML es un formato de intercambio de datos basado en marcas.
En este tema veremos como utilizar PostgreSQL, que es un sistema de BBDD objeto-relacional que
ofrece las capacidades que hemos comentado.
91
92
<tipo>,
<tipo>,
<tipo>,
<tipo>
Ejemplo:
CREATE TABLE partes
(
id
nombre
color
peso
ciudad
);
Se pueden poner tambin claves ajenas, de la misma forma que se poda en MySQL.
CREATE TABLE propietarios
(
id integer primary key,
nombre varchar(20),
id_parte integer,
foreign key (id_parte)
references partes(id)
);
Al tener las tablas vacas, si intentsemos insertar este valor, veremos que no se puede. Si el propietario
con el cdigo 3, llamado Juan posee la parte 1, deberamos escribir lo siguiente:
INSERT INTO propietarios VALUES (3, Juan, 1 );
Para que esto funcione, primero deberamos hacer algo como esto
INSERT INTO partes VALUES (1,Tornillo, Rojo, 12.3, Londres );
Para ver las tablas que hay se puede usar el pseudocomando d. Para ver la descripcin de una tabla
concreta se puede usar d <nombre_de_tabla>
Herencia
La herencia permite que una tabla herede automticamente los campos y restricciones de otra tabla a la
que se llama tabla padre.
Por ejemplo, supongamos que en una empresa hay empleados con id y sueldo, pero despues hay varios
tipos de empleado, como investigador, becario y administrativo.
Creacin de la tabla padre:
CREATE TABLE empleados
(
id
93
nombre
sueldo
varchar(50),
numeric(6,2)
);
Ejercicio: insertar el investigador con id 5, con nombre Tomas, sueldo 3500 y nombre_proyecto Consola.
Respuesta: El cdigo SQL es el siguiente:
INSERT INTO investigadores VALUES (5,Tomas, 3500, Consola);
Si ahora consultamos las dos tablas veremos que el valor SE INSERTA EN LAS DOS TABLAS
Podemos repetir la insercin de valores, las veces que deseemos, y siempre se propagarn los valores
INSERT INTO investigadores VALUES ( 7,Julian, 5100, Antena );
Ejercicio: Construir las tablas Becarios y Administrativos que heredan de Empleados. La tabla Becarios
tiene los campos duracion_contrato (integer) y la Administrativos tiene los campos categoria varchar(10)
y titulacion varchar(15). Insertar valores en las dos tablas.
CREATE TABLE becarios ( duracion_contrato integer )
inherits (empleados);
INSERT INTO becarios VALUES ( 4, Luis, 1900, 9 );
CREATE TABLE administrativos
(
categoria varchar(10),
titulacion varchar(15)
) INHERITS (empleados);
INSERT INTO administrativos VALUES
(
13, Angel, 2450,
B1, Tec. Sup. DAM
);
Ejercicio: Borrar el empleado cuyo cdigo es el nmero 7. Examinar las tablas investigadores y empleados para ver qu ha ocurrido.
delete from empleados
where id=7;
Ejercicio: Borrar el investigador cuyo cdigo es el nmero 42. Examinar las tablas investigadores y
empleados para ver qu ha ocurrido.
94
Ejercicio: La empresa en la que trabajamos ha decidido crear dos categoras adicionales de empleados.
Los becarios repartidores y los becarios auxiliares.
La tabla Repartidores tiene un solo campo llamado km y que es de tipo numeric (6,1). La tabla auxiliares tiene dos campos denominados horas_extra, de tipo integer, y el campo tipo_acceso, que es un
varchar(30).
Insertar valores en Repartidores y Auxiliares y comprobar qu ocurre en las diversas tablas.
CREATE TABLE repartidores
(
km numeric(6,1)
) INHERITS (becarios);
CREATE TABLE auxiliares
(
horas_extra integer,
tipo_acceso varchar(30)
) INHERITS (becarios);
Un repartidor tiene un id (22), un nombre (Ramon), un sueldo (870), una duracin de contrato (6 meses),
y un kilometraje 1450.
INSERT INTO repartidores VALUES
(
22, Ramon, 870, 6, 1450
);
Un auxiliar tiene un id (33), un nombre (Ricardo), un sueldo (760),una duracin de contrato (18 meses),
unas horas extra (85), y un tipo de acceso (Convenio)
INSERT INTO auxiliares VALUES
(
33, Ricardo, 760, 18,
85, Convenio
);
Conclusin: la herencia funciona como un rbol de tablas, en las cuales el SGBD propaga correctamente
todos los datos hacia las tablas padre. Adems, al construir las tablas no es necesario construir ninguna
clave ajena ni especificar borrados o actualizaciones en cascada.
Tipos de herencia
En Postgres, la herencia no es absoluta. Es decir, en nuestro ejemplo de empleados, becarios y administrativos, podemos tener datos que aparezcan en una tabla, pero no en las tablas hija.
En el ejemplo que hemos visto, la pregunta sera puede haber alguien que est simplemente en la tabla
empleados, sin estar en ninguna de las hijas?. S
Probemos por ejemplo este SQL.
INSERT INTO empleados VALUES
(
95
5, Alicia, 1950
);
Cuando en una tabla hay datos suyos y datos de otras tablas que heredan, la seleccin de datos puede
requerir comandos especiales.
Cmo se pueden recuperar simplemente las personas que son empleados normales, sin tener en cuenta
becarios o investigadores?.
Para recuperar tales datos se debe hacer lo siguiente
select * from only empleados;
En resumen: si se desea recuperar los datos de una tabla sin incluir los datos de sus posibles tablas hija,
se debe hacer un select * from only <nombre_de_la_tabla>
Y para usar ese tipo en un campo, se usa de la misma forma que cualquier otro tipo.
CREATE TABLE rectangulos
(
id int primary key,
r Rectangulo
);
Como se insertan datos en estas tablas?. La insercin de tipos creados por nosotros requiere usar (
<datos> ).
INSERT INTO rectangulos VALUES
(
1, (2, 12)
);
INSERT INTO rectangulos VALUES
(
2, (6, 2)
);
INSERT INTO rectangulos VALUES
(
3, (2, 12)
);
96
Ejercicio: crear una tabla que pueda almacenar el tipo de datos Punto3D. Un punto en 3D tiene tres
coordenadas x, y, z que pueden ser nmeros con hasta 2 decimales. Insertar algunos valores en la tabla.
CREATE TYPE Punto3D AS
(
x decimal(8,2),
y decimal(8,2),
z decimal(8,2)
);
CREATE TABLE puntos
(
id integer primary key,
punto Punto3D
);
insert into puntos values
(
1,
(2.25, 6.57, 8.96
);
Un detalle importante es que cuando los valores sean cadenas NO SE DEBEN DEJAR ESPACIOS
ENTRE LAS COMAS.
Ejercicio: crear un tipo de datos Linea que tenga un campo m (que es la pendiente de la recta) de tipo
decimal(8,2), un campo k que es la constante a sumar, de tipo decimal(8,2) y un campo orientacion que
es varchar(5). Crear una tabla que permita almacenar valores e insertar 3.
CREATE TYPE Linea AS
(
m decimal(8,2),
k decimal(8,2),
orientacion varchar(5)
);
CREATE TABLE lineas
(
id integer primary key,
l Linea
);
Cuidado: al insertar informacin de los varchar, se deben evitar los espacios entre comas.
INSERT INTO lineas VALUES
(
1, (3,2,N-S)
97
);
INSERT INTO lineas VALUES
(
2, (2.41,-7.22,SE-NO)
);
INSERT INTO lineas VALUES
(
3, (-4.46,-12.33,NE-SO)
);
98
to_tsquery(virtual);
select id from capitulos
where
to_tsvector(texto)
@@
to_tsquery(VirtualBox | (Virtual & Box));
Si indicamos el idioma del texto, Postgres utilizar una base de datos interna para eliminar las stop-words
adecuadas para ese idioma.
Qu ocurre si una misma palabra buscada aparece en dos o ms documentos?.
99
Esto indica que queremos que nuestra BD acte como una extensin PostGIS, es decir como una base
de datos SIG
create extension postgis;
100
(
LINESTRING(4 1, 4 4,5 7)
)
);
insert into lineas values
(
30,
ST_GeomFromText
(
LINESTRING(6 2, 6 5, 4 7)
)
);
101
)
);
Ejercicio: Utilizando la funcin ST_Intersects averiguar qu parcelas tienen intersecciones con otras
parcelas.
select p1.id, p2.id
from parcelas as p1,
parcelas as p2
where ST_Intersects
(
p1.parcela, p2.parcela
)=t and p1.id<>p2.id;
Se puede calcular el area de un polgono cualquiera por irregular que sea o independientemente de los
huecos son ST_Area
select id, ST_Area(parcela) from parcelas;
102
CAPTULO 9
ndices y tablas
genindex
modindex
search
103