随时更新 MySQL table 另一个 table 更改
Update MySQL table any time another table changes
我正在尝试减少我的应用程序用于构建仪表板的查询数量,因此我正在尝试将我需要的所有信息提前收集到一个 table 中。大多数仪表板可以使用 JSON 在 javascript 中构建,这将减少服务器负载,因为每个 PHP foreach 会导致过多的查询。
考虑到这一点,我有一个查询将来自其他 3 个 table 的用户信息汇总在一起,并按家庭将结果串联到 JSON 组中。每当 3 个 table 中的任何一个发生任何变化时,我都需要更新 JSON 对象,但不确定 "right " 的方法是什么。
我可以设置一个常规作业来执行 UPDATE 语句,其中日期比上次更新更新,但这会错过新记录,如果我插入它会错过更新。我可以删除并重新构建 table,但整个查询 运行 需要大约 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)
我希望为每个 table 创建类似的东西,但乍一看,您似乎无法 运行 复杂的查询,例如我们正在创建嵌套 JSON。
我错了吗?触发器是执行此操作的正确方法,还是有更好的方法?
作为演示:
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 ;
备注:
MySQL触发器是行级触发器;为受触发语句影响的 "for each row" 触发触发器。 MySQL 不支持语句级触发器。
对 NEW.family_id
的引用是对刚刚更新的行的 family_id
列值的引用,触发触发器的行。
MySQL 触发器禁止触发器中的 SQL 语句修改 orders
table 中的任何行。但是可以修改其他tables.
触发器主体中的 SQL 语句可以任意复杂,只要它不是返回结果集的裸 SELECT 或 DML INSERT/UPDATE/DELETE 语句即可。 MySQL 触发器中不允许使用 DDL 语句(如果不是全部的话,大部分)。
我正在尝试减少我的应用程序用于构建仪表板的查询数量,因此我正在尝试将我需要的所有信息提前收集到一个 table 中。大多数仪表板可以使用 JSON 在 javascript 中构建,这将减少服务器负载,因为每个 PHP foreach 会导致过多的查询。
考虑到这一点,我有一个查询将来自其他 3 个 table 的用户信息汇总在一起,并按家庭将结果串联到 JSON 组中。每当 3 个 table 中的任何一个发生任何变化时,我都需要更新 JSON 对象,但不确定 "right " 的方法是什么。
我可以设置一个常规作业来执行 UPDATE 语句,其中日期比上次更新更新,但这会错过新记录,如果我插入它会错过更新。我可以删除并重新构建 table,但整个查询 运行 需要大约 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)
我希望为每个 table 创建类似的东西,但乍一看,您似乎无法 运行 复杂的查询,例如我们正在创建嵌套 JSON。
我错了吗?触发器是执行此操作的正确方法,还是有更好的方法?
作为演示:
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 ;
备注:
MySQL触发器是行级触发器;为受触发语句影响的 "for each row" 触发触发器。 MySQL 不支持语句级触发器。
对 NEW.family_id
的引用是对刚刚更新的行的 family_id
列值的引用,触发触发器的行。
MySQL 触发器禁止触发器中的 SQL 语句修改 orders
table 中的任何行。但是可以修改其他tables.
SQL 语句可以任意复杂,只要它不是返回结果集的裸 SELECT 或 DML INSERT/UPDATE/DELETE 语句即可。 MySQL 触发器中不允许使用 DDL 语句(如果不是全部的话,大部分)。