如何在仅插入数据库中创建具有依赖元素的草稿页面

时间:2017-12-06 12:58:27

标签: sql database postgresql database-design

我有一个只插入的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.book_id FK替换Element.page_id FK,以便让一个元素和页面的桶更松散地相互耦合。这样,在克隆页面时,我不必克隆所有元素,但我需要一种方法将每个元素与特定版本的页面相关联。

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

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

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

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

1 个答案:

答案 0 :(得分:1)

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

  1. 您可以使用自己的元素插入每个新页面。 (使用null父级)
  2. 如果现有Pages的任何新版本即将推出,您可以插入包含父页面ID的新页面。
  3. 无需将父页面的元素设置为新页面。 (页面可以从父页面检索它们)
  4. 如果新版本具有特定的元素,您可以将它们设置为新的页面。
  5. 等等。
  6. 请注意,PostgreSQL在递归查询中表现出色。