【问题标题】:Keeping page changes history. A bit like SO does for revisions保留页面更改历史记录。有点像 SO 对修订所做的
【发布时间】:2011-03-29 17:25:07
【问题描述】:

我有一个 CMS 系统,可以像这样跨表存储数据:

Entries Table
+----+-------+------+--------+--------+
| id | title | text | index1 | index2 |
+----+-------+------+--------+--------+

Entries META Table
+----+----------+-------+-------+
| id | entry_id | value | param |
+----+----------+-------+-------+

Files Table
+----+----------+----------+
| id | entry_id | filename |
+----+----------+----------+

Entries-to-Tags Table
+----+----------+--------+
| id | entry_id | tag_id |
+----+----------+--------+

Tags Table
+----+-----+
| id | tag |
+----+-----+

我正在尝试实施一个修订系统,有点像 SO。如果我只是为Entries Table 做这件事,我打算只在一个单独的表中保留对该表的所有更改的副本。因为我必须为至少 4 个表执行此操作(TAGS 表不需要修改),所以这似乎根本不是一个优雅的解决方案。

你们会怎么做呢?

请注意,元表是在EAV (entity-attribute-value)中建模的。

提前谢谢你。

【问题讨论】:

    标签: mysql database version-control revision entity-attribute-value


    【解决方案1】:

    您好,目前正在研究类似问题的解决方案,我正在通过将我的表分成两个表来解决它,一个控制表和一个数据表。控制表将包含一个主键和对数据表的引用,数据表将包含自增修订键和控制表的主键作为外键。

    以你的条目表为例

    Entries Table
    +----+-------+------+--------+--------+
    | id | title | text | index1 | index2 |
    +----+-------+------+--------+--------+
    

    变成

    entries             entries_data
    +----+----------+   +----------+----+--------+------+--------+--------+
    | id | revision |   | revision | id |  title | text | index1 | index2 |
    +----+----------+   +----------+----+--------+------+--------+--------+
    

    查询

    select * from entries join entries_data on entries.revision = entries_data.revision;
    

    您使用插入语句而不是更新 entries_data 表,然后使用条目表的新修订版更新条目表的修订版。

    此系统的优点是您可以通过更改条目表中的修订属性来移动到不同的修订。缺点是您需要更新查询。我目前正在将其集成到 ORM 层中,因此开发人员无论如何都不必担心编写 SQL。我正在玩弄的另一个想法是有一个所有数据表都使用的集中修订表。这将允许您使用单个修订号来描述数据库的状态,类似于颠覆修订号的工作方式。

    【讨论】:

    • 为什么有人不赞成 ejrowley 的回答?我仍在寻找可能的最佳解决方案,并将在应得的情况下给予信用。但这似乎是一个可行的解决方案,不是吗?
    • 即使你的系统不是我想要的;我相信 Edward Williams 中的Media Wiki table-scheme 在性能和可用性方面都是更接近的答案;我相信你的答案与爱德华兹的答案一致,有更好的示意图,所以我接受了。谢谢!
    【解决方案2】:

    看看这个问题:How to version control a record in a database

    为什么不为每个表设置一个单独的 history_table(根据链接问题的公认答案)?这只是具有原始表的 PK 和修订号的复合主键。毕竟,您仍然需要将数据存储在某个地方。

    【讨论】:

    • 你的回答很有趣。特别是Media Wiki 数据库方案。它创建了一个额外的层table -> revisions keys -> revisions data,使data table 尽可能小,同时提供修订历史记录并能够在修订之间来回导航,就像 SO 一样。我还是想知道有没有更优雅的方式来存放它。
    【解决方案3】:

    对于我们的一个项目,我们采用了以下方式:

    Entries Table
    +----+-----------+---------+
    | id | date_from | date_to |
    +----+--------_--+---------+
    
    EntryProperties Table
    +----------+-----------+-------+------+--------+--------+
    | entry_id | date_from | title | text | index1 | index2 |
    +----------+-----------+-------+------+--------+--------+
    

    相当复杂,仍然允许跟踪整个对象的生命周期。因此,对于查询我们想要的活动实体:

    SELECT 
    entry_id, title, text, index1, index2
    FROM
    Entities INNER JOIN EntityProperties
    ON Entities.id = EntityProperties.entity_id
    AND Entities.date_to IS NULL
    AND EntityProperties.date_to IS NULL
    

    唯一担心的是实体被删除(所以我们在那里放了一个 date_to)然后由管理员恢复的情况。使用给定的方案无法跟踪此类技巧。

    任何这样的尝试的总体缺点是显而易见的 - 您必须编写大量的 TSQL,其中非版本控制的数据库将用于类似 select A join B 之类的东西。

    【讨论】:

      猜你喜欢
      • 2013-05-01
      • 2015-11-17
      • 1970-01-01
      • 2021-05-16
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      相关资源
      最近更新 更多