database - registros - triggers en postgresql
¿Para qué sirven las reglas de PostgreSQL? (4)
Pregunta
A menudo veo que se establece que las reglas deben evitarse y los factores desencadenantes utilizados en su lugar . Puedo ver el peligro en el sistema de reglas, pero ciertamente hay usos válidos para las reglas, ¿verdad? ¿Qué son?
Estoy pidiendo esto por interés general; No estoy muy experimentado con bases de datos.
Ejemplo de lo que podría ser un uso válido
Por ejemplo, en el pasado necesité bloquear ciertos datos, así que hice algo como esto:
CREATE OR REPLACE RULE protect_data AS
ON UPDATE TO exampletable -- another similar rule for DELETE
WHERE OLD.type = ''protected''
DO INSTEAD NOTHING;
Entonces, si quiero editar los datos protegidos:
START TRANSACTION;
ALTER TABLE exampletable DISABLE RULE protect_data;
-- edit data as I like
ALTER TABLE exampletable ENABLE RULE protect_data;
COMMIT;
Estoy de acuerdo en que esto es chiflado, pero no pude cambiar la (s) aplicación (es) accediendo a la base de datos en este caso (o incluso arrojar errores). Así que los puntos de bonificación para encontrar una razón por la cual este es un uso peligroso / inválido del sistema de reglas , pero no por qué esto es un mal diseño .
¿Qué tal esto ?: Tienes una tabla que debe cambiarse a una vista. Para admitir aplicaciones heredadas que se insertan en dicha tabla, se crea una regla que asigna "insertos" a la nueva vista a la (s) tabla (s) subyacente (s).
Aquí se muestran algunos problemas con las reglas: http://www.depesz.com/index.php/2010/06/15/to-rule-or-not-to-rule-that-is-the-question/ (para Por ejemplo, si se incluye un elemento aleatorio () en una consulta, podría ejecutarse dos veces y devolver valores diferentes.
El mayor inconveniente de las reglas es que la gente no las entiende .
Por ejemplo, uno podría pensar que tener la regla:
CREATE OR REPLACE RULE protect_data AS
ON UPDATE TO exampletable -- another similar rule for DELETE
WHERE OLD.type = ''protected''
DO INSTEAD NOTHING;
Significará que si voy a emitir:
update exampletable set whatever = whatever + 1 where type = ''protected''
No se ejecutará ninguna consulta. Lo cual no es verdad La consulta se ejecutará, pero se ejecutará en versión modificada, con una condición adicional.
Además, las reglas rompen algo muy útil, es la cláusula de retorno:
$ update exampletable set whatever = whatever + 1 where type = ''normal'' returning *;
ERROR: cannot perform UPDATE RETURNING on relation "exampletable"
HINT: You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause.
Para envolverlo, si realmente, de verdad, tiene que usar vistas escribibles, y está utilizando el 9.1 PostgreSQL anterior, es posible que tenga un motivo válido para usar las reglas.
En todos los demás casos, lo más probable es que te dispares en un pie, incluso si no lo ves de inmediato.
He tenido algunas experiencias amargas con las reglas cuando se trata de funciones volátiles (si la memoria sirve, la publicación de blog de depesz destaca algunas de ellas).
También he roto la integridad referencial cuando los uso debido al momento en que se disparan los desencadenadores fkey:
CREATE OR REPLACE RULE protected_example AS
ON DELETE TO example
WHERE OLD.protected
DO INSTEAD NOTHING;
... luego agregue otra tabla, y haga referencia de ejemplo a esa tabla con una clave externa de eliminación de cascada. Luego, elimina * de esa mesa ... y retrocede horrorizado.
Informé del problema anterior como un error, que fue descartado como una característica / caso de borde necesario. Solo unos meses después comprendí por qué podría ser así, es decir, el desencadenador fkey hace su trabajo, y la regla luego se activa y funciona sola, pero el disparador f no verifica que su trabajo se haya realizado correctamente por razones de rendimiento. .
El caso de uso práctico donde sigo usando reglas es cuando un desencadenante BEFORE
pre manipular datos (el estándar SQL dice que no está permitido, pero Postgres lo complacerá) puede resultar en manipular previamente las filas afectadas y así cambiar su ctid ( es decir, se actualiza dos veces o no se elimina porque una actualización invalida la eliminación).
Esto da como resultado que Postgres devuelva un número incorrecto de filas afectadas, lo cual no es gran cosa hasta que supervise ese número antes de emitir declaraciones posteriores.
En este caso, he descubierto que el uso de una o dos reglas estratégicamente ubicadas puede permitir la ejecución preventiva de las declaraciones ofensivas, lo que hace que Postgres devuelva la cantidad correcta de filas afectadas.
Uno de los casos de uso para REGLAS son vistas actualizables (aunque eso cambia en 9.1 ya que esa versión introduce activadores INSTEAD OF para vistas)
Otra buena explicación se puede encontrar en el manual:
Para las cosas que ambos pueden implementar, lo mejor depende del uso de la base de datos. Se dispara un disparador para cualquier fila afectada una vez. Una regla manipula la consulta o genera una consulta adicional. Por lo tanto, si se afectan muchas filas en una declaración, una regla que emite un comando extra es más rápida que la activación de cada fila y debe ejecutar sus operaciones muchas veces. Sin embargo, el enfoque desencadenante es conceptualmente mucho más simple que el enfoque de la regla, y es más fácil para los principiantes acertar.
(Tomado de: http://www.postgresql.org/docs/current/static/rules-triggers.html )