Pregunta

Recientemente comencé a trabajar en una empresa con una enorme "empresa". solicitud. En mi último trabajo, diseñé la base de datos, pero aquí tenemos un departamento completo de Arquitectura de Base de Datos del que no formo parte.

Una de las cosas más extrañas en su base de datos es que tienen un montón de vistas que, en lugar de que el usuario proporcione los rangos de fechas que desean ver, se unen con una tabla (temporal global) "TMP_PARM_RANG" con una fecha de inicio y finalización. Cada vez que la aplicación principal comienza a procesar una solicitud, lo primero que hace es " DELETE FROM TMP_PARM_RANG ; " luego una inserción en él.

Esto parece una forma extraña de hacer las cosas, y no es muy seguro, pero todos los demás aquí parecen estar de acuerdo. ¿Es esto normal o es válida mi inquietud?

Actualización Debo mencionar que usan transacciones y bloqueos por cliente, por lo que está protegido contra la mayoría de los problemas de concurrencia. Además, hay literalmente docenas, si no cientos de vistas, que dependen de TMP_PARM_RANG .

¿Fue útil?

Solución

¿Entiendo esto correctamente?

Hay una vista como esta:

SELECT * FROM some_table, tmp_parm_rang
  WHERE some_table.date_column BETWEEN tmp_parm_rang.start_date AND tmp_parm_rang.end_date;

Luego, en alguna interfaz, un usuario ingresa un rango de fechas y la aplicación hace lo siguiente:

  1. Elimina todas las filas existentes de TMP_PARM_RANG
  2. Inserta una nueva fila en     TMP_PARM_RANG con los valores del usuario
  3. Selecciona todas las filas de la vista

Me pregunto si los cambios en TMP_PARM_RANG se han confirmado o revertido, y si es así, ¿cuándo? ¿Es una mesa temporal o una mesa normal? Básicamente, dependiendo de las respuestas a estas preguntas, el proceso puede no ser seguro para que varios usuarios lo ejecuten en paralelo. Uno espera que si este fuera el caso ya lo hubieran descubierto y abordado, pero ¿quién sabe?

Incluso si se hace de una manera segura para subprocesos, hacer cambios en la base de datos para operaciones de consulta simples no tiene mucho sentido. Estos DELETE e INSERTs están generando redo / undo (o lo que sea equivalente en una base de datos que no sea de Oracle) lo cual es completamente innecesario.

Una forma simple y más normal de lograr el mismo objetivo sería ejecutar esta consulta, vinculando las entradas del usuario a los parámetros de la consulta:

SELECT * FROM some_table WHERE some_table.date_column BETWEEN ? AND ?;

Otros consejos

Si la base de datos es Oracle, posiblemente sea una tabla temporal global; cada sesión ve su propia versión de la tabla y las inserciones / eliminaciones no afectarán a otros usuarios.

Debe haber alguna razón comercial para esta tabla. He visto vistas con fechas codificadas que en realidad eran vistas particionadas y estaban usando fechas como el campo de partición. También he visto unirme en una mesa como cuando se trata de los horarios de verano. Imagine una vista que devuelva toda la actividad que ocurrió durante el horario de verano. Y ninguna de estas cosas se eliminaría e insertaría en la tabla ... eso es extraño

Entonces, o hay una razón más profunda para esto que necesita ser desenterrada, o simplemente es algo que en ese momento parecía una buena idea, pero por qué se hizo de esa manera se perdió como conocimiento tribal.

Personalmente, supongo que sería una ocurrencia bastante extraña. Y por lo que está diciendo, dos métodos que llaman al proceso al mismo tiempo podrían ser muy interesantes.

Normalmente, los rangos de fechas se realizan como filtros en una vista y no se controlan con valores externos almacenados en otras tablas.

La única justificación que pude ver para esto es si hubo un proceso de varios pasos, que solo se ejecutó una vez a la vez y las fechas son necesarias para múltiples operaciones, a través de múltiples procedimientos almacenados.

Supongo que les permitiría admitir múltiples rangos. Por ejemplo, pueden devolver todas las fechas entre el 1/1/2008 y el 1/1/2009 Y el 1/1/2006 y el 1/1/2007 para comparar los datos de 2006 con los de 2008. No podría hacer eso con un solo par de parámetros enlazados. Además, no sé cómo hace Oracle su almacenamiento en caché del plan de consulta para las vistas, pero ¿tal vez tenga algo que ver con eso? Con las columnas de fecha siendo verificadas como parte de la vista, el servidor podría almacenar en caché un plan que siempre asume que las fechas serán verificadas.

Simplemente lanzando algunas conjeturas aquí :)

Además, escribiste:

  

Debo mencionar que usan   transacciones y bloqueos por cliente, entonces   está protegido contra la mayoría de la concurrencia   problemas.

Si bien eso puede proteger contra problemas de consistencia de datos debido a la concurrencia, duele cuando se trata de problemas de rendimiento debido a la concurrencia.

¿También agregan uno -en la aplicación- para generar el siguiente valor único para la clave primaria?

Parece que el concepto de estado compartido elude a estas personas, o la razón del estado compartido nos elude.

Eso me parece un algoritmo bastante extraño. Me pregunto cómo maneja la concurrencia: ¿está envuelto en una transacción?

Me parece que alguien no estaba seguro de cómo escribir su cláusula WHERE.

Las vistas probablemente se usan como tablas temporales. En SQL Server podemos usar una variable de tabla o una tabla temporal (# / ##) para este propósito. Aunque los expertos no recomiendan la creación de vistas, he creado muchas de ellas para mis proyectos de SSRS porque las tablas en las que estoy trabajando no se refieren entre sí (¡NO FK, en serio!). Tengo que solucionar las deficiencias en el diseño de la base de datos; Es por eso que estoy usando mucho las vistas.

Con el enfoque global de tabla temporal GTT que comentas aquí, el método es seguro con respecto a un sistema multiusuario, así que no hay problema. Si se trata de Oracle, me gustaría verificar que el sistema esté utilizando un nivel adecuado de muestreo dinámico para que el GTT se una de manera adecuada o que se realice una llamada a DBMS_STATS para proporcionar estadísticas sobre el GTT.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top