Nace una alternativa de código abierto a SQL

Una de las intenciones originales de inventar SQL es obviamente reducir la dificultad de las personas que implementan los cálculos de consulta de datos. En SQL se utiliza mucho vocabulario y gramática similar al inglés, y se espera que el personal no técnico también pueda dominarlo. De hecho, SQL simple puede leerse en inglés, incluso por personas sin experiencia en programación.

Sin embargo, frente a los requisitos de cálculo de consultas ligeramente complejos, SQL parecerá impotente y, a menudo, escribirá cientos de líneas de declaraciones anidadas de varios niveles. Este tipo de SQL, sin mencionar que es difícil de completar para el personal no técnico, no es fácil ni siquiera para los programadores profesionales y, a menudo, se convierte en el punto culminante de los exámenes de aplicación de muchas empresas de software. SQL de tres y cinco líneas solo existe en libros de texto y cursos de capacitación. En realidad, el SQL utilizado para la consulta de informes generalmente se mide en "K".

Análisis y discusión de las dificultades de SQL

¿Por qué es esto? Usamos un ejemplo muy simple para examinar las deficiencias de SQL en términos de cálculos.

Considere una tabla de rendimiento de ventas con tres campos (se omite la información de la fecha por simplicidad):

cantidad de ventas Tabla de rendimiento de ventas
ventas Nombre del vendedor, suponiendo que no haya un nombre duplicado
producto productos a la venta
cantidad Ventas de este vendedor en este producto

Ahora queremos conocer la lista de los 10 mejores vendedores que son acondicionadores de aire y televisores.

Este problema no es difícil, la gente naturalmente diseñará el siguiente proceso de cálculo:

1. Ordene por ventas de acondicionadores de aire para encontrar los 10 mejores;

2. Ordene por ventas de TV para encontrar los 10 mejores;

3. Tome la intersección de los resultados de 1 y 2 para obtener la respuesta;

Hagámoslo ahora con SQL.

Early SQL no admite pasos, por lo que es un poco engorroso escribir los dos primeros pasos en subconsultas:

select * from     ( select top 10 sales from sales_amount where product='AC' order by amount desc )intersect     ( select top 10 sales from sales_amount where product='TV' order by amount desc )

Más tarde, SQL también descubrió que sería problemático no hacerlo paso a paso, por lo que proporcionó la sintaxis CTE, que puede usar la palabra clave with para nombrar los resultados de la consulta en los pasos anteriores y usarlos en los siguientes pasos:

with A as       select top 10 sales from sales_amount where product='AC' order by amount desc     B as       select top 10 sales from sales_amount where product='TV' order by amount descselect * from A intersect B

Las oraciones no son más cortas, pero las ideas se aclaran paso a paso.

Ahora, hagamos el problema un poco más complicado y cambiémoslo para calcular los vendedores cuyas ventas de todos los productos están entre los 10 principales. Imagínese cómo calcularlo. Es fácil pensar en ello extendiendo las ideas mencionadas anteriormente. :

1. Enumere todos los productos;

2. Saque los 10 mejores de cada producto y guárdelos por separado;

3. Tome la intersección de todos los 10 primeros;

Sin embargo, usar la sintaxis CTE solo puede hacer más cálculos para una cierta cantidad de resultados intermedios. Y no sabemos de antemano que hay varios productos en total, lo que hará que el número de cláusulas en CON sea incierto, por lo que no podemos escribirlo.

Otra forma de pensar:

1. Agrupe los datos por producto, ordene cada grupo y saque los 10 principales;

2. Tome la intersección de todos los 10 primeros;

Pero esto necesita guardar el resultado de la agrupación del primer paso, y este resultado intermedio es una tabla, que tiene un campo para almacenar los 10 miembros principales de la agrupación correspondiente, es decir, el valor del campo será un conjunto, que no es compatible con SQL Este tipo de datos todavía no se puede escribir.

Si tiene el soporte de las funciones de ventana, puede cambiar su forma de pensar nuevamente. Después de agrupar por producto, calcule la cantidad de veces que cada vendedor aparece en el top 10 de todos los grupos. Si es igual al número total de productos, significa que el vendedor está en las ventas de todos los productos están en el top 10.

select salesfrom ( select sales,     from ( select sales,                   rank() over (partition by product order by amount desc ) ranking            from sales_amount)     where ranking <=10 )group by saleshaving count(*)=(select count(distinct product) from sales_amount)

Se puede escribir, pero ¿cuántas personas pueden escribir SQL tan complejo?

Las dos primeras ideas simples no se pueden realizar con SQL, solo se puede usar la tercera forma indirecta de pensar. La razón aquí radica en una importante deficiencia de SQL: colección incompleta .
Aunque SQL tiene el concepto de conjuntos, no proporciona conjuntos como un tipo de datos básico. El valor de una variable o campo no puede ser un conjunto, y no hay otro tipo de datos de conjunto excepto las tablas, lo que hace que una gran cantidad de operaciones de conjunto en el pensamiento Se requieren desvíos al escribir y escribir.

Usamos la palabra clave top en el cálculo anterior. De hecho, no existe tal cosa en la teoría del álgebra relacional (se puede combinar con otros cálculos). Esta no es una forma estándar de escribir SQL.

A ver que tan dificil es encontrar el top 10 sin top?

La idea general es esta: encuentre la cantidad de miembros que son más grandes que usted como clasificación, y luego saque a los miembros cuya clasificación no exceda 10, y escriba el SQL de la siguiente manera:

select salesfrom ( select A.sales sales, A.product product,             (select count(*)+1 from sales_amount              where A.product=product AND A.amount<=amount) ranking       from sales_amount A )where product='AC' AND ranking<=10

o

select salesfrom ( select A.sales sales, A.product product, count(*)+1 ranking       from sales_amount A, sales_amount B       where A.sales=B.sales and A.product=B.product AND A.amount<=B.amount       group by A.sales,A.product )where product='AC' AND ranking<=10

¡Puede que no sea fácil para los programadores profesionales escribir tales sentencias SQL! En cambio, solo se calcula un top 10.

Dar un paso atrás, aunque haya un trompo, solo facilita sacar la parte anterior. Si cambiamos el problema para que ocupe el lugar del 6 al 10, o encontramos al vendedor que tiene más del 10% de ventas que el siguiente, estas dificultades aún existen, y aún se necesita una forma indirecta de pensar para hacerlo con SQL.

La razón de este fenómeno es otra importante deficiencia de SQL: la falta de soporte ordenado . SQL hereda el conjunto desordenado en matemáticas, lo que hace que los cálculos relacionados con el orden sean bastante difíciles, y es concebible cuán comunes serán los cálculos relacionados con el orden (como en comparación con el mes pasado, en comparación con el mismo período del año pasado, 20% superior, clasificación, etc).

La función de ventana agregada en el estándar SQL2003 proporciona algunas capacidades de cálculo relacionadas con el orden, lo que hace que algunos de los problemas anteriores tengan soluciones más simples y alivia este problema de SQL en cierta medida. Sin embargo, el uso de funciones de ventana suele ir acompañado de subconsultas, que no permiten a los usuarios utilizar directamente el acceso secuencial a los miembros de la colección, y todavía hay muchas operaciones ordenadas que son difíciles de resolver.

Ahora queremos centrarnos en la proporción de género de los "buenos" vendedores calculada anteriormente, es decir, cuántos hombres y mujeres hay. En circunstancias normales, la información de género del vendedor se registrará en la lista en lugar de la tabla de desempeño, simplificada de la siguiente manera:

empleado formulario de empleado
nombre Nombre del empleado, suponiendo que no haya nombres duplicados
género sexo del empleado

Ya hemos calculado la lista de "buenos" vendedores, y la idea más natural es usar la lista para averiguar su género al ir a la lista y contarlos nuevamente. Pero obtener información a través de tablas en SQL requiere una unión entre tablas, por lo que, siguiendo el resultado original, el SQL se escribiría como:

select employee.gender,count(*)from employee,    ( ( select top 10 sales from sales_amount where product='AC' order by amount desc )    intersect    ( select top 10 sales from sales_amount where product='TV' order by amount desc ) ) Awhere A.sales=employee.namegroup by employee.gender

Solo una tabla de asociación más conducirá a tal engorro, pero en realidad, hay una gran cantidad de información almacenada en las tablas y, a menudo, hay varias capas. Por ejemplo, el vendedor tiene un departamento y el departamento tiene un gerente. Ahora queremos saber qué gerentes son responsables del "buen" vendedor, por lo que necesitamos conectar tres tablas. No es fácil escribir claramente dónde y grupo en este cálculo. Es trabajo.

Esta es la siguiente dificultad importante de SQL de la que queremos hablar: falta de mecanismo de referencia de objetos , la relación entre objetos en álgebra relacional se mantiene completamente por el mismo valor de clave externa, lo que no solo es muy ineficiente cuando se busca, sino también no puede ser utilizado por claves foráneas El miembro de registro puntiagudo se trata directamente como un atributo de este registro.Imagínese si la oración anterior se puede escribir así:

select sales.gender,count(*)from (…) // …是前面计算“好”销售员的SQLgroup by sales.gender

Obviamente, esta oración no solo es más clara, sino también más eficiente desde el punto de vista computacional (sin cálculos de unión).

Analizamos varias dificultades importantes de SQL a través de un ejemplo simple, que también es la razón principal por la que SQL es difícil o largo de escribir. El proceso de resolución de problemas comerciales basado en un sistema informático es el proceso de traducir la solución del problema comercial en una gramática informática formal (similar a los estudiantes de primaria que resuelven problemas y traducen los problemas en cuatro operaciones aritméticas formalizadas). Las dificultades mencionadas anteriormente en SQL causarán grandes obstáculos para la traducción de soluciones de problemas. En casos extremos, ocurrirá un fenómeno tan extraño: la dificultad de formalizar la solución del problema en una gramática computacional es mucho mayor que la dificultad de resolver el problema. mismo _

Otro ejemplo que es fácil de entender para los programadores es que usar SQL para hacer cálculos de datos es similar a usar lenguaje ensamblador para completar las cuatro operaciones aritméticas. Es fácil para nosotros escribir una fórmula como 3+5*7, pero si usamos lenguaje ensamblador (tomando X86 como ejemplo), tenemos que escribirla como

mov ax,3mov bx,5mul bx,7add ax,bx

Este tipo de código es mucho peor que 3+5*7 tanto en escritura como en lectura (será aún más terrible si encuentra decimales). Aunque no es demasiado problema para los programadores expertos, esta forma de escribir sigue siendo demasiado oscura para la mayoría de las personas.En este sentido, FORTRAN es de hecho un gran invento.

Para mayor comodidad de la comprensión, el ejemplo que damos no deja de ser una tarea muy sencilla. Las tareas en realidad son mucho más complicadas que estos ejemplos, y se enfrentarán muchas dificultades, grandes y pequeñas, en el proceso. Escriba unas pocas líneas más para esta pregunta y unas pocas líneas más para esa pregunta. No es sorprendente que una tarea un poco más complicada escriba cientos de líneas de SQL anidado de varios niveles. Además, estos cientos de líneas suelen ser una declaración. Debido a razones de ingeniería, SQL es difícil de depurar, lo que exacerba aún más la dificultad del análisis de consultas complejas.

más ejemplos

Pongamos algunos ejemplos más para ilustrar estos aspectos.

Para hacer que el SQL del ejemplo sea lo más simple posible, aquí se usa una gran cantidad de funciones de ventana, por lo que se adopta la sintaxis de la base de datos ORACLE que admite funciones de ventana. Generalmente es más complicado escribir estos SQL usando la sintaxis de otros bases de datos
Estos problemas en sí mismos no deben considerarse muy complicados y, a menudo, aparecen en el análisis de datos diario, pero ya son difíciles para SQL.

trastorno de la colección

Los cálculos ordenados son muy comunes en los cálculos de datos por lotes (ocupan los 3/3 primeros lugares, se comparan con la edición anterior, etc.), pero SQL continúa usando el concepto de conjuntos desordenados en matemáticas, los cálculos ordenados no se pueden realizar directamente y pueden solo se puede ajustar cambiando el método de ideas.

 Tarea 1    Empleados en el grupo de mediana edad en la empresa

 
 
select name, birthdayfrom (select name, birthday, row_number() over (order by birthday) ranking      from employee )where ranking=(select floor((count(*)+1)/2) from employee)

La mediana es un cálculo común.Originalmente, es muy simple quitar el miembro del medio en el conjunto ordenado. Sin embargo, el mecanismo de recopilación desordenada de SQL no proporciona un mecanismo para acceder directamente a los miembros por ubicación. Es necesario crear artificialmente un campo de número de secuencia y luego usar el método de consulta condicional para seleccionarlo, lo que resulta en el uso de subconsultas para completar.

 Tarea 2    ¿Cuántos días de negociación es el aumento continuo más largo de una determinada acción?

