Vistas y Vistas Materializadas
Las vistas son una de las herramientas más potentes para la abstracción de datos y la seguridad en una arquitectura de base de datos.
Una Vista no es simplemente “una consulta guardada”. Es una tabla virtual cuya definición reside en el diccionario de datos de la base de datos, pero que no almacena datos físicamente (a diferencia de las tablas base). Actúa como una capa de interfaz que simplifica la complejidad del esquema subyacente.
¿Por qué usar Vistas?
En el diseño de sistemas avanzados, las vistas cumplen tres funciones críticas:
- Abstracción y Simplicidad: Permiten que los usuarios finales o los desarrolladores de aplicaciones consulten resultados complejos (con múltiples
JOINsyCASE WHEN) como si fueran una simple tabla. - Seguridad y Control de Acceso: Puedes otorgar permisos a un usuario para ver una Vista que contiene solo 3 columnas de una tabla que tiene 50, protegiendo datos sensibles (como salarios o contraseñas).
- Independencia Lógica de Datos: Si la estructura de las tablas base cambia (por ejemplo, divides una tabla en dos), puedes actualizar la definición de la Vista para que las aplicaciones que la consultan no dejen de funcionar.
Gestión de Vistas en PostgreSQL (Procedimientos DDL)
PostgreSQL ofrece una sintaxis robusta para gestionar el ciclo de vida de las vistas.
En los siguientes ejemplos se trabaja sobre el siguiente esquema sencillo de un hospital

