【问题标题】:redesigning my database重新设计我的数据库
【发布时间】:2023-12-08 23:30:01
【问题描述】:

在一个旧的网络应用程序上,我有一个具有以下结构的表:
tools(id, name, abbreviation, width, height, power, type)

问题是我需要为工具添加历史支持。工作场景是每个工具的细节都可以修改,我需要跟踪变化。例如,如果我需要查看过去某个日期的某个工具的详细信息,我该怎么做?

数据库的外观如何?

【问题讨论】:

  • 到目前为止你想到了什么?

标签: mysql database-design versioning


【解决方案1】:

我会保留同一张表,但添加一个dateEffective 字段,然后在每次工具更改时创建一个新行。然后在查询表时,您可以使用以下命令获取给定日期的工具版本:

SELECT * FROM tools WHERE id=@id AND dateEffective<@thisDate ORDER BY dateEffective DESC LIMIT (0,1)

编辑您可能希望创建另一个名为 toolVersionId 的字段作为主键。

编辑 2 针对您的评论,如何:

SELECT *
FROM tools t1
WHERE toolVersionId IN (SELECT toolVersionId
                        FROM tools t2
                        WHERE t2.id = t1.id
                        ORDER BY t2.dateEffective DESC
                        LIMIT (0,1)
                       );

【讨论】:

  • 你知道我怎样才能得到整个表格,只有工具的最后一个状态吗?
  • @doledoug 我已经发布了我的尝试,但不确定它是否会起作用(我不是专家,抱歉!)请告诉我。
【解决方案2】:

可能有很多方法可以做到这一点。我过去成功的一种方法是在表格中添加一个version_id 列。因此idversion_id 的组合成为任何特定版本工具的完整密钥。请注意,使用这种方法很容易获得特定工具的所有版本,您只需选择id。获取该工具的当前版本也很容易,只需id, max(version_id)

这种方法的一个缺点是您需要编写代码来管理版本控制。

【讨论】:

  • 也许一些漂亮的触发器可以自动“归档”版本?
  • @mike,是的,这当然是一种可能性,尽管我过去没有那样做。
  • 是的,数据库逻辑有点反 mySQL。我更喜欢 Postgres,我们不介意编写数据库代码 :)
  • @MikeChristensen:从这个角度来看postgres和mysql有什么区别?
  • 我没有太多的 mySQL 经验,但对我来说,“文化”似乎不同——Oracle、SQL Server 和 Postgres 提倡更多的是“让数据库来完成我们所有的工作”的理念,而 mySQL 则提倡“仅使用数据库来存储数据,并在中间层进行计算”的心态。当然,这是一个笼统的概括,但我认为它有一定的道理。
【解决方案3】:

创建一个包含所有相同列的 ToolsVersions 表,也只添加一个时间戳。每次更改工具时,将旧值与当前时间戳一起保存到 ToolsVersions 表中。然后,您可以相当轻松地查询某个范围内的所有版本,或者找到最接近所需日期的版本。

【讨论】: