在开发内容管理系统时,我遇到了一些困难。回到我的数据模型,我注意到一些随着时间的推移可能变得更加普遍的问题。
也就是说,我想维护一个用户修改记录的审计跟踪(更改日志)(即使用户修改记录也会被记录下来)。由于包含任意数量的模块,我不能对主键使用“按表自动递增”字段,因为当试图在单个表中维护主键时,它将不可避免地导致冲突。
审计跟踪将保留user_id
、record_id
、timestamp
、action
(插入/更新/删除)和archive
(旧记录的序列化副本)的记录。
我考虑了一些可能的解决方案,比如在应用程序逻辑中生成一个UUID
主键(以确保跨数据库平台的兼容性)。
我考虑过的另一个选项(我相信即使考虑这个方法,大家的共识也会是否定的)是,创建一个RecordKey
表,来维护一个全局自动递增的键。不过,我相信有更好的方法来实现这一点。
最后,我很想知道在尝试实现这一点时应该考虑哪些选择。例如,我打算允许(至少开始)mysql和sqlite3存储的选项,但我关心每个数据库如何处理UUID
s。
编辑以使我的问题不那么含糊:使用全局id是否是解决我的问题的推荐方法?如果是这样,使用128位UUID(应用程序或数据库生成),我可以在表设计中做些什么来帮助最大化查询效率?
最佳答案
好吧,你撞到砖墙了。你会意识到数据库的设计确实有问题。而且你以后还会多次撞到这面砖墙。你的未来看起来并不光明。你想改变这一切。很好。
但你还没有做的是,找出真正的原因是什么。你不能逃避可预见的未来,除非你这样做。如果你做得好,就不会有砖墙,至少不会有这种特殊的砖墙。
首先,您在所有表上粘贴Id
iot列以强制唯一性,而没有真正理解用于查找数据的标识符和键。那是墙是用砖砌成的。对于一个需要考虑的问题,这是一种未经深思熟虑的下意识反应。这就是你要重新参观的地方。
不要再重复同样的错误。对guid或uuid或32字节的iot列进行重击以修复您的iot列不会做任何事情,只会使db变得更胖,并且所有访问,特别是连接,都会慢得多。这堵墙将由混凝土砌块砌成,每小时都会撞到你。
回去看看这些表,然后设计它们,以期成为数据库中的表。这意味着您的起点是没有surrogate键,没有iot列。完成后,将很少有Id
列。不是零,不是所有的桌子,但很少。所以墙里的砖很少。我最近发布了一组详细的步骤,请参考:
Link to Answer re Identifiers
有一个审计表包含所有表的审计“记录”的理由是什么?你喜欢碰见砖墙吗?是否希望在一个文件中的插入热点上限制数据库的并发性和速度?
审计需求已经在dbs中实现了40多年,因此您的用户有一些其他需求不会改变的可能性不是很高。还是好好做吧。对于审计表,唯一正确的方法(对于RDB)是每个可审计实表有一个审计表。pk将是原始表pk加上datetime(复合键在现代数据库中是正常的)。其他列将是userid和action。行本身将是前一个图像(新图像是主表中的单个当前行)。使用完全相同的列名。不要把它捆成一根巨大的绳子。
如果不需要数据(图像之前),请停止记录。无缘无故地把所有的音量都录下来是很愚蠢的。可以从备份中获得恢复。
是的,一张桌子是个怪物。还有另一种保证数据库单线程的方法。
不要回应我的帖子,我已经从你的评论中看到,你有做错事的所有“正确”理由,并且保持你的砖墙完好无损。我想帮你摧毁他们。仔细考虑几天后再作出回应。
关于database - 主键,UUID,RecordKey表,哦,我的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4282519/