select max (consecutive_day)from (select count(*) (consecutive_day      from (select sum(rise_mark) over(order by trade_date) days_no_gain            from (select trade_date,                         case when                              closing_price>lag(closing_price) over(order by trade_date)                         then 0 else 1 END rise_mark                from stock_price) )     group by days_no_gain)

Las colecciones desordenadas también pueden conducir a la distorsión de las ideas.

La forma convencional de calcular el número de días de subida consecutivos: establezca una variable temporal con un valor inicial de 0 para registrar la fecha de subida consecutiva, y luego compárela con el día anterior, si no ha subido, se borrará a 0 , y si ha subido, sumar 1. Al final del ciclo, ver el valor aparece el valor máximo.

Este proceso no se puede describir cuando se usa SQL.Es necesario cambiar la forma de pensar y calcular el número acumulado de días no crecientes desde la fecha inicial hasta el día actual.Encuentre su recuento máximo. No es fácil leer esta oración de SQL, pero es aún más difícil escribirla.

La colección no está completa.

No hay duda de que las colecciones son la base del cálculo de datos por lotes. Aunque SQL tiene el concepto de conjuntos, se limita a describir conjuntos de resultados simples y no utiliza conjuntos como un tipo de datos básico para expandir su rango de aplicación.

 Tarea 3    Empleados con el mismo cumpleaños que otros en la empresa

select * from employeewhere to_char (birthday, ‘MMDD’) in    ( select to_char(birthday, 'MMDD') from employee      group by to_char(birthday, 'MMDD')      having count(*)>1 )

La intención original de agrupar es dividir la colección de origen en varias subcolecciones, y el valor devuelto también debe ser estos subconjuntos. Pero SQL no puede representar este "conjunto de conjuntos", lo que obliga al siguiente paso de cálculos agregados para estos subconjuntos a formar conjuntos de resultados regulares.

Pero a veces lo que queremos no es el valor de resumen del subconjunto sino el subconjunto en sí. En este momento, es necesario volver a consultar usando las condiciones obtenidas al agrupar de la colección de origen, e inevitablemente aparecen subconsultas.

 Tarea 4    Encuentra los 10 mejores estudiantes en cada materia

select namefrom (select name      from (select name,                   rank() over(partition by subject order by score DESC) ranking            from score_table)      where ranking<=10)group by namehaving count(*)=(select count(distinct subject) from score_table)

Con la idea de la colección, ordene y filtre los subconjuntos después de la agrupación de materias para seleccionar los 10 principales de cada materia, y luego haga la intersección de estos subconjuntos para completar la tarea. Sin embargo, SQL no puede expresar el "conjunto de conjuntos”, y no existe una operación de intersección para conjuntos con un número indefinido de conjuntos. En este momento, es necesario cambiar la forma de pensar, usar funciones de ventana para encontrar los 10 primeros de cada tema, y ​​luego agrupar a los estudiantes para encontrar estudiantes cuyos tiempos de ocurrencia sean iguales al número de temas, causando dificultad en la comprensión.

falta de referencia de objeto

En SQL, la relación de referencia entre las tablas de datos se mantiene mediante la clave externa del mismo valor, y el registro al que apunta la clave externa no se puede usar directamente como el atributo de este registro. Al consultar, es necesario usar múltiples uniones de tabla o subconsultas para completar No sólo escribir engorroso e ineficiente.

 Tarea 5    Los empleados varones de la directora

unirse con varias tablas

select A.*from employee A, department B, employee Cwhere A.department=B.department and B.manager=C.name and      A.gender='male' and C.gender='female'

con subconsulta

select * from employeewhere gender='male' and department in    (select department from department     where manager in          (select name from employee where gender='female'))

Si el campo de departamento en la tabla de empleados apunta al registro en la tabla de departamentos, y el campo de gerente en la tabla de departamentos apunta al registro en la tabla de empleados, entonces la condición de consulta puede escribirse simplemente en esta forma intuitiva y eficiente:

where gender='male' and department.manager.gender='female'

Pero en SQL, solo puede usar uniones o subconsultas de varias tablas para escribir las dos declaraciones anteriores obviamente oscuras.

 Tarea 6    empresa del primer empleo del empleado

unirse con varias tablas

select name, company, first_companyfrom (select employee.name name, resume.company company,             row_number() over(partition by resume. name                               order by resume.start_date) work_seq      from employee, resume where employee.name = resume.name)where work_seq=1

con subconsulta

select name,    (select company from resume     where name=A.name and           start date=(select min(start_date) from resume                       where name=A.name)) first_companyfrom employee A

No existe un mecanismo de referencia de objetos ni un SQL totalmente agregado, ni las subtablas pueden tratarse como atributos (valores de campo) de la tabla principal. Las consultas de subtablas utilizan uniones de varias tablas para aumentar la complejidad de la instrucción y filtran o agrupan el conjunto de resultados en una correspondencia uno a uno con los registros de la tabla principal (los registros conectados corresponden a las subtablas uno a uno). -uno); Utilice una subconsulta para calcular temporalmente un subconjunto de registros de subtabla relacionados con los registros de la tabla principal cada vez, aumentando la cantidad de cálculo general (la cláusula with no se puede usar para subconsultas) y la complejidad de escritura.

