sql >> Base de Datos >  >> RDS >> Database

Fundamentos de las expresiones de tabla, Parte 1

Este artículo es el primero de una serie sobre los fundamentos de las expresiones de tabla en T-SQL. Me centraré principalmente en cuatro tipos de expresiones de tabla con nombre, que se conocen en T-SQL como tablas derivadas, expresiones de tabla común (CTE), vistas y funciones con valores de tabla en línea (TVF en línea).

Me inspiré para escribir esta serie en mi buen amigo, Grant Fritchey, a quien conozco desde hace muchos años. Como señala repetidamente Grant, muchos de los que usan expresiones de tabla comunes en T-SQL piensan que SQL Server persiste en el conjunto de resultados de la consulta interna, y que la razón de esta creencia es el uso del término tabla en el nombre de la construcción. Cuando surge este tema en las discusiones de la comunidad, a menudo las personas argumentan que el uso del término tabla en el nombre de la construcción es inapropiado, ya que en realidad no es una tabla. Incluso hay sugerencias para iniciar una campaña de nombres con la esperanza de ver un cambio de nombre futuro para esta construcción, al menos en T-SQL. Algunas de las sugerencias incluyen expresión de consulta , vista en línea , vista a nivel de declaración , y otros.

Quizás esto sorprenda a algunos, pero en realidad encuentro el uso del término mesa en expresión de tabla común como muy apropiado. De hecho, encuentro el uso del término expresión de tabla según sea apropiado. Para mí, la mejor manera de describir qué es un CTE en T-SQL es una expresión de tabla con nombre . Lo mismo se aplica a lo que T-SQL llama tablas derivadas (la construcción de lenguaje específico en oposición a la idea general), vistas y TVF en línea. Todas son expresiones de tabla con nombre.

Si puede soportarme un poco, proporcionaré el razonamiento de mi punto de vista en este artículo. Se me ocurrió que tanto la confusión de nombres como la confusión sobre si hay un aspecto de persistencia en las expresiones de tablas se pueden aclarar con una mejor comprensión de los fundamentos de nuestro campo de sistemas de administración de bases de datos relacionales. Esos fundamentos son la teoría relacional, cómo SQL (el lenguaje estándar) se relaciona con él y cómo el dialecto T-SQL utilizado en las implementaciones de SQL Server y Azure SQL Database se relaciona con ambos.

Como punto de partida, desea poder responder las siguientes preguntas:

  • ¿Qué significa la independencia de los datos físicos principio en el modelo relacional significa?
  • ¿Qué es una tabla en SQL y cuál es su contraparte en el modelo relacional?
  • ¿Cuál es la propiedad de cierre del álgebra relacional?
  • ¿Qué es una expresión de tabla y cuál es la contraparte en el modelo relacional?

Una vez que pueda responder las preguntas anteriores correctamente, es muy probable que encuentre el uso del término expresión de tabla nombrada según corresponda para las construcciones antes mencionadas (lo que T-SQL llama tablas derivadas, CTE, vistas y TVF en línea).