A. Crear una Vista (CREATE VIEW)
Para crear una vista, definimos un nombre y le asignamos la consulta DQL que queremos encapsular.
Ejemplo: Vamos a crear una vista llamada resumen_ingresos_hospital basada en nuestro esquema anterior.
CREATE VIEW resumen_ingresos_hospital AS
SELECT
codigo_diagnostico,
COUNT(*) AS total_atenciones,
SUM(costo_base) AS ingresos_brutos
FROM atenciones
GROUP BY codigo_diagnostico;
B. Actualizar o Modificar una Vista (CREATE OR REPLACE)
En PostgreSQL, no existe un comando ALTER VIEW para cambiar la consulta interna. Se utiliza CREATE OR REPLACE VIEW.
Regla Profesional: Solo puedes usar
OR REPLACEsi vas a añadir columnas al final o cambiar la lógica interna. No puedes cambiar el nombre de las columnas existentes, el orden, ni sus tipos de datos. Si necesitas cambios estructurales profundos, debes borrarla y recrearla.1
CREATE OR REPLACE VIEW resumen_ingresos_hospital AS
SELECT
codigo_diagnostico,
COUNT(*) AS total_atenciones,
SUM(costo_base) AS ingresos_brutos,
ROUND(AVG(nivel_urgencia), 1) AS urgencia_promedio -- Añadimos una columna
FROM atenciones
GROUP BY codigo_diagnostico;
C. Eliminar una Vista (DROP VIEW)
Para eliminar la definición de la vista del diccionario de datos.
-- Uso básico
DROP VIEW IF EXISTS resumen_ingresos_hospital;
-- Uso avanzado (CASCADE)
-- Si otras vistas o reportes dependen de esta, CASCADE los eliminará también.
DROP VIEW resumen_ingresos_hospital CASCADE;
D. Consultar una Vista
Una vez creada, la vista se trata exactamente igual que una tabla en cualquier sentencia SELECT.
SELECT * FROM resumen_ingresos_hospital
WHERE ingresos_brutos > 5000;
Vistas Actualizables (Simple vs. Complex)
PostgreSQL permite realizar INSERT, UPDATE o DELETE directamente sobre una vista bajo ciertas condiciones:
- La vista debe tener una sola tabla en la cláusula
FROM. - No debe contener funciones de agregación (
SUM,AVG,COUNT),DISTINCT,GROUP BYoHAVING.
Para vistas complejas, se utilizan disparadores (Triggers) tipo INSTEAD OF.
Vistas Materializadas
En bases de datos con millones de registros, consultar una vista normal puede ser lento porque la consulta se ejecuta “en tiempo real”. PostgreSQL ofrece las Materialized Views, que sí guardan los datos físicamente en disco.
- Ventaja: Velocidad de lectura instantánea.
- Desventaja: Los datos no se actualizan solos; hay que refrescarlos manualmente.
-- Crear vista materializada
CREATE MATERIALIZED VIEW estadisticas_historicas AS
SELECT ... (consulta pesada) ...;
-- Refrescar los datos (por ejemplo, cada noche)
REFRESH MATERIALIZED VIEW estadisticas_historicas;
Práctica: Implementación de una “Capa de Privacidad” (Security View)
1. El Escenario
La dirección del hospital desea compartir datos con el departamento de estadística para analizar costos y urgencias. Sin embargo, por ley, está prohibido que el personal de estadística vea nombres completos o fechas exactas de nacimiento.
2. Requerimientos Técnicos
Debes crear una vista llamada v_metricas_anonimas que cumpla con:
- Ofuscación de Identidad: El nombre del paciente no debe aparecer. En su lugar, debe mostrarse la inicial del nombre seguido de asteriscos y el ID (ej:
J******* (ID: 45)). - Anonimización de Edad: No mostrar la fecha de nacimiento. Calcular la edad actual.
- Seguridad de Diagnóstico: Mostrar el código del diagnóstico y el nivel de urgencia.
- Cálculos Financieros: Mostrar el costo final de la atención (aplicando la lógica de recargos/subsidios que vimos antes).
- Filtro de Privacidad: Solo incluir registros de pacientes que tengan más de 18 años para evitar el manejo de datos de menores en esta vista.
3. Solución Propuesta
Esta consulta utiliza funciones de texto, matemáticas, fechas y lógica condicional dentro de la definición de la vista.
CREATE OR REPLACE VIEW v_metricas_anonimas AS
SELECT
-- 1. Ofuscación del nombre (Muestra la primera letra y oculta el resto)
LEFT(TRIM(p.nombre_completo), 1) || '******* (ID: ' || p.id_paciente || ')' AS paciente_anonimo,
-- 2. Transformación de fecha a edad (Dato menos sensible)
EXTRACT(YEAR FROM AGE(p.fecha_nacimiento)) AS edad_paciente,
p.genero,
a.fecha_atencion::DATE AS fecha_servicio,
a.codigo_diagnostico,
-- 3. Lógica de negocio embebida
CASE
WHEN a.nivel_urgencia <= 2 THEN 'CRÍTICO'
WHEN a.nivel_urgencia BETWEEN 3 AND 4 THEN 'ESTABLE'
ELSE 'CONTROL'
END AS categoria_urgencia,
-- 4. Cálculo financiero protegido
ROUND(
CASE
WHEN a.nivel_urgencia <= 2 THEN a.costo_base * 0.5
WHEN a.nivel_urgencia = 5 THEN a.costo_base * 1.2
ELSE a.costo_base
END, 2
) AS costo_final
FROM pacientes p
JOIN atenciones a ON p.id_paciente = a.id_paciente
-- 5. Filtro de cumplimiento (Compliance)
WHERE EXTRACT(YEAR FROM AGE(p.fecha_nacimiento)) >= 18;
4. Ejercicios Complementarios
Una vez creada la vista, resuelver estos retos sobre la vista:
- Análisis de Costos por Edad: “Utilizando la vista, determinar cuál es el costo promedio de atención para el segmento de pacientes entre 30 y 50 años”.
- Verificación de Seguridad: “Realizar un
SELECT *sobre la vista y explicar por qué es imposible identificar quién es el paciente que más gastó en el mes de marzo”. - Prueba de Integridad: “¿Qué sucede con la vista si el departamento de sistemas añade una nueva columna llamada
telefonoa la tablapacientes? ¿Se actualiza la vista automáticamente?”
- La razón no es un capricho de diseño, sino que se fundamenta en la integridad de las dependencias y la estructura del catálogo del sistema: Tuple Descriptor, la Cascada de Dependencias y Rules System. Comparativa para usar
OR REPLACE:
Sí – Cambiar la lógica de WHERE; no altera las columnas de salida
Sí – Añadir columnas al final; no desplaza ni inválida las posiciones de las columnas anteriores
No – Cambiar el nombre de columna; Rempe las referencias de objetos dependientes
No – Cambiar el tipo de dato: Inválida el Tuple Descriptor registrado en el catálogo
No – Cambiar el orden de columnas: PostgreSQL referencia columnas por posición interna en ciertos contextos ↩︎
Un comentario en “Vistas y Vistas Materializadas”
Los comentarios están cerrados.