mysql - 应该使用 id 还是 timestamp 来确定数据库表中行的创建顺序? (考虑到系统时钟设置不正确的可能性)

标签 mysql database schema

数据库表用于存储对文本文档的编辑更改。

数据库表有四列:{id, timestamp, user_id, text}

每次用户编辑文档时,都会在表中添加一个新行。新行有一个自动递增的 ID,以及一个与数据保存时间相匹配的时间戳。

为了确定用户在特定编辑期间所做的编辑更改,将响应他或她的编辑插入的行中的 texttext先前插入的行。

要确定哪一行是先前插入的行,可以使用 id 列或 timestamp 列。据我所知,每种方法都有优点和缺点。

使用id确定创建顺序

  • 优点:不会因系统时钟设置不当而导致问题。

  • 缺点:似乎是对 id 列的滥用,因为它规定了 id 列的含义而不是身份。管理员可能出于任何原因(例如,在数据迁移期间)更改一组 id 的值,因为只要它们是唯一的,值是什么并不重要。然后就无法再确定行的创建顺序。

使用timestamp确定创建顺序

  • 优点:id 列仅用于标识,而 timestamp 用于时间,这是应该的。
  • 缺点:只有在每次向表中插入一行时都知道系统时钟已正确设置时,此方法才可靠。如何才能确信系统时钟已为每个插入正确设置?如果发现系统时钟被错误地设置为过去一个未知的时间段,如何修复表的状态?

我寻求一个强有力的论据来选择一种方法而不是另一种方法,或者描述比我正在考虑的两种方法更好的另一种方法。

最佳答案

使用顺序 id 会更简单,因为它可能(?)是一个主键,因此可以索引并可以更快地访问。鉴于您有 user_id,您可以快速断言最后和之前的编辑。

使用 timestamp 也是适用的,但它可能是一个更长的条目,我们根本不知道它是否被索引,加上冲突的可能性。您正确地指出系统时钟可以改变...而顺序 id 则不能。

鉴于您的更新:

由于很难看出您的确切要求,我将其作为特定项目需要 20 万多个复杂文档和数百万次修订的证据。

根据我自己的经验(构建一个完全可审计的文档/分析系统),我为一个由 60 多名全职研究人员组成的内部团队工作。我们最终使用 id 和许多其他字段(包括 timestamp)来提供审计跟踪和完整版本控制。

我们构建的系统每个配置文件都有 200 多个字段,因此对文档进行版本控制远比为每个文档存储一 block 更改的文本/内容要复杂得多;然而,每个配置文件都可以被编辑、批准、拒绝、回滚、发布,甚至可以作为一个文档导出为 PDF 或其他格式。

我们最终做的(经过大量策略/计划之后)是存储配置文件的顺序版本,但它们键控主要id 字段

时间戳

时间戳也被捕获作为二次检查,我们通过使用定期检查时间对齐并在必要时更正它们的 cron 脚本确保保持系统时钟准确(在服务器集群中)。我们还使用了 Ntpd以防止时钟漂移。

其他捕获的数据

还包括(但不限于)为每次编辑捕获的其他数据:

User_id
User_group
Action
Approval_id

还有其他表格满足内部要求(包括自动生成的文档注释)- 因为一些配置文件编辑是使用来自机器人的数据完成的(使用 NER/机器学习/AI 构建),但需要批准在发布编辑/更新之前由团队中的一员完成。

还保留了所有用户操作的操作日志,以便在进行审核时,可以查看单个用户的操作 - 即使他们没有执行此类操作的权限,它仍然被记录。

关于迁移,我不认为这是一个大问题,因为您可以轻松地在移动/转储/传输数据时保留 id 序列。也许唯一的问题是您是否需要合并数据集。您总是可以在那种情况下编写迁移脚本 - 所以从个人角度来看,我认为这种劣势有所减少。

可能值得查看数据浏览器的 Stack Overflow 表结构(相当复杂)。您可以在此处查看表结构:https://data.stackexchange.com/stackoverflow/query/new ,来自关于元的问题:How does SO store revisions?

作为修订系统,SO 运行良好, Markdown /修订功能可能是一个很好的例子。

关于mysql - 应该使用 id 还是 timestamp 来确定数据库表中行的创建顺序? (考虑到系统时钟设置不正确的可能性),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13485852/

相关文章:

php - MySQL - 简化教师/学生订阅者的复杂查询

php - sql命令从数量中减去一项

php - Symfony 不识别 ISNULL 函数

mysql - 从理论上讲,此 SQL 查询是否太大而无法在负载下快速提供服务?

sql - 我如何授予和撤销 Postgresql 用户的特定权限?

mysql - 从数据库中存储的完整路径中提取目录名

州/市目录的 URL 和站点结构

postgresql - postgresql 中的这种安全方法有多安全?

php - 从 Synology NAS 连接 mysql

java - 如何在 Hibernate 中插入外键定义为 Long 的实体?