Como hemos observado, la arquitectura ANSI/SPARC distingue tres niveles, que se describen en el esquema conceptual, el esquema interno y los esquemas externos. Hasta ahora, mientras creábamos las tablas de la base de datos, íbamos describiendo el esquema conceptual. Para describir los diferentes esquemas externos utilizamos el concepto de vista del SQL.
Para crear una vista es necesario utilizar la sentencia CREATE VIEW. Veamos su formato:
CREATE VIEW nombre_vista [(lista_columnas)] AS (consulta)
[WITH CHECK OPTION];
Lo primero que tenemos que hacer para crear una vista es decidir qué nombre le queremos poner (nombre_vista). Si queremos cambiar el nombre de las columnas, o bien poner nombre a alguna que en principio no tenía, lo pode- mos hacer en lista_columnas. Y ya sólo nos quedará definir la consulta que formará nuestra vista.
Las vistas no existen realmente como un conjunto de valores almacenados en la base de datos, sino que son tablas ficticias, denominadas derivadas (no materializadas). Se construyen a partir de tablas reales (materializadas) almacenadas en la base de datos, y conocidas con el nombre de tablas básicas (o tablas de base). La no-existencia real de las vistas hace que puedan ser actualizables o no.
Creación de una vista en BDUOC
Creamos una vista sobre la base de datos BDUOC que nos dé para cada cliente el número de proyectos que tiene encargados el cliente en cuestión.
CREATE VIEW proyectos_por_cliente (codigo_cli, numero_proyectos) AS
(SELECT c.codigo_cli, COUNT(*)
FROM proyectos p, clientes c
WHERE p.codigo_cliente = c.codigo_cli
GROUP BY c.codigo_cli);
Si tuviésemos las siguientes extensiones:
• Tabla clientes:
codigo_cli | nombre_cli | nif | dirección | ciudad | teléfono |
10 | EGICSA | 38.567.893-C | Aragón 11 | Barcelona | NULL |
20 | CME | 38.123.898-E | Valencia 22 | Girona | 972.223.57.21 |
30 | ACME | 36.432.127-A | Mallorca33 | Leida | 973.23.45.67 |
• Tabla proyectos:
codigo_proyec | nombre_proyec | precio | fecha_inicio | fecha_prev_fin | fecha_fin | codigo_cliente |
---|---|---|---|---|---|---|
1 | GESCOM | 1.000.000 | 1-1-98 | 1-1-99 | NULL | 10 |
2 | PESCI | 2.000.000 | 1-10-96 | 31-3-98 | 1-5-98 | 10 |
3 | SALSA | 1.000.000 | 10-2-98 | 1-2-99 | NULL | 20 |
4 | TNELL | 4.000.000 | 1-1-97 | 1-12-99 | NULL | 30 |
Y mirásemos la extensión de la vista proyectos_por_clientes, veríamos lo que encontramos en el margen.
En las vistas, además de hacer consultas, podemos insertar, modificar y borrar filas.
codigo_cli | numero_proyectos |
---|---|
10 | 2 |
20 | 1 |
30 | 1 |
Actualización de vistas en BDUOC
Si alguien insertase en la vista proyectos_por_cliente, los valores para un nuevo cliente 60 con tres proyectos encargados, encontraríamos que estos tres proyectos tendrían que figurar realmente en la tabla proyectos y, por lo tanto, el SGBD los debería insertar con la información que tenemos, que es prácticamente inexistente. Veamos gráficamente cómo quedarían las tablas después de esta hipotética actualización, que no llegaremos a hacer nunca, ya que iría en contra de la teoría del modelo relacional:
• Tabla clientes:
codigo_cli | nombre_cli | nif | dirección | ciuda | teléfono |
10 | ECIGSA | 38.567.893-C | Aragón 11 | Barcelona | NULL |
20 | CME | 38.123.898-E | Valencia 22 | Girona | 972.23.57.21 |
30 | ACME | 36.432.127-A | mallorca 33 | Lleida | 973.23.45.67 |
60 | NULL | NULL | NULL | NULL | NULL |
• Tabla proyectos:
codigo_proyec | nombre_proyec | precio | fecho_inicio | fecha_prev_fin | fecha_fin | codigo_cliente |
1 | GESCOM | 1.000.000 | 1-1-98 | 1-1-99 | NULL | 10 |
2 | PESCI | 2.000.000 | 1-10-96 | 31-3-98 | 1-5-98 | 10 |
3 | SALSA | 1.000.000 | 10-2-98 | 1-2-99 | NULL | 20 |
NULL | NULL | NULL | NULL | NULL | NULL | 60 |
NULL | NULL | NULL | NULL | NULL | NULL | 60 |
NULL | NULL | NULL | NULL | NULL | NULL | 60 |
El SGBD no puede actualizar la tabla básica clientes si sólo sabe la clave primaria, y todavía menos la tabla básica proyectos sin la clave primaria; por lo tanto, esta vista no sería actualizable.
En cambio, si definimos una vista para saber los clientes que tenemos en Barcelona o en Girona, haríamos:
CREATE VIEW clientes_Barcelona_Girona AS
(SELECT *
FROM clientes
WHERE ciudad IN (‘Barcelona’, ‘Girona’))
WHITH CHECK OPTION;
Si queremos asegurarnos de que se cumpla la condición de la cláusula WHERE, debemos poner la opción WHITH CHECK OPTION. Si no lo hiciésemos, podría ocurrir que alguien incluyese en la vista clientes_Barcelona_Girona a un cliente nuevo con el código 70, de nombre JMB, con el NIF 36.788.224-C, la dirección en NULL, la ciudad Lleida y el teléfono NULL.
Si consultásemos la extensión de la vista clientes_Barcelona_Girona, veríamos:
codigo_cli | nombre_cli | nif | dirección | ciudad | teléfono |
---|---|---|---|---|---|
10 | ECIGSA | 38.567.893-C | Aragón 11 | Barcelona | NULL |
20 | CME | 38.123.898-E | Valencia 22 | Girona | 972.223.57.21 |
Esta vista sí podría ser actualizable. Podríamos insertar un nuevo cliente con código 50, de nombre CEA, con el NIF 38.226.777-D, con la dirección París 44, la ciudad Barcelona y el teléfono 93.422.60.77. Después de esta actualización, en la tabla básica clientes encontraríamos, efectivamente:
codigo_cli |
nombre_cli |
nif |
dirección |
ciudad |
teléfono |
---|---|---|---|---|---|
10 | ECIGSA | 35.567.893-C | Aragón 11 | Barcelona | NULL |
20 | CME | 38.123.898-E | Valencia 22 | Girona | 972.23.57.21 |
30 | ACME | 36.432.127-A | Mallorca 33 | Lleida | 973.23.45.67 |
50 | CEA | 38.226.777-D | París 44 | Barcelona | 93.442.60.77 |
Para borrar una vista es preciso utilizar la sentencia DROP VIEW, que presenta el formato:
DROP VIEW nombre_vista (RESTRICT|CASCADE);
Si utilizamos la opción RESTRICT, la vista no se borrará si está referenciada, por ejemplo, por otra vista. En cambio, si ponemos la opción CASCADE, todo lo que referencie a la vista se borrará con ésta.
Borrar una vista en BDUOC
Para borrar la vista clientes_Barcelona_Girona, haríamos lo siguiente:
DROP VIEW clientes_Barcelona_Girona RESTRICT;