有没有mysql“多表”触发器 - 例如,只有在所有表更新完成后才触发的触发器?

5

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

关系只是一个数字连接(如果有对它的专业术语请告诉我),它允许我将多个姓名、电子邮件、电话、住址连接成一个对象 -

例如:the touchRelation.json列

{ 
"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()函数。有没有一种简单的方法来判断是否已更新了一个或多个表,并且仅在所有表的所有更新完成后重新生成relations.json?
一个可能的解决方案是创建一个“待处理更新”表,将信息存储在队列中,逐个从队列表中插入/更新数据到存储表,然后调用更新函数,但我确信这不是最佳选择。
另一个选择是在数据库中创建一个JSON解析器,读取完整的json关系(来自上面的大型json),更新表,然后构建json对象,但这似乎是对数据库的不良使用。

2
也许可以使用事务来进行这样的更新,并在“提交事务”时运行触发器? - Vesper
1
这就是存储过程的使用场景。创建一个调用你的代码的过程,并移除直接更新表的权限 - 从而强制开发人员始终调用该过程。 - Knaģis
1
@Vesper:我认为MySQL不支持在提交时触发的触发器。 - user330315
如果JSON文档始终完全基于数据库中的内容,那么在选择时“即时生成”JSON是否更好呢?尽管MySQL根本没有JSON支持,但仍可以通过函数实现。 - user330315
好问题 - json始终基于数据库的内容,但是我请求数据的次数比插入数据的次数多得多。此外,任何时候都有很多请求数据的请求,如果每次都动态生成复杂的json对象数千次,那么我的服务器将会崩溃,而我只需生成一次即可,六个月后也不用再担心它。 - Patrick Pease
显示剩余5条评论
2个回答

0

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

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

只有通过“每个表一个触发器”的方式,您才能实现所需的功能,而不必采用奇特的解决方案(例如模拟材料化视图)。

然而,由于您已经将数据存储了3次(一次在“正常”列中,一次在表JSON中,一次在关系JSON中),效率真的很重要吗?您知道这是一个问题吗?

我更担心的是,我原则上不喜欢触发器——它们很难测试,调试起来更困难,而且在不断变化的数据库中难以维护。 对于那些作用于当前行之外的数据或表的触发器,我感到非常紧张——在你的四个表上测试插入/更新/删除的不同排列组合将会非常困难——如果"touchEmail"上的触发器有一个覆盖了"touchHome"触发器管理的数据的错误,那该怎么办呢?你也可能会遇到死锁等问题。(不确定这是否是MySQL上的真实问题)。
你是否考虑过为JSON使用其他缓存方式?有很多选择。MySQL有查询缓存;如果你可以依赖它,你可以即时生成JSON,并缓存查询结果。这样做的巨大好处是处理缓存失效是自动的——当底层数据发生变化时,MySQL会清除缓存中相关的项。不过,调优这个缓存是棘手的。
下一个选择是你所使用的编程语言/框架提供的缓存解决方案。大多数现代框架都包含了缓存解决方案,但你几乎肯定需要在代码中使缓存失效;这可能是一个复杂的解决方案,但把责任放在了应用程序开发人员身上是正确的做法。
如果您的解决方案需要扩展到异域级别,您可以使用专用缓存 - memcache 可用于大多数环境和语言。它工作稳定、可扩展,但也会引入显著的额外复杂性。

我了解触发器可能是一场噩梦 - 然而,我们的设计模式的一部分是尽可能完全地将数据库与开发人员/应用程序分离。 - Patrick Pease
数据冗余问题是不典型的。显然,数据被存储了3次 - 使这个问题与众不同的是,虽然我们可以输入到(几乎)任何表中,但我们只从一个表中请求。从table_column->table_json->relation_json,这也是非常线性的路径。每一步都清晰地区分于前一步。这使得规范化/故障排除变得相当简单。 - Patrick Pease
我并没有考虑过除了本地 JSON No-SQL 数据库之外的其他缓存方案。但是我对 No-SQL 数据库不太熟悉,无法作出明智的决定。有什么建议吗? - Patrick Pease

0

在这里输入图像描述 我能想到的最好的方案是创建一个“更新”元数据列,并将默认设置为0。当我们更新电话、电子邮件、姓名或家庭信息时,元数据列会更改为1(表示未提交到关系JSON列的更新)

接下来创建一个存储过程“request_relations_json()”,检查是否有未提交的修改(在“更新”元列中为1)。如果没有更新,则返回当前的relations.json列到应用程序。如果有更新,则重新生成json然后返回到应用程序。

虽然这很hackish,但并不是每次更新都要生成json。我仍然希望有更优雅的解决方案存在。


后来我改用了CouchDB,感到非常兴奋。它美观易用,当我更改模式时可以节省很多时间。 - Patrick Pease

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接