如何在多个数据库表中维护唯一标识符?

时间:2014-01-13 11:25:48

标签: sql database oracle oracle11g

我的任务是为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

我考虑过使用触发器执行此操作,因此当其中一个表更新时,其他表版本号随后会更新,但我可以看到一些问题,如下所示:

  • 如何从一个表中停止触发器,然后触发另一个表的触发器?(我们最终会在这里永远调用触发器)
  • 如何停止比赛条件? (即当表1和表2同时更新时,我如何知道哪个是最新的版本号?)

我是Oracle数据库开发的新手,所以关于这是否是一个好主意的一些建议/如果有更好的方法这样做会很棒。

2 个答案:

答案 0 :(得分:0)

我认为您正在寻找的是序列:http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_6015.htm#SQLRF01314

这些表可以独立地从定义的序列中获取数字,因此不会出现竞争条件或触发器

答案 1 :(得分:0)

对你的第一个问题的简短回答是“不,你不能。”原因是用户无法停止声明的触发器。我能想象的唯一方法是锁定表的一些存储,例如,您创建一个中间表,并在您的群集表中选择同一行进行更新。但这确实是一种糟糕的方式,正如你在第二个问题中提到的那样。这将导致可怕的并发问题。

对于你的第二个问题,你是对的。用于更新同一审计表的不同原始表的不同触发器将导致严重的争用。明智的做法是记住触发工作的方式,即当其余的事务提交时它们被提交。因此,如果所有相关表都将更新相同的审计表,尤其是对于同一行,则同时将使合理范例不被使用。规范化的一个好处是性能增益,因为当您更新不同的表时将不会相互满足。但在这种情况下,如果要在审计表中同步不同的表的操作。它最终将像平面文件一样工作。所以我的建议是尽力说服你的老板使用你的原始提案。

但是,如果您的应用程序始终在事务中更新这些聚簇表,并将一个审计信息写入审计表。您可以编写存储过程以首先更新实体,并在事务结束时编写审计。然后,您可以使用sequence生成审计表的id。这不会是任何争论。