2008-08-18 25 views
17

En el pasado, nunca me ha gustado el uso de desencadenantes en las tablas de la base de datos. Para mí siempre representaron algo de "magia" que iba a suceder en el lado de la base de datos, muy lejos del control de mi código de aplicación. También quería limitar la cantidad de trabajo que el DB tenía que hacer, ya que generalmente es un recurso compartido y siempre asumí que los disparadores podrían llegar a ser costosos en escenarios de carga alta.Disparadores de bases de datos

Dicho esto, he encontrado un par de casos en los que los desencadenantes tienen sentido usarlos (al menos en mi opinión tienen sentido). Recientemente, sin embargo, me encontré en una situación en la que a veces podría necesitar "puentear" el gatillo. Me sentí realmente culpable por tener que buscar la forma de hacerlo, y todavía creo que un mejor diseño de la base de datos aliviará la necesidad de evitarlo. Desafortunadamente, este DB es utilizado por múltiples aplicaciones, algunas de las cuales son mantenidas por un equipo de desarrollo muy poco cooperativo que gritaba sobre los cambios de esquema, por lo que estaba atascado.

¿Cuál es el consenso general sobre desencadenantes? Amor em? ¿Los odio? ¿Crees que sirven un propósito en algunos escenarios? ¿Piensas que tener una necesidad de puentear un gatillo significa que estás "haciéndolo mal"?

Respuesta

12

