Vistas SQL explicadas: cree, use y evite los errores, con ejemplos

  1. Inicio
  2. Blog
  3. Bases de datos y SQL

Bases de datos y SQL

Vistas SQL explicadas: Cree, utilice y evite los errores, con ejemplos

Una vista es una consulta guardada que puede usar como una tabla. Aprenda cómo crear una, por qué las vistas mantienen la coherencia de los informes, qué hacen y qué no hacen para mejorar el rendimiento y las trampas que las rompen.

8 min de lectura
Vistas SQL explicadas: cree, use y evite los errores, con ejemplos

Puntos clave

  • Una vista es una consulta almacenada con nombre que puede seleccionar como si fuera una tabla.
  • Una vista normal no almacena datos, por lo que siempre muestra los resultados actuales.
  • Las vistas simplifican consultas complejas, mantienen la lógica empresarial coherente y pueden restringir el acceso a las columnas.
  • No hacen una consulta más rápido por sí solos, aunque las vistas materializadas sí pueden hacerlo.

La misma consulta de informe de veinte líneas se copió en cinco paneles y cada copia se desvió un poco. Uno cuenta los pedidos cancelados, mientras que otro no. Las vistas SQL resuelven esto definiendo esa lógica una vez, en la base de datos, con un nombre claro.

Ejecutamos todos los ejemplos a continuación en SQLite 3.50 y los resultados mostrados provienen de esa ejecución. Las vistas son SQL estándar, pero detalles como la actualización a través de una vista, las vistas materializadas y el manejo de dependencias varían entre las bases de datos, y los señalamos.

¿Qué es una vista?

Una vista es una declaración SELECT guardada en la base de datos con un nombre. Cuando consulta la vista, la base de datos ejecuta esa consulta guardada. Actúa como una tabla de lectura, pero una vista normal no contiene su propia copia de los datos.

Piense en un filtro guardado en una hoja de cálculo. El filtro no es una segunda copia de la hoja. Es una forma de mirar los mismos datos, que siempre reflejan los últimos valores.

Las tablas de muestra

CREATE TABLE customers (
  id INT PRIMARY KEY, name TEXT, city TEXT, email TEXT, credit_limit INT
);
CREATE TABLE orders (
  id INT PRIMARY KEY, customer_id INT, total INT, status TEXT
);

INSERT INTO customers VALUES
 (1,'Asha','Pune','asha@example.com',50000),
 (2,'Ben','Delhi','ben@example.com',20000),
 (3,'Chitra','Pune','chitra@example.com',80000);

INSERT INTO orders VALUES
 (101,1,1200,'paid'), (102,1,800,'paid'),
 (103,2,300,'pending'), (104,3,2500,'paid');

Crear una vista

Esta vista resume los pedidos de cada cliente. Oculta una unión, una agrupación y una expresión CASE detrás de un nombre simple:

CREATE VIEW customer_sales AS
SELECT c.id, c.name, c.city,
       COUNT(o.id) AS orders,
       COALESCE(SUM(CASE WHEN o.status = 'paid' THEN o.total END), 0) AS paid_total
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.name, c.city;

Ahora cualquiera puede usarlo, sin saber cómo funciona:

SELECT * FROM customer_sales ORDER BY paid_total DESC;

-- 3 | Chitra | Pune  | 1 | 2500
-- 1 | Asha   | Pune  | 2 | 2000
-- 2 | Ben    | Delhi | 1 |    0

SELECT name, paid_total FROM customer_sales WHERE city = 'Pune';

-- Asha   | 2000
-- Chitra | 2500

Ben aparece con cero, porque la vista usa LEFT JOIN y COALESCE. Decisiones como esta, tomadas una vez en la vista, son exactamente las que mantienen la coherencia de los informes. Para actualizar su comprensión del manejo de NULL, consulte Valores NULL de SQL.

Las vistas siempre están actualizadas.

Dado que una vista normal ejecuta su consulta cada vez, aparecen nuevos datos inmediatamente. Agregamos un pedido pagado para Ben y consultamos la vista nuevamente:

INSERT INTO orders VALUES (105, 2, 900, 'paid');

SELECT name, paid_total FROM customer_sales WHERE name = 'Ben';

-- Ben | 900

No hubo ningún paso de actualización ni copia para mantener la sincronización. Ésta es la diferencia clave con guardar los resultados de la consulta en una tabla separada.

Ocultar columnas