No quiero parecer que tengo un conocimiento muy profundo de la teoría relacional. Mi experiencia es T-SQL. Reconozco que hay mucho más que no sé sobre la teoría relacional de lo que sé, y que algunas cosas que creo que sé, simplemente no lo son. Cuando leo los escritos de C. J. Dates sobre el tema, siento que apenas estoy arañando la superficie de lo que hay que saber, y que podría y debería esforzarme por comprenderlo mejor. Reconozco y creo firmemente que una buena comprensión de la teoría relacional se traduce directamente en una mejor comprensión de SQL y T-SQL, y en escribir un código T-SQL mejor, más preciso y más sólido. Para cualquiera que elija los datos como su carrera, recomiendo leer SQL y teoría relacional:cómo escribir código SQL preciso, 3.ª edición, de C. J. Date (O'Reilly 2015).

En la primera parte de esta serie quiero establecer una comprensión de mi uso de los términos expresión de tabla y expresión de tabla con nombre , que está de acuerdo con el uso de este término por parte de Date y, lamentablemente, no está de acuerdo con el uso de este término por parte del estándar SQL. Para lograr esto, proporcionaré algunos antecedentes de la teoría relacional y el estándar SQL. Pero como dije, recomiendo leer el libro de Date para una cobertura verdaderamente detallada de este tema.

Comenzaré explicando qué significa el principio de independencia de los datos físicos. A continuación, explicaré qué es una tabla en SQL y su contraparte en la teoría relacional. Luego explicaré qué significa la propiedad de cierre del álgebra relacional. Una vez que tenga una idea razonable de lo que es una tabla y lo que significa la propiedad de cierre, será bastante sencillo comprender qué es una expresión de tabla. Luego, mi atención se centrará en los detalles de T-SQL. Tengo mucho que decir sobre los fundamentos de las expresiones de tabla en T-SQL, tanto en términos del tratamiento conceptual como de los detalles de implementación, incluida la representación física y las consideraciones de ajuste de consultas.

Encuentro este tema fascinante y muy práctico una vez que profundizas en los detalles de implementación. De hecho, tengo tanto que decir al respecto que no estoy seguro de cuántas partes tendrá esta serie. Lo que puedo decirles con un alto grado de confianza es que habrá múltiples partes. Probablemente más de uno y menos de 100. En las próximas partes profundizaré en los tipos individuales de expresiones de tabla con nombre, consideraciones de modificación, aspectos en línea, aspectos de ordenación, correlaciones y más.

En mis ejemplos, usaré una base de datos de muestra llamada TSQLV5. Puede encontrar el script que crea y completa esta base de datos aquí, y su diagrama ER aquí.

Independencia de datos físicos

La independencia de los datos físicos es un principio de la teoría relacional que dice que los detalles de la implementación física deben ocultarse o ser transparentes para el usuario que envía las consultas al sistema de gestión de la base de datos relacional. En las consultas, se supone que los usuarios deben centrarse en qué necesitan usar operaciones lógicas basadas en álgebra relacional, en lugar de cómo para obtener los datos. Se supone que no deben preocuparse por cómo se estructuran, acceden y procesan los datos. Dichos detalles de implementación física tienden a diferir sustancialmente entre diferentes implementaciones (productos RDBMS). Incluso con el mismo RDBMS, los detalles de implementación física a veces cambian entre diferentes versiones y compilaciones. En teoría, la idea detrás del principio de independencia de los datos físicos es proteger la inversión del usuario eliminando la necesidad de revisar sus soluciones cuando actualiza su RDBMS a una nueva versión, o incluso cuando migra de un RDBMS a otro. Como probablemente sepas bien, en la práctica las cosas no son tan simples, pero ese es un tema para otra discusión.

¿Qué es una mesa?

Si ha estado trabajando con T-SQL o cualquier otro dialecto de SQL por un tiempo, desarrolla una comprensión intuitiva de lo que es una tabla. El problema es que, sin algunos antecedentes de teoría relacional, a menudo la comprensión intuitiva no es muy precisa. Un error típico es que intuitivamente tendemos a centrarnos en los detalles de implementación física. Por ejemplo, cuando está pensando en qué es una tabla, ¿está pensando en una tabla como una estructura lógica (un conjunto de filas) o está pensando en detalles de implementación física en la plataforma que está usando (en SQL Server , páginas, extensiones, montón versus índice agrupado, índices no agrupados, etc.)? Como usuario que escribe código SQL para consultar una tabla, siguiendo el principio de independencia de datos físicos, se supone que debe pensar en la tabla como una estructura lógica y dejar que el RDBMS se preocupe por los detalles de implementación física. Entonces, demos un paso atrás e intentemos averiguar qué es una tabla.

Una tabla es la contrapartida de SQL a la estructura principal de la teoría relacional:una relación. Para simplificar las cosas y limitar el alcance de mi cobertura, no voy a entrar en la distinción entre una variable de relación y un valor de relación. Si sigue mi recomendación y lee el libro de Date, muy rápidamente tendrá una imagen clara de tales sutilezas.

Una relación tiene un encabezado y un cuerpo.

El encabezado de la relación es un conjunto de atributos . En la teoría matemática de conjuntos, un conjunto no tiene orden ni duplicados. Se supone que debes identificar un atributo por su nombre y no por alguna posición. En consecuencia, los nombres de los atributos deben ser únicos.

¿Puedes identificar cuál es la contraparte de un atributo en SQL? Probablemente hayas adivinado que es una columna . Sin embargo, SQL realmente tiene una noción de orden para sus columnas en función de su orden de aparición en la instrucción CREATE TABLE. Por ejemplo, aquí está la instrucción CREATE TABLE para la tabla Sales.Shippers en la base de datos TSQLV5:

CREATE TABLE Sales.Shippers
(
  shipperid   INT          NOT NULL IDENTITY,
  companyname NVARCHAR(40) NOT NULL,
  phone       NVARCHAR(24) NOT NULL,
  CONSTRAINT  PK_Shippers  PRIMARY KEY(shipperid)
);

Consulta la tabla usando el notorio SELECT * , así:

SELECT * FROM Sales.Shippers;

Cuando ejecuté esta consulta en mi sistema, obtuve el siguiente resultado:

shipperid  companyname    phone
---------- -------------- ---------------
1          Shipper GVSUA  (503) 555-0137
2          Shipper ETYNR  (425) 555-0136
3          Shipper ZHISN  (415) 555-0138

SQL garantiza que las columnas se devolverán de izquierda a derecha según el orden de definición. Explicaré lo que sucede con las filas en breve. SQL incluso le permite referirse a la posición ordinal de la columna de la lista SELECT en la cláusula ORDER BY, así (no es que esté recomendando esta práctica, ni tampoco Aaron Bertrand):

SELECT shipperid, companyname, phone
FROM Sales.Shippers
ORDER BY 2;

Esta consulta genera el siguiente resultado:

shipperid  companyname    phone
---------- -------------- ---------------
2          Shipper ETYNR  (425) 555-0136
1          Shipper GVSUA  (503) 555-0137
3          Shipper ZHISN  (415) 555-0138

El cuerpo de una relación es un conjunto de tuplas . Nuevamente, recuerde que un conjunto no tiene orden ni duplicados. Por lo tanto, una relación debe tener al menos una clave candidata que le permita identificar de forma única una tupla. La contrapartida de SQL a una tupla es una fila . Sin embargo, en SQL no está obligado a definir una clave en una tabla y, si no lo hace, puede terminar con filas duplicadas. Incluso si tiene una clave definida en su tabla, puede obtener filas duplicadas devueltas de una consulta en la tabla. He aquí un ejemplo:

SELECT country FROM HR.Employees;

Esta consulta genera el siguiente resultado:

country
--------
USA
USA
USA
USA
UK
UK
UK
USA
UK

Esta consulta no produce un resultado relacional debido a la posibilidad de filas duplicadas. Mientras que la teoría relacional se basa en la teoría de conjuntos, SQL se basa en la teoría de conjuntos múltiples. Un conjunto múltiple (también conocido como un superconjunto o una bolsa) puede tener duplicados. SQL le brinda una herramienta para eliminar duplicados con una cláusula DISTINCT, así:

SELECT DISTINCT country FROM HR.Employees;

Esta consulta genera el siguiente resultado:

country
--------
UK
USA

Lo que SQL mantiene de la teoría relacional en términos del cuerpo de la tabla es la propiedad sin orden. A menos que agregue una cláusula ORDER BY en la consulta, no tiene ninguna garantía de que el resultado tendrá un orden específico entre las filas. Entonces, el cuerpo del resultado de la consulta anterior es relacional, al menos en el sentido de que no tiene duplicados y no tiene un orden garantizado.

Suponga que consulta una tabla en SQL Server y no incluye una cláusula ORDER BY en la consulta. ¿Espera que SQL Server siempre devuelva las filas en un orden específico como comportamiento garantizado? Mucha gente lo hace. Muchos piensan que siempre recuperará las filas según el orden del índice agrupado. Ese es un buen ejemplo de ignorar el principio de independencia de los datos físicos y hacer suposiciones basadas en la intuición, y quizás en el comportamiento observado en el pasado. Microsoft sabe que una consulta SQL sin una cláusula ORDER BY no garantiza ningún orden entre las filas de resultados y, por lo tanto, incluso si a nivel físico los datos residen en una estructura de índice, SQL Server no tiene que procesar los datos en el índice. pedido. Puede elegir, bajo ciertas condiciones físicas, hacerlo, pero puede elegir no hacerlo bajo otras condiciones físicas. Recuerde también que los detalles de implementación física pueden cambiar entre diferentes versiones y compilaciones del producto. Si desea garantizar que la consulta devolverá las filas de resultados en un orden específico, la única forma de garantizar esto es introducir una cláusula ORDER BY en la consulta más externa.

Como probablemente haya deducido, los diseñadores de SQL realmente no vieron como una prioridad seguir la teoría relacional. Y lo que describí aquí son solo algunos ejemplos. Hay muchos más. Como mencioné anteriormente, mi objetivo en este artículo es proporcionar suficiente información teórica crítica para aclarar la confusión que rodea a las expresiones de tabla, antes de comenzar a profundizar en los detalles de T-SQL en artículos futuros.

¿Qué es una expresión de tabla?

El álgebra relacional (el álgebra que define operaciones sobre relaciones en la teoría relacional) tiene un cierre propiedad. Lo que significa es que una operación sobre relaciones produce una relación. Un operador relacional opera en una o más relaciones como entrada y produce una sola relación como salida. La propiedad de cierre le permite anidar operaciones. Una expresión relacional es una expresión que opera sobre relaciones y devuelve una relación. Por lo tanto, se puede usar una expresión relacional donde el álgebra relacional espera una relación.

Si lo piensa, no es diferente a las operaciones con números enteros que dan un resultado entero. Suponga que la variable @i es una variable entera. La expresión @i + 42 produce un número entero y, por lo tanto, se puede usar donde se espera un número entero, como en (@i + 42) * 2.

Dado que una tabla en SQL es la contraparte de una relación en la teoría relacional, aunque no muy exitosa, una expresión de tabla en SQL es la contraparte de una expresión relacional. Como se mencionó anteriormente, uso el término expresión de tabla siguiendo el uso de este término por parte de C. J. Dates. El estándar SQL tiene una gran cantidad de términos confusos, algunos de los cuales me temo que no son muy apropiados. Por ejemplo, SQL Standard usa el término expresión de tabla para describir específicamente una expresión basada en las cláusulas de consulta que comienzan con una cláusula FROM obligatoria e incluyen opcionalmente las cláusulas WHERE, GROUP BY, HAVING y WINDOW (la última no se admite en T -SQL), y excluyendo la cláusula SELECT. Aquí está la especificación del estándar:

7.4

Función
Especifique una tabla o una tabla agrupada.

Formato
::=

[ ]
[ ]
[ ]
[ ]

Es cierto que el resultado de lo que el estándar llama una expresión de tabla se considera una tabla, pero no puede usar dicha expresión como una consulta independiente. La versión de fecha de la expresión de la tabla de términos es en realidad más cercana a lo que el estándar SQL llama expresión de consulta . Aquí está la especificación del estándar para lo que llama expresión de consulta:

7.17

Función
Especifique una tabla.

Formato
::=
[ ]
[ ] [ ] [ ]
::=
CON [ RECURSIVO ]
::=
[ { }… ]
::=
[ ]
AS

[ ]
::=

::=

| UNION [ TODOS | DISTINCT ]
[ ]
| EXCEPTO [ TODO | DISTINCT ]
[ ]
::=

| INTERSECCIÓN [ TODO | DISTINCT ]
[ ]
::=

|
[ ] [ ] [ ]

::=

|
|
::=
TABLE
::=
CORRESPONDING [ BY ]
::=

::=
ORDER BY
::=
OFFSET { FILA | FILAS }
::=
FETCH { PRIMERO | SIGUIENTE } [ ] { FILA | FILAS } { SOLO | CON LAZOS }
::=

|
::=

::=

::=
PERCENT

7.3

Función
Especifique un conjunto de para construir una tabla.

Formato
::=
VALUES
::=
[ { }… ]
::=
VALUES
::=

[ { }… ]

Observe que esta especificación incluye lo que T-SQL llama expresión de tabla común, aunque el estándar en realidad no usa este término, sino que simplemente lo llama con elemento de lista . Observe también que la llamada expresión de consulta no tiene que estar basada en una consulta, sino que podría basarse en lo que se llama un constructor de valores de tabla (el uso de una cláusula VALUES para construir un conjunto de filas). Por último, aunque la expresión de consulta estándar se basa en una expresión, devuelve una tabla y se puede usar donde normalmente se espera una tabla. Por estas razones, encuentro mucho más apropiado el uso que hace Date del término expresión de tabla.

Conclusión

Puedo ver por qué algunos pueden encontrar la insistencia en los nombres y la terminología como un poco pedante y tal vez incluso una pérdida de tiempo. Sin embargo, me siento muy diferente. Creo que en cualquier campo, la aspiración a usar nombres propios y terminología te obliga a estudiar bien los fundamentos, y reflexiona sobre tus conocimientos. Con la esperanza de que en este artículo no logré alienarlo lo suficiente como para no querer continuar con las próximas partes de la serie, a partir del artículo del próximo mes, voy a centrarme en la forma en que se nombran los diferentes tipos. las expresiones de tabla se manejan usando T-SQL en SQL Server y Azure SQL Database.