【问题标题】:Is there a mysql "multitable" trigger - E.G. a trigger that fires only after ALL tables are done updating?是否有 mysql“多表”触发器 - 例如仅在所有表完成更新后触发的触发器?
【发布时间】:2014-06-24 08:46:18
【问题描述】:

几个表有一个触发器,它在更新/插入时生成该行的 json 对象表示。例如。 {"email": ..., "relations: N" } //<--an email.json column 并将其存储在 json 列中

relations 只是一个数字绑定(如果有一个词,请告诉我),它允许我将多个姓名、电子邮件、电话、家庭绑定到一个对象中 -

例如the touchRelation.json column

{ 
"emails": [ {"email": 1@a.com },{"email:  2@a.com"},{"email:  N@a.com"}],
"teles" : [ {"tele" : ... },{"tele : ...."},{"tele : ...."}],
"Names" : [ {"Name" : ... },{"Name : ...."},{"Name : ...."}],
"Homes" : [ {"Home" : ... },{"Home : ...."},{"Home : ...."}],
}

我遇到的问题是 1) 每次其他表中的一个获取数据 CRUD 时更新 touchRelations.json 会浪费且效率低下,尤其是在一次更新多个表时

2) 我可能无法依赖开发人员在每次查询后调用 update_Relations_json()。

是否有一种简单的方法可以判断一个或多个表是否已更新,并且仅在所有表的所有更新完成后重新生成关系.json?


一种可能的解决方案是创建一个“挂起的更新”表,将信息存储在队列中,并将队列表中的数据一一插入/更新到存储表中,然后调用更新函数,但我是确定这不是最佳选择。

另一种选择是在数据库中创建一个 JSON 解析器,该解析器读取完整的 json 关系(上面的大关系),更新表然后构建 json 对象,但这似乎是对数据库的不良使用。

【问题讨论】:

  • +1 for Good Question.I don't know solution for this, but just for an IDEA, if you know which table was last updated then, you can create trigger for that table only.跨度>
  • 可能使用事务进行此类更新,并在commit transaction 运行触发器?
  • 不知道是不是最好的,但我可能会创建一个包含所有表的名称和某种控件(是否已经更新)的表。
  • 这是使用存储过程的地方。创建最终调用您的代码的过程并删除直接更新表的权限 - 从而迫使开发人员始终调用该过程。
  • @Vesper:我认为 MySQL 不支持在提交时触发的触发器。

标签: mysql sql json


【解决方案1】:

不确定这是答案还是评论,但是...

MySQL 不支持事务触发器。这意味着您只能在表中的数据发生更改时触发触发器。在您的示例中,我猜测数据更改没有预定义的顺序或组合 - 在一种情况下,您可能正在创建一个全新的记录,其中包含电子邮件、地址、姓名和电话;在另一种情况下,您可能正在向现有记录添加新的电话号码。

拥有“每个表的触发器”是您无需求助于奇异解决方案(如mimicking a materialized view)即可实现您想要的唯一方法。

但是,由于您已经存储了 3 次数据(一次在“普通”列中,一次在表 JSON 中,一次在关系 JSON 中),效率真的那么重要吗?你知道这是个问题吗?

我更担心的是,原则上我不喜欢触发器——它们很难测试,更难调试,而且在不断发展的数据库中也更难维护。 作用于当前行之外的数据或表的触发器让我非常紧张 - 在 4 个表上测试插入/更新/删除的不同排列将非常困难 - 如果“touchEmail”上的触发器有一个覆盖数据的错误怎么办由“touchHome”上的触发器管理?您还可能面临死锁等问题(不确定这是否是 MySQL 的现实问题)。

您是否考虑过为您的 JSON 使用不同的缓存?有多种选择。 MySQL 有一个query cache;如果您可以依赖它,您将动态创建 JSON,并缓存查询。这具有自动处理缓存失效的巨大好处——随着底层数据的变化,MySQL 会清除缓存中的相关项目。不利的一面是——调整这个缓存很棘手。

下一个选项是您的编程语言/框架为您提供什么。大多数现代框架都包含缓存解决方案,但您几乎可以肯定最终会在代码中使缓存无效;这可能是一个复杂的解决方案,但将责任放在它所属的地方(应用程序开发人员)。

如果您的解决方案必须扩展到特殊级别,您可以使用专用缓存 - memcache 适用于大多数环境和语言。它有效、可扩展、稳健 - 但也引入了显着的额外复杂性。

【讨论】:

  • 我知道触发器可能是一场噩梦 - 但是,我们设计模式的一部分是尽可能完全地将数据库与开发人员/应用程序分开。
  • 数据冗余问题是非典型的。很明显,数据被存储了 3 次——不同之处在于,虽然我们可以输入(几乎)任何表,但我们只向 ONE 请求。从 table_column->table_json->relation_json 也是一个非常线性的路径。每一步都与上一步有明显的区别。使标准化/故障排除变得相当简单。
  • 除了原生 json no-sql 数据库之外,我还没有真正考虑过不同的缓存。但我对 no-sql 数据库不够熟悉,无法做出明智的决定。建议?
【解决方案2】:

我能想到的最佳选择是创建一个默认值为 0 的“更新”元数据列。当我们更新电话、电子邮件、姓名或家庭时,元数据列更改为 1(表示更新未提交到关系 JSON 列)

接下来创建一个存储过程“request_relations_json()”,用于检查未决提交(“更新”元列中的 1)。如果没有更新,则将当前的 Relations.json 列返回给应用程序。如果有更新,则重新生成 json,然后将其返回给应用程序。

它很老套,但它不会在每次更新时生成 json。我仍然希望有更优雅的解决方案。

【讨论】:

  • 后来我改用 couchdb,激动不已。它既漂亮又简单,当我更改架构时它可以节省很多时间。
猜你喜欢
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2013-09-09
  • 2016-11-27
  • 1970-01-01
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多