【问题标题】:How to create draft pages with dependent elements in insert-only database如何在仅插入数据库中创建具有依赖元素的草稿页面
【发布时间】:2017-12-06 12:58:27
【问题描述】:

我有一个只插入的 PostgreSQL 数据库,其中包含一个 Book 表、一个 Page 表和一个 Element 表。 书籍可以有多个页面,页面可以有多个元素。 数据库是仅插入的,因为每当修改页面时,出于审核原因,都会在新记录中创建该页面的新版本。

-------------
Book
-------------
id [PK]

-------------
Page
-------------
id [PK]
book_id [FK]
version
created

-------------
Element
-------------
id [PK]
page_id [FK]
version
created

目前,Element 有一个指向 Page.id 的外键,而 Page 有一个指向 Book.id 的外键。

要求有独立的页面草稿(版本),可以包含任意数量的元素。每次创建新的页面草稿(版本)时,新草稿应该是之前版本的克隆,并且应该包含之前版本中的所有元素。元素可以添加到页面的特定版本或从中删除,但元素记录永远不会被删除。

出于可扩展性的原因,我会避免将所有元素与页面一起克隆,因为元素的数量可能非常大。我也会避免页面和元素之间的多对多关系。

我正在考虑将 Element.page_id FK 替换为 Element.book_id FK,以便让单个元素和页面更松散地耦合在一起。这样,在克隆页面时,我不必克隆所有元素,但我需要一种方法将每个元素与页面的特定版本相关联。

理想情况下,我应该能够通过单个 SQL 查询检索一个包含与该版本相关联的所有元素的页面版本。

我仍处于设计/原型制作阶段,因此数据库的任何方面都可能被更改以满足要求。

根据上述要求关联页面和元素的最佳方式是什么?我希望要求清楚,如果没有,请提出任何问题,我会尽力澄清。

注意:“仅插入”数据库是指没有记录被更新或删除的数据库,只有插入。这是出于审核目的,因此我们可以获得任何编辑活动的完整历史记录。

【问题讨论】:

    标签: sql database postgresql database-design


    【解决方案1】:

    可能的解决方案是使用页面上的一元关系(每个页面都有父 Page_id)。

    1. 您可以使用自己的元素插入每个新页面。 (与 null 父级)
    2. 如果现有页面的任何新版本即将推出,您可以插入具有父页面 ID 的新页面。
    3. 无需将父页面的元素设置为新页面。 (页面可以从父页面检索它们)
    4. 如果新版本有特定的元素,您可以将它们设置为新的即将到来的页面。
    5. 等等。

    请注意,PostgreSQL 在递归查询方面具有卓越的性能。

    【讨论】:

    • 这是一个有趣的解决方案。我认为,如果我想更新子页面中的元素但属于父页面,我可以将一个新元素添加到具有相同哈希标识符但更新的 created 日期的子页面。这样,如果我想查询子页面的所有元素,我可以获取具有不同哈希值和最近的 created 日期的元素。
    猜你喜欢
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    相关资源
    最近更新 更多