Los disparadores generalmente se usan incorrectamente, introducen errores y por lo tanto deben evitarse. Nunca diseñe un disparador para hacer una comprobación de restricción de integridad que cruce filas en una tabla (por ejemplo, "el salario promedio por departamento no puede exceder X).

Tom Kyte, VP de Oracle ha indicado que preferiría remove triggers as a feature of the Oracle base de datos debido a su frecuencia papel en los insectos. él sabe que es sólo un sueño, y disparadores están aquí para quedarse, pero si pudiera, eliminaría los factores desencadenantes de Oracle, él (junto con el CUANDO OTROS cláusula y transacciones autónomas).

¿Se pueden utilizar los disparadores correctamente? De manera absoluta.

El problema es que no se usan correctamente en modo muchos casos que estoy dispuesto a dar hasta cualquier beneficio percibido solo para obtener deshacerse de los abusos (y errores) causados ​​por ellos. - Tom Kyte

2

Trabajo con aplicaciones web y winforms en C# y I HATE dispara con pasión. Nunca me he encontrado con una situación en la que pudiera justificar el uso de un desencadenante para mover esa lógica a la capa empresarial de la aplicación y replicar allí la lógica de activación.

No hago ningún tipo de trabajo de tipo DTS ni nada de eso, por lo que podría haber algunos casos de uso para usar el disparador allí, pero si alguien en alguno de mis equipos dice que podrían querer usar un disparador, es mejor que lo hagan preparó bien sus argumentos porque me niego a esperar y permitir que los desencadenantes se agreguen a cualquier base de datos en la que estoy trabajando.

Algunas razones por las que no me gustan los desencadenantes:

  • Se mueven lógica en la base de datos. Una vez que comienzas a hacer eso, estás pidiendo un mundo de dolor porque pierdes tu depuración, tu seguridad en tiempo de compilación, tu flujo lógico. Es todo cuesta abajo.
  • La lógica que implementan no es fácilmente visible para nadie.
  • No todos los motores de bases de apoyo disparadores para que su solución crea dependencias en los motores de bases de datos

Estoy seguro de que podría pensar en más razones de la parte superior de mi cabeza, pero los solos son suficientes para mí a no utilizar disparadores .

+0

Uso los disparadores en los condicionales de inserción/actualización/eliminación para aumentar/disminuir los contadores en una tabla. En este momento esta es la única vez que lo uso. Son esos desencadenadores bien? –

0

No soy fan, personalmente. Los usaré, pero solo cuando descubra un cuello de botella en el código que se puede borrar moviendo acciones a un disparador. En general, prefiero la simplicidad y una forma de mantener las cosas simples es mantener la lógica en un solo lugar: la aplicación. También trabajé en trabajos donde el acceso es muy compartimentado. En esos entornos, cuanto más código agregue, más personas tendré que contratar, incluso para las soluciones más simples.

1

Me encuentro pasando por alto los factores desencadenantes al realizar importaciones masivas de datos. Creo que está justificado en tales circunstancias.

Si termina pasando por alto los factores desencadenantes muy a menudo, es probable que necesite echar un vistazo a lo que los puso allí en primer lugar.

En general, votaría por "sirven para un propósito en algunos escenarios". Siempre estoy nervioso por las implicaciones de rendimiento.

2

Los disparadores pueden ser muy útiles. También pueden ser muy peligrosos. Creo que están bien para las tareas de limpieza de la casa como rellenar datos de auditoría (creados por, fecha de modificación, etc.) y en algunas bases de datos se pueden utilizar para la integridad referencial.

Pero no soy un gran admirador de poner mucha lógica de negocios en ellos. Esto puede hacer que el apoyo problemático porque:

  • es una capa adicional de código para investigar
  • a veces, como el PO aprendió, cuando se necesita para hacer un conjunto de datos fijar el gatillo podría estar haciendo cosas con la suposición de que la cambio de datos es siempre a través de una directiva de aplicación y no de un desarrollador o DBA solucionar un problema, o incluso de una aplicación diferente

En cuanto a tener que pasar por alto un disparador para hacer algo, podría significar que estás haciendo algo mal , o podría significar que el activador está haciendo algo mal.

La regla general que me gusta usar con los desencadenantes es mantenerlos livianos, rápidos, simples y lo más no invasivos posible.

+0

+1 para rellenar datos de auditoría de forma no invasiva. – zacharydl

0

Primero usé desencadenantes hace un par de semanas. Cambiamos a través de un servidor de producción de SQL 2000 a SQL 2005 y encontramos que los controladores se comportaban de manera diferente con los campos NText (que almacenaban un documento XML grande) y descartaban el último byte. Usé un disparador como una solución temporal para agregar un byte ficticio adicional (un espacio) al final de los datos, resolviendo nuestro problema hasta que se pudiera implementar una solución adecuada.

Aparte de este caso especial y temporal, diría que los evitaría, ya que ocultan lo que está pasando, y la función que proporcionan debe manejarse explícitamente por el desarrollador en lugar de como una magia oculta.

8

Piense en una base de datos como un gran objeto grande: después de cada llamada a ella, debe estar en un estado lógicamente consistente.

Las bases de datos se exponen a través de tablas, y mantener tablas y filas consistentes se puede hacer con activadores. Otra forma de mantenerlos constantes es no permitir el acceso directo a las tablas, y solo permitirlo a través de procedimientos almacenados y vistas.

La desventaja de los desencadenantes es que cualquier acción puede invocarlos; esto también es una fortaleza: nadie va a arruinar la integridad del sistema por incompetencia.

Como contrapunto, permitir el acceso a una base de datos solo a través de procedimientos almacenados y vistas aún permite el acceso de permisos de puerta trasera. Se confía en que los usuarios con permisos suficientes no rompan la integridad de la base de datos, todos los demás usan procedimientos almacenados.

En cuanto a la reducción de la cantidad de trabajo: las bases de datos son sorprendentemente eficientes cuando no tienen que lidiar con el mundo exterior; estarías realmente sorprendido de cuánto incluso el cambio de proceso perjudica el rendimiento. Esa es otra ventaja de los procedimientos almacenados: en lugar de una docena de llamadas a la base de datos (y todas las visitas de ida y vuelta asociadas), hay una.

Agrupar las cosas en un solo proceso almacenado está bien, pero ¿qué sucede cuando algo sale mal? Supongamos que tiene 5 pasos y el primer paso falla, ¿qué ocurre con los otros pasos? Necesita agregar un montón de lógica para atender esa situación. Una vez que empiezas a hacer eso, pierdes los beneficios del procedimiento almacenado en ese escenario.

La lógica de negocio tiene que ir a alguna parte, y hay un montón de reglas de dominio implícitas incorporados en el diseño de una base de datos - las relaciones, restricciones, etc., son un intento de codificar las normas comerciales diciendo, por ejemplo, un usuario solo puede tener una contraseña Dado que ha empezado a implementar las reglas de negocio en el servidor de la base de datos teniendo estas relaciones, etc., ¿dónde dibuja la línea? ¿Cuándo la base de datos renuncia a la responsabilidad de la integridad de los datos y comienza a confiar en las aplicaciones de las llamadas y en los usuarios de la base de datos para hacerlo bien? Los procedimientos almacenados con estas reglas integradas en ellos pueden llevar mucho poder político a las manos de los DBA. Se trata de cuántos niveles van a existir en su arquitectura de n niveles; si hay una capa de presentación, negocios y datos, ¿dónde se encuentra la separación entre el negocio y los datos? ¿Qué valor agregado agrega la capa empresarial? ¿Ejecutará la capa empresarial en el servidor de la base de datos como procedimientos almacenados?

Sí, creo que tener que eludir un disparador significa que "lo estás haciendo mal"; en este caso, un gatillo no es para ti.

enter image description here

0

Sinceramente, la única vez que utiliza disparadores para simular un índice único que se le permite tener NULL que no cuentan para la singularidad.

0

En cuanto a la reducción de la cantidad de trabajo: las bases de datos son sorprendentemente eficientes cuando no tienen que lidiar con el mundo exterior; estarías realmente sorprendido de cuánto incluso el cambio de proceso perjudica el rendimiento. Esa es otra ventaja de los procedimientos almacenados: en lugar de una docena de llamadas a la base de datos (y todas las visitas de ida y vuelta asociadas), hay una.

esto es un poco fuera de tema, pero también debe tener en cuenta que solo está viendo esto desde un potencial positivo.

Agrupar cosas en un único proceso almacenado está bien, pero ¿qué sucede cuando algo sale mal? Supongamos que tiene 5 pasos y el primer paso falla, ¿qué ocurre con los otros pasos? Necesita agregar un montón de lógica para atender esa situación. Una vez que empiezas a hacer eso, pierdes los beneficios del procedimiento almacenado en ese escenario.

0

fan total,

pero realmente tiene que usarlo con moderación cuando,

  • necesidad de mantener la coherencia (especialmente cuando las tablas de dimensiones se utilizan en un almacén y tenemos que relacionar los datos de la tabla de hechos con su propia dimensión. En algún momento, la fila correcta en la tabla de dimensiones puede ser muy costosa de computar, por lo que desea que la clave se escriba directamente en la tabla de hechos, una buena manera de mantener esa "relación" es con el disparador

  • La necesidad de registrar los cambios (en una tabla de auditoría, por ejemplo, es útil saber qué @@ usuario hizo el cambio y cuándo ocurrió)

Algunos RDBMS como SQL Server 2005 también le proporciona disparadores en CREAR/Sentencias ALTER/DROP (para que pueda saber quién creó qué tabla, cuándo, quitó qué columna, cuándo, etc.)

Honestamente, usando disparadores en esos 3 escenarios, no veo por qué necesitaría alguna vez "desactivarlos".

0

La regla general es: no utilizar disparadores. Como se mencionó anteriormente, agregan sobrecarga y complejidad que pueden evitarse fácilmente moviendo la lógica fuera de la capa DB.

Además, en MS SQL Server, los disparadores se disparan una vez por cada comando sql, y no por fila. Por ejemplo, la siguiente instrucción sql ejecutará el desencadenante solo una vez.

UPDATE tblUsers 
SET Age = 11 
WHERE State = 'NY' 

Mucha gente, incluido yo mismo, estaban bajo la impresión de que los disparadores se activan en cada fila, pero este no es el caso. Si tiene una instrucción sql como la anterior que puede cambiar los datos en más de una fila, puede incluir un cursor para actualizar todos los registros afectados por el desencadenador. Puedes ver cómo esto puede complicarse muy rápidamente.

+4

Nunca use un cursor en un desencadenador. Sí, necesita contabilizar inserciones, actualizaciones o eliminaciones de varias filas, pero debe hacerlo de forma predeterminada. Quité el cursor de un disparador donde trabajo y la inserción de 40,000 registros cambió de 45 minutos a alrededor de 30 segundos. – HLGEM

2

"Nunca diseñar un disparador para hacer la comprobación de restricción de integridad que cruza las filas en una tabla" - No puedo estar de acuerdo. La pregunta está etiquetada 'SQL Server' y las cláusulas CHECK constraints 'en SQL Server no pueden contener una subconsulta; peor aún, la implementación parece tener una suposición 'codificada' de que un CHECK involucrará solo una fila, por lo que usar una función no es confiable. Entonces, si necesito una restricción que legítimamente involucre más de una fila, y un buen ejemplo aquí es la clave primaria secuenciada en una tabla temporal clásica de "tiempo válido" en la que necesito evitar períodos superpuestos para la misma entidad: cómo puedo Lo hago sin un disparador? Recuerde que esta es una clave principal, algo para garantizar que tengo integridad de datos, por lo que su aplicación en cualquier lugar que no sea el DBMS está fuera de cuestión. Hasta que las restricciones CHECK obtengan subconsultas, no veo una alternativa al uso de desencadenantes para ciertos tipos de restricciones de integridad.

Cuestiones relacionadas