enmascarar - mascaras en sql
¿La base de datos desencadena el mal? (21)
Creo que los factores desencadenantes no solo no son malos, sino que también son necesarios para un buen diseño de la base de datos. Los programadores de aplicaciones piensan que las bases de datos solo se ven afectadas por su aplicación. A menudo están equivocados. Si se quiere mantener la integridad de los datos, no importa de dónde provenga el cambio de datos, los desencadenadores son un requisito y es una tontería evitarlos porque algunos programadores son demasiado etnocéntricos para considerar que algo distinto a su preciada aplicación puede estar afectando las cosas. No es difícil diseñar o probar o solucionar un desencadenante si usted es un desarrollador de bases de datos competente. Tampoco es difícil determinar si un disparador está causando un resultado inesperado si se te ocurre (como a mí) mirar allí. Si recibo un error al decir que una tabla a la que no me estoy refiriendo en mi sp tiene un error FK, sé sin siquiera pensarlo que ese desencadenante está causando el problema y también cualquier desarrollador de base de datos competente. Poner reglas comerciales solo en la aplicación es la causa número uno que he encontrado de datos incorrectos, ya que otros no tienen idea de que la regla existe y la violan en sus procesos. Las reglas centradas en datos pertenecen a la base de datos y los desencadenadores son clave para aplicar los más complejos.
¿La base de datos desencadena una mala idea?
En mi experiencia, son malvados, porque pueden dar lugar a efectos secundarios sorprendentes y son difíciles de depurar (especialmente cuando un disparador dispara a otro). A menudo, los desarrolladores ni siquiera piensan en buscar si hay un desencadenante.
Por otro lado, parece que si tienes una lógica que debe ocurrir en el tiempo que se crea un nuevo FOO
en la base de datos, entonces el lugar más infalible para ponerlo es un disparador de inserción en la tabla FOO.
La única vez que usamos desencadenadores es para cosas realmente simples como configurar el ModifiedDate
.
Creo que pueden ser malvados, pero tan malvados como cualquier otra cosa en desarrollo.
Aunque realmente no tengo mucha experiencia con ellos, los tuve en un proyecto reciente en el que trabajé y que me ha llevado a esta conclusión. El problema que tengo con ellos es que pueden hacer que la lógica empresarial termine en dos ubicaciones, una biblioteca de códigos y una base de datos.
Lo veo como un argumento similar con el uso de sprocs. Con frecuencia, los desarrolladores que son realmente buenos en SQL escriben lógica comercial en la base de datos, mientras que las personas que no lo hacen tienen su lógica de negocios en otra parte.
Así que mi regla de oro es ver cuál es la estructura de su proyecto. Si parece viable tener la lógica de negocios almacenada en la base de datos, entonces podría ser útil tener activadores.
De hecho, muy a menudo los desencadenantes están siendo mal utilizados. De hecho, en la mayoría de los casos ni siquiera los necesitas. Pero eso no los hace necesariamente malos.
Un escenario que me viene a la mente cuando los disparadores son útiles es cuando tienes una aplicación heredada para la cual no tienes el código fuente y no hay forma de cambiarlo.
Decir que son malvados es una exageración, pero pueden ser de malla. Cuando el disparo de un gatillo dispara otros disparadores, se vuelve realmente complicado. Digamos que son problemáticos: http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html
Hacer lógica de negocios en Oracle con desencadenadores es más difícil de lo que parece debido a problemas de concurrencia múltiple. No verá cambios en otra sesión hasta que las otras sesiones se comprometan.
Definitivamente no son malvados. Encontré factores desencadenantes valiosos durante la refactorización de esquemas de bases de datos, al cambiar el nombre de una columna, o al dividir una columna en dos columnas o viceversa (ejemplo: nombre / mayúsculas y minúsculas) y ayudar a la transición.
También son muy útiles para auditar.
En un nivel alto, hay dos casos de uso para desencadenantes1
1) Para hacer que cosas "automágicamente" sucedan. En este caso, los desencadenantes causan un efecto secundario, cambian los datos de maneras que no se esperaban debido a que el operador (primitivo) insertó, actualizó o eliminó lo que se ejecutó y provocó que se disparara el disparador.
El consenso general aquí es que los desencadenantes son realmente dañinos. Porque cambian la semántica conocida de una instrucción INSERT, UPDATE o DELETE. Cambiar la semántica de estos tres operadores primitivos de SQL morderá a otros desarrolladores que más adelante en el futuro necesitarán trabajar en las tablas de su base de datos que ya no se comportan de la manera esperada cuando se les opera con las primitivas de SQL.
2) Para hacer cumplir las reglas de integridad de datos, que no sean las que podemos tratar de forma declarativa (usando CHECK, PRIMARY KEY, UNIQUE KEY y FOREIGN KEY). En este caso de uso, todos los desencadenantes son datos de CONSULTA (SELECCIONAR) para verificar si el cambio realizado por INSERT / UPDATE / DELETE está permitido o no. Al igual que las restricciones declarativas hacen por nosotros. Solo en este caso nosotros (los desarrolladores) hemos programado la aplicación.
El uso de disparadores para este último caso de uso no es dañino.
Estoy blogueando sobre eso en: http://harmfultriggers.blogspot.com
Esta respuesta se aplica específicamente a SQL Server. (Aunque también se puede aplicar a otros RDBMS, no tengo idea. Hubiera preferido dar como respuesta here pero eso fue cerrado como un engaño de esto.)
Un aspecto no mencionado en ninguna de las respuestas hasta ahora es la seguridad. Debido a que, de forma predeterminada, los desencadenantes se ejecutan en el contexto del usuario que ejecuta la instrucción que hace que el desencadenador se dispare, esto puede causar una amenaza de seguridad a menos que se revisen todos los desencadenantes.
El ejemplo dado en BOL en el encabezado " Gestionar la seguridad del desencadenador" es de un usuario que crea un disparador que contiene el código GRANT CONTROL SERVER TO JohnDoe ;
para escalar sus propios permisos.
Estoy de acuerdo. Los problemas con los desencadenantes son personas, no desencadenantes. Aunque es más a tener en cuenta, más a considerar y aumenta la responsabilidad de los programadores que verifican las cosas correctamente, no descartamos los índices para simplificar nuestras vidas. (Los índices incorrectos pueden ser tan malos como los desencadenantes malos)
La importancia de los factores desencadenantes (en mi mente) es que ...
- Cualquier sistema siempre debe estar en un estado válido
- El código para hacer cumplir este estado válido debe estar centralizado (no escrito en cada SP)
Desde el punto de vista del mantenimiento, un disparador es muy útil para los codificadores competentes y los problemas para los más jóvenes / aficionados. Sin embargo, estas personas necesitan aprender y crecer de alguna manera.
Supongo que se trata de tu entorno de trabajo. ¿Tiene personas confiables que aprenden bien y se puede confiar en que sean metódicas? Si no, aparentemente tienes dos opciones:
- Acepte que tendrá que perder la funcionalidad para compensar
- Acepte que necesita personas diferentes o una mejor capacitación y gestión
Suenan duros, y supongo que lo son. Pero es la verdad básica, en mi mente ...
La idea de los factores desencadenantes no es mala, limitar el anidamiento de los factores desencadenantes es malo.
Las herramientas nunca son malvadas. Las aplicaciones de esas herramientas pueden ser malas.
Los desencadenadores parecen funcionar bien para el registro de auditoría.
Los desencadenantes son extremadamente potentes y útiles, existen varios escenarios en los que un desencadenador es la mejor solución para un problema.
También son una muy buena herramienta de "pirateo". A menudo hay situaciones en las que no tiene el control inmediato tanto del código como de la base de datos. Si tiene que esperar 2 meses para la próxima versión principal de su código, puede aplicar un parche a su base de datos inmediatamente luego puede colocar un activador en una tabla para realizar alguna funcionalidad adicional. Luego, cuando la liberación del código sea posible, puede reemplazar este desencadenador con su versión codificada de la misma funcionalidad si así lo desea.
Al final del día, todo es "malo" si no sabes lo que está haciendo. Decidir que los desencadenantes se deben a que hay desarrolladores que no los entienden es lo mismo que argumentar que los autos son malvados porque algunas personas no pueden conducir ...
Los desencadenantes tienen sus usos: el registro / auditoría y el mantenimiento de una fecha de "última modificación" son dos usos muy buenos que se han mencionado en respuestas anteriores.
Sin embargo, uno de los principios básicos del buen diseño es que las reglas de negocios / lógica de negocios / como quiera llamarlo deben concentrarse en un solo lugar. Poner parte de la lógica en la base de datos (a través de activadores o procesos almacenados) y algo en la aplicación viola ese principio. Duplicar la lógica en ambos lugares es aún peor, ya que invariablemente no se sincronizarán entre sí.
También está el tema del "principio de menor sorpresa" que ya se ha mencionado.
Los disparadores son una buena herramienta cuando se usan correctamente. Especialmente para cosas como auditoría de cambios, llenado de tablas de resumen, etc.
Ahora pueden ser "malvados" si terminas en un "infierno desencadenante" con un gatillo que desencadena otros desencadenantes. Una vez trabajé en un producto COTS donde tenían lo que llamaron "desencadenadores de flexión". Estos desencadenantes se almacenaron en una tabla, ya que las picaduras de sql dinámicas se compilaron cada vez que se ejecutaron. Los desencadenadores compilados verían y verían si esa tabla tiene algún desencadenador flexible para ejecutar y luego compilar y ejecutar el desencadenador "flexible". En teoría, esto sonaba como una idea genial porque el producto se personalizaba fácilmente, pero la realidad era que la base de datos prácticamente explotó debido a todas las compilaciones que tenía que hacer ...
Así que sí, son geniales si mantienes lo que estás haciendo en perspectiva. Si es algo muy simple como auditoría, resumen, secuenciación automática, etc., no hay problema. Solo tenga en cuenta la tasa de crecimiento de la tabla y cómo el desencadenador afectará el rendimiento.
Los principales problemas con los factores desencadenantes son a) son completamente globales: se aplican independientemente del contexto de la actividad de la tabla; yb) son sigilosos; es fácil olvidar que están ahí hasta que te lastimen con consecuencias involuntarias (y muy misteriosas).
Lo que significa que deben usarse con cuidado para las circunstancias apropiadas; que en mi experiencia se limita a cuestiones de integridad relacional (a veces con una granularidad más fina de la que se puede obtener declarativamente); y generalmente no para fines comerciales o transaccionales. YMMV.
Mayormente sí.
La dificultad con un disparador es que hace cosas "detrás de tu espalda"; el desarrollador que mantiene la aplicación fácilmente podría no darse cuenta de que está allí y hacer cambios que arruinen las cosas sin siquiera darse cuenta.
Crea una capa de complejidad que simplemente agrega trabajo de mantenimiento.
En lugar de usar un activador, un procedimiento / rutina almacenada, generalmente se puede hacer lo mismo, pero de una manera clara y sostenible: llamar a una rutina almacenada significa que el desarrollador puede ver su código fuente y ver exactamente qué está sucediendo.
Nah, no son malvados, simplemente no se entienden bien :-D
Los desencadenantes tienen un uso válido, pero con demasiada frecuencia como un retro-hack que en última instancia empeora las cosas.
Si está desarrollando un DB como parte de una aplicación, la lógica siempre debe estar en el código o sprocs haciendo la llamada. Los desencadenantes solo llevarán al dolor de depuración más adelante.
Si comprende cómo el bloqueo, el bloqueo y la forma en que los DB acceden a los archivos en el disco, utilizar desencadenantes de la manera correcta (por ejemplo, auditar o archivar el acceso directo a BD) puede ser realmente valioso.
No malvado En realidad, simplifican cosas como
1. Registro / auditoría de cambios en registros o incluso esquemas de bases de datos
Podría tener un disparador en ALTER TABLE que revierte los cambios en su entorno de producción. Esto debería evitar cualquier modificación accidental de la tabla.
2. Imposición de introgidad referencial (relaciones de clave primaria / extranjera, etc.) en múltiples bases de datos
No, en realidad son una buena idea. Si hay un problema con tus disparadores específicos, entonces no los estás haciendo bien, pero eso generalmente significa que hay un problema con tu implementación, no el concepto de desencadenantes :-).
Usamos los desencadenantes mucho porque pone la actividad específica de DBMS bajo el control de la base de datos a la que pertenece. Los usuarios de un DBMS no deberían tener que preocuparse por ese tipo de cosas. La integridad de los datos recae en la base de datos en sí, no en las aplicaciones o usuarios que la usan. Sin restricciones y factores desencadenantes y otras características en la base de datos, las aplicaciones tienen que aplicar las reglas y solo se necesita una aplicación / usuario deshonesto o defectuoso para destruir los datos.
Por ejemplo, sin desencadenantes, cosas tan maravillosas como las columnas autogeneradas no existirían y tendría que procesar una función en cada fila al seleccionarlas. Es probable que anule el rendimiento del DBMS, mucho mejor para crear la columna generada automáticamente en el momento de la inserción / actualización ya que es la única vez que cambia.
Además, la falta de factores desencadenantes impediría que las reglas de datos se apliquen en el DBMS, como los preactivadores para garantizar que las columnas tengan un formato específico. Tenga en cuenta que esto es diferente de las reglas de integridad de datos que generalmente son solo búsquedas de claves externas.
Sé que los desarrolladores que piensan que los factores desencadenantes deben usarse siempre que sea la forma más directa de lograr la funcionalidad que desean, y los desarrolladores que nunca lo harán. Es casi como un dogma entre los dos campos.
Sin embargo, personalmente estoy completamente de acuerdo con MarkR: puede (casi) escribir siempre código funcionalmente equivalente al desencadenante que será más persistente y, por lo tanto, más fácil de mantener.
Si hay efectos secundarios, es un problema de diseño. En algunos sistemas de bases de datos, no hay otra posibilidad de establecer un campo de autoincremento, es decir, para un campo de ID de clave principal.