每当另一个表发生更改时更新MySQL表

时间:2018-04-27 16:01:27

标签: mysql triggers database-trigger mysql-5.7

我正在尝试减少应用程序用于构建仪表板的查询数量,因此我尝试将我需要的所有信息预先收集到一个表中。大多数仪表板都可以使用JSON在javascript中构建,这将减少服务器负载,从而导致大量的PHP foreach,从而导致查询过多。

考虑到这一点,我有一个查询将来自其他3个表的用户信息汇总在一起,将JSON组中的结果连接起来。我需要在任何3个表中的任何更改时更新JSON对象,但不确定"对"这样做的方法是。

我可以设置一个常规作业来执行UPDATE语句,其中日期比上次更新更新,但是会丢失新记录,如果我插入,则会错过更新。我可以删除并重建表,但整个查询运行大约需要16秒,所以这看起来不是正确答案。

这是我的初步查询:

SET group_concat_max_len = 100000;
SELECT family_id, REPLACE(REPLACE(REPLACE(CONCAT("[", GROUP_CONCAT(family), "]"), "\\", ""), '"[', '['), ']"', ']') as family_members
FROM (

SELECT family_id,
    JSON_OBJECT(
"customer_id",                      c.id, 
"family_id",                        c.family_id,
"first_name",                       first_name,
"last_name",                        last_name,
"balance_0_30",                     pa.balance_0_30,
"balance_31_60",                    pa.balance_31_60,
"balance_61_90",                    pa.balance_61_90,
"balance_over_90",                  pa.balance_over_90,
"account_balance",                  pa.account_balance,
"lifetime_value",                   pa.lifetime_value,
"orders",                           CONCAT("[", past_orders, "]")
) AS family

FROM
    customers AS c
LEFT JOIN accounting AS pa ON c.id = pa.customer_id
LEFT JOIN (
    SELECT patient_id, 
        GROUP_CONCAT(
            JSON_OBJECT(
            "id",                   id,
            "item",                 item,
            "price",                price,
            "date_ordered",         date_ordered
            )
        ) as past_orders 
    FROM orders
    WHERE date_ordered < NOW()
    GROUP BY customer_id
) AS r ON r.customer_id = c.id
where c.user_id = 1

) AS results
GROUP BY family_id

我简要介绍了触发器,但我希望的是:

create TRIGGER UPDATE_FROM_ORDERS
AFTER INSERT OR UPDATE
ON orders
(EXECUTE QUERY FROM ABOVE WHERE family_id = orders.family_id)

我希望为每个表创建类似的东西,但乍一看它看起来不像你可以运行复杂的查询,比如我们创建嵌套的JSON。

我错了吗?触发器是正确的方法,还是有更好的方法?

1 个答案:

答案 0 :(得分:0)

作为示范:

+ my-project/
    + src/
        - senario.java //import hoge.fuga.*
        + hoge/
            + fuga/
                - Foo.java //package hoge.fuga
                - Bar.java //package hoge.fuga
    + build/
        - senario.class
        + hoge/
            + fuga/
                - Foo.class
                - Bar.class

注意:

MySQL触发器是行级触发器;针对受触发语句影响的“每行”触发一个触发器。 MySQL不支持语句级触发器。

DELIMITER $$ CREATE TRIGGER orders_au ON orders AFTER UPDATE FOR EACH ROW BEGIN SET group_concat_max_len = 100000 ; UPDATE target_table t SET t.somecol = ( SELECT expr FROM ... WHERE somecol = NEW.family_id ORDER BY ... LIMIT 1 ) WHERE t.family_id = NEW.family_id ; END$$ DELIMITER ; 的引用是对刚刚更新的行的NEW.family_id列的值的引用,触发触发器的行。

MySQL触发器禁止触发器中的SQL语句修改family_id表中的任何行。但它可以修改其他表。

触发器体中的SQL语句可以是任意复杂的,只要它不是一个返回结果集的裸SELECT,或者是DML INSERT / UPDATE / DELETE语句。在MySQL触发器中不允许使用DDL语句(大多数情况下都是如此)。