我的任务是为Oracle 11g数据库创建历史表。我在本文What is the best way to keep changes history to database fields?
的第一个答案中提出了与基于记录的解决方案非常相似的内容然后我的老板建议,由于某些表是聚类的,即表1中的某些数据与表2相关(将其视为表格在归一化之前的格式),他希望是在此群集级别的所有表之间维护的版本号。建议的生成版本号的方法是使用SYS_GUID http://docs.oracle.com/cd/B12037_01/server.101/b10759/functions153.htm。
我考虑过使用触发器执行此操作,因此当其中一个表更新时,其他表版本号随后会更新,但我可以看到一些问题,如下所示:
我是Oracle数据库开发的新手,所以关于这是否是一个好主意的一些建议/如果有更好的方法这样做会很棒。
答案 0 :(得分:0)
我认为您正在寻找的是序列:http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_6015.htm#SQLRF01314
这些表可以独立地从定义的序列中获取数字,因此不会出现竞争条件或触发器
答案 1 :(得分:0)
对你的第一个问题的简短回答是“不,你不能。”原因是用户无法停止声明的触发器。我能想象的唯一方法是锁定表的一些存储,例如,您创建一个中间表,并在您的群集表中选择同一行进行更新。但这确实是一种糟糕的方式,正如你在第二个问题中提到的那样。这将导致可怕的并发问题。
对于你的第二个问题,你是对的。用于更新同一审计表的不同原始表的不同触发器将导致严重的争用。明智的做法是记住触发工作的方式,即当其余的事务提交时它们被提交。因此,如果所有相关表都将更新相同的审计表,尤其是对于同一行,则同时将使合理范例不被使用。规范化的一个好处是性能增益,因为当您更新不同的表时将不会相互满足。但在这种情况下,如果要在审计表中同步不同的表的操作。它最终将像平面文件一样工作。所以我的建议是尽力说服你的老板使用你的原始提案。
但是,如果您的应用程序始终在事务中更新这些聚簇表,并将一个审计信息写入审计表。您可以编写存储过程以首先更新实体,并在事务结束时编写审计。然后,您可以使用sequence生成审计表的id。这不会是任何争论。