Las vistas se utilizan a menudo para exponer solo las columnas que una persona o aplicación necesita. Aquí, las direcciones de correo electrónico y los límites de crédito quedan fuera:

CREATE VIEW public_customers AS
SELECT id, name, city FROM customers;

-- columns: id, name, city

En bases de datos con permisos, como PostgreSQL, SQL Server y MySQL, puede otorgar acceso a la vista a un usuario informador, pero no a la tabla subyacente. SQLite no tiene cuentas de usuario, por lo que solo pudimos mostrar la restricción de la columna. Trate una vista como una capa de protección. Los datos confidenciales aún necesitan un control de acceso adecuado y algunas bases de datos ofrecen seguridad a nivel de fila para filtrar filas por usuario.

Rendimiento: las vistas no aumentan la velocidad

Un mito común es que las vistas aceleran las consultas. Una vista normal se reemplaza por su definición cuando la consulta, por lo que la base de datos hace el mismo trabajo que si usted mismo hubiera escrito la consulta completa. Nuestro plan de ejecución mostró la unión y agrupación de la vista ejecutándose como parte de la consulta:

EXPLAIN QUERY PLAN SELECT * FROM customer_sales WHERE city = 'Pune';

-- CO-ROUTINE customer_sales
-- SCAN c ...
-- SEARCH o USING AUTOMATIC COVERING INDEX (customer_id=?) LEFT-JOIN
-- USE TEMP B-TREE FOR GROUP BY
-- SCAN customer_sales

Por lo tanto, una vista de una consulta lenta sigue siendo una consulta lenta. La velocidad proviene de los índices y de un buen diseño de consultas, como se explica en Optimización de consultas SQL y Explicación de los índices SQL. Tenga cuidado también con las vistas basadas en otras vistas. Las capas de nido hacen que sea fácil unir la misma mesa grande varias veces sin que te des cuenta.

Vistas materializadas

Una vista materializada sí almacena sus resultados, como una tabla almacenada en caché. Las lecturas son rápidas, pero los datos están tan actualizados como la última actualización.

-- PostgreSQL
CREATE MATERIALIZED VIEW daily_sales AS
SELECT order_date, SUM(total) AS revenue FROM orders GROUP BY order_date;

REFRESH MATERIALIZED VIEW daily_sales;
Característica Vista normal Vista materializada
Almacena datos No si
Frescura Siempre actual A partir de la última actualización
Velocidad de lectura Igual que la consulta Rápido
Costo de almacenamiento Ninguno si
Bueno para Simplificación, coherencia Informes y paneles pesados

El soporte varía. PostgreSQL y Oracle tienen vistas materializadas y SQL Server ofrece vistas indexadas con sus propias reglas. SQLite y MySQL carecen de ellos, por lo que la gente usa una tabla de resumen regular que se actualiza según un cronograma. No ejecutamos el ejemplo de PostgreSQL para este artículo.

Consejo: Antes de crear una vista materializada, decida qué tan obsoletos pueden estar los datos. “Actualizado cada hora” debe ser aceptable para las personas que leen el informe, así que dígaselo.

¿Puedes actualizar una vista?

Depende de la base de datos y la vista. Una vista simple de una sola tabla, sin agrupación o DISTINCT, a menudo se puede actualizar en PostgreSQL, MySQL y SQL Server, y el cambio pasa a la tabla. Una vista con combinaciones o agregados generalmente no puede hacerlo, porque la base de datos no puede decir qué fila cambiar.

SQLite no permite escrituras directas en vistas en absoluto. Nuestro intento fracasó:

INSERT INTO customer_sales (name) VALUES ('X');

-- cannot modify customer_sales because it is a view

Algunas bases de datos admiten activadores INSTEAD OF para hacer que se pueda escribir en una vista, y muchas ofrecen WITH CHECK OPTION, que detiene escrituras que no serían visibles a través de la vista. En la práctica, la mayoría de los equipos mantienen las vistas como de solo lectura y escriben en las tablas.

Dependencias y roturas

Una vista depende de las tablas desde las que lee. Creamos una vista en una tabla y luego la soltamos:

CREATE TABLE ghost AS SELECT 1 AS x;
CREATE VIEW v_ghost AS SELECT x FROM ghost;
DROP TABLE ghost;

SELECT * FROM v_ghost;
-- no such table: main.ghost