Introducción de SPL

Ahora que el problema ha terminado, es hora de hablar sobre la solución.

De hecho, al analizar el problema, se especifica hasta cierto punto la solución, y se rediseña el lenguaje de cálculo para superar estas dificultades de SQL, y se soluciona el problema.

¡Por eso se inventó SPL!

SPL es un lenguaje de programación de código abierto, su nombre completo es lenguaje de proceso estructurado, que está a solo una palabra de SQL. El propósito es resolver mejor el funcionamiento de los datos estructurados. SPL enfatiza el orden, admite el mecanismo de referencia de objetos y, por lo tanto, logra una recopilación completa, lo que reducirá en gran medida la dificultad de la "traducción de soluciones" mencionada anteriormente.

El espacio aquí no es apropiado para introducir SPL en detalle, solo enumeramos el código SPL del ejemplo en la sección anterior para sentirlo:

 tarea 1   

A
1 =empleado.sort(cumpleaños)
2 =A1((A1.largo()+1)/2)

Para los SPL basados ​​en conjuntos ordenados, obtener valores por posición es una tarea sencilla.

 tarea 2   

A
1 =stock_price.sort(trade_date)
2 =0
3 =A1.max(A2=if(precio_de_cierre>precio_de_cierre[-1],A2+1,0))

SPL simplemente escribe códigos de cálculo de acuerdo con el proceso de pensamiento natural.

 tarea 3   

A
1 =empleado.grupo(mes(cumpleaños),día(cumpleaños))
2 =A1.select(~.len()>1).conj()

SPL puede guardar conjuntos de resultados agrupados y continuar procesando como colecciones regulares.

 tarea 4   

A
1 =score_table.group(asignatura)
2 =A1.(~.clasificación(puntuación).pselect@a(~<=10))
3 =A1.(~(A2(#)).(nombre)).isect()

Para usar SPL, solo necesita escribir el código de cálculo de acuerdo con el proceso de pensamiento.

 tarea 5   

A
1 =empleado.select(género=="masculino" && departamento.gerente.género=="femenino")

Una SPL que admita referencias a objetos puede simplemente acceder al campo del registro al que apunta la clave externa como propiedad propia.

 tarea 6   

A
1 =empleado.nuevo(nombre,currículum.minp(fecha_inicio).empresa:primera_empresa)

SPL admite colecciones de subtablas como campos de la tabla principal, al igual que para acceder a otros campos, no es necesario volver a calcular las subtablas.

SPL tiene un IDE intuitivo, que proporciona funciones de depuración convenientes y puede recorrer el código para reducir aún más la complejidad de la escritura de código.

Para los cálculos en la aplicación, SPL proporciona un controlador JDBC estándar que se puede integrar en aplicaciones Java como SQL:

Class.forName("com.esproc.jdbc.InternalDriver");Connection conn =DriverManager.getConnection("jdbc:esproc:local://");Statement st = connection.();CallableStatement st = conn.prepareCall("{call xxxx(?,?)}");st.setObject(1, 3000);st.setObject(2, 5000);ResultSet result=st.execute();...

 

Supongo que te gusta

Origin blog.csdn.net/2301_77463738/article/details/131142479
Recomendado
Clasificación