SQLite permitió la caída y solo falló más tarde, cuando se usó la vista. Otras bases de datos, como PostgreSQL, se niegan a eliminar una tabla de la que depende una vista, a menos que agregue CASCADE, lo que también elimina la vista. De cualquier manera, cambiar el nombre o eliminar una columna puede interrumpir las vistas, así que verifíquelas en su prueba de regresión después de realizar cambios en el esquema.

También hay una trampa sutil con SELECT * en una vista. Creamos CREATE VIEW star AS SELECT * FROM customers y luego agregamos una columna a la tabla. En SQLite, la vista eligió la nueva columna. Otras bases de datos, incluida PostgreSQL, expanden la lista de columnas cuando se crea la vista, por lo que no aparecen nuevas columnas. Así que enumere las columnas explícitamente. Documenta la vista y se comporta igual en todas partes.

Administrar vistas

Tarea Sintaxis común
crear CREAR VER nombre COMO SELECCIONAR...
Reemplazar CREATE OR REPLACE VIEW (PostgreSQL, MySQL, Oracle)
Reemplazar en SQL Server CREAR O ALTERAR VISTA
Quitar Nombre de DROP VIEW
Eliminar de forma segura SOLTAR VER SI EXISTE nombre

Al eliminar una vista solo se elimina la consulta guardada. En nuestra prueba, la tabla customers todavía tenía las tres filas después de eliminar public_customers. Mantenga las definiciones de vista en el control de versiones junto con sus migraciones, para que los cambios se revisen como cualquier otro código.

Ver vs CTE vs tabla

Opción Toda la vida Almacena datos Lo mejor para
Ver hasta caer No Lógica compartida utilizada por muchas consultas.
CTE una declaración No Organizar una única consulta compleja
Vista materializada hasta caer si Lecturas rápidas de resultados costosos
mesa hasta caer si Los datos reales

Errores comunes

  • Esperando un aumento de velocidad. Una vista normal ejecuta su consulta cada vez.
  • Usando SELECT * en vistas. El comportamiento difiere entre las bases de datos cuando las tablas cambian.
  • Anidamiento profundo. Las vistas creadas sobre vistas ocultan uniones costosas.
  • Usar ORDER BY dentro de una vista. El orden no está garantizado cuando lo consulta, así que ordene en la consulta externa.
  • Nombres poco claros. Un prefijo como v_, o un sustantivo claro como customer_sales, ayudan.
  • Olvidar vistas durante las migraciones. Pruébelas después de cada cambio de esquema.

Conclusión

Las vistas son una forma sencilla de darle un lugar a la lógica importante en la base de datos. Úselos para mantener la coherencia de los informes y ocultar columnas innecesarias, no como un truco de rendimiento. Para comenzar, busque una consulta que aparezca en varios lugares de su código, conviértala en una vista con columnas explícitas y señale a cada persona que llama.

Preguntas frecuentes

¿Qué es una vista en SQL?

Una vista es una consulta SELECT guardada con un nombre. Lo consulta como una tabla y la base de datos ejecuta la consulta subyacente cada vez, por lo que los resultados siempre están actualizados.

¿Una vista SQL almacena datos?

Una vista normal no almacena datos, solo la consulta. Una vista materializada almacena resultados y debe actualizarse para mantenerse actualizada.

¿Las vistas son más rápidas que las tablas?

No. Una vista normal hace el mismo trabajo que su consulta subyacente. Las vistas materializadas pueden acelerar las lecturas, a costa del almacenamiento y la frescura.

¿Puedes insertar en una vista?

A veces. Las vistas simples de una sola tabla a menudo se pueden actualizar en PostgreSQL, MySQL y SQL Server. Las vistas con uniones o agrupaciones generalmente no lo son y SQLite no lo permite.

¿Qué sucede con una vista si se elimina la tabla?

Depende de la base de datos. Algunos se niegan a eliminar la tabla mientras una vista depende de ella, mientras que otros lo permiten y la vista falla cuando se consulta.

sigue aprendiendo

Trabajar con Stack Quora

¿Necesitas ayuda con pruebas, WordPress o SEO?

Ayudamos a los equipos a enviar mejor software y hacer crecer sus sitios. Cuéntenos en qué está trabajando y le sugeriremos un siguiente paso claro.

Sigue leyendo

Más guías sobre testing, IA y desarrollo moderno

¿Te gustó este artículo? Elige un tema y salta directo a nuestros tutoriales más recientes.

Inteligencia artificial

Explicación de las alucinaciones de la IA: por qué los modelos de lenguaje inventan cosas y cómo reducirlas

Se explicaron las alucinaciones de la IA: qué son, por qué los modelos de lenguaje las producen, tipos comunes, cómo reducirlas con conexión a tierr…

Leer artículo →
DevOps

Explicación de las variables de entorno: archivos .env, secretos y configuración bien hechos

Variables de entorno explicadas con ejemplos de Python que ejecutamos: leerlas y configurarlas, por qué cada valor es una cadena, archivos .env, her…

Leer artículo →
Desarrollo de software

Explicación de la limitación de velocidad de API: algoritmos, encabezados y manejo de errores 429

La limitación de la tasa de API se explica con una simulación que ejecutamos: depósito de tokens, ventana fija, ventana deslizante, 429 respuestas, …

Leer artículo →
Automatización de pruebas

Burlarse en Python: unittest.mock, patch y los errores que hacen que las pruebas mientan

Burlarse en Python con unittest.mock, probado: Mock y return_value, side_effect, parches donde se usa un nombre, especificación y autospec, fechas d…

Leer artículo →
Pruebas de software

Explicación de la cobertura del código: cobertura de línea versus sucursal y lo que realmente significa 100%

Cobertura del código explicada con una ejecución real de cobertura.py: cobertura de línea, rama y condición, lectura de un informe, por qué una cobe…

Leer artículo →
Bases de datos y SQL

DELETE vs TRUNCATE vs DROP en SQL: diferencias, reversión y cuándo usar cada uno

DELETE vs TRUNCATE vs DROP explicado con SQL probado: qué elimina cada uno, reversión, activadores, restablecimiento de identidad, velocidad y en qu…

Leer artículo →
Bases de datos y SQL

Vistas SQL explicadas: cree, use y evite los errores, con ejemplos

Vistas SQL explicadas con consultas que ejecutamos: creación de una vista, resultados en vivo, ocultación de columnas, rendimiento, vistas actualiza…

Leer artículo →
Desarrollo de software

Interfaz TypeScript versus tipo: diferencias reales, probadas con el compilador

Interfaz TypeScript versus tipo, verificado con el compilador real: qué pueden hacer ambos, qué puede hacer solo uno, fusión de declaraciones, exten…

Leer artículo →
Desarrollo de software

Python *args y **kwargs explicados: funciones flexibles con ejemplos claros

Python *args y **kwargs explicados con el código que ejecutamos: empaquetado y desempaquetado, orden de parámetros, argumentos solo de palabras clav…

Leer artículo →
Desarrollo de software

Funciones Lambda de Python: sintaxis, usos reales y cuándo no utilizarlas

Funciones lambda de Python explicadas con el código que ejecutamos: sintaxis, clasificación con clave, mapa y filtro, cierres, trampa de enlace tard…

Leer artículo →
Inteligencia artificial

¿Qué son los agentes de IA? Cómo funcionan, con un bucle de agente simple que puedes ejecutar

¿Qué son los agentes de IA? Una guía sencilla sobre el bucle del agente, las herramientas, la memoria y las barreras de seguridad, con un pequeño bu…

Leer artículo →
DevOps

Monitoreo versus observabilidad: la verdadera diferencia, con registros, métricas y seguimientos

Explicación del monitoreo versus observabilidad: fallas conocidas y desconocidas, registros, métricas y seguimientos, un recorrido por incidentes de…

Leer artículo →
DevOps

Docker Volumes versus Bind Mounts: persistir los datos del contenedor de la manera correcta

Se explican los volúmenes de Docker frente a los montajes de enlace: por qué desaparecen los datos del contenedor, volúmenes con nombre, montajes de…

Leer artículo →
Automatización de pruebas

TDD vs BDD: diferencias clave, una función creada en ambos sentidos y cuándo usar cada una

TDD vs BDD explicado con una característica de descuento construida en ambos sentidos: refactor rojo-verde con el código que ejecutamos, escenarios …

Leer artículo →
Desarrollo de software

Git merge vs rebase: diferencias, ejemplos y cuándo usar cada uno

Git merge vs rebase explicado con salida real del log, una tabla comparativa, la regla de oro del rebase y un flujo de trabajo seguro para equipos.

Leer artículo →
Desarrollo de software

List comprehension en Python: sintaxis, ejemplos y cuándo evitarla

List comprehension en Python explicada: sintaxis, filtros, if-else, bucles anidados, tiempos medidos y cuándo es mejor un bucle for normal.

Leer artículo →