应该将记录草案保存在单独的表格中吗?

问题描述:

我们正在构建一个简单的基于网络的系统,通过这个系统,某人添加了一个记录,例如一个CMS页面,并在网站上显示之前由负责人批准。应该将记录草案保存在单独的表格中吗?

如果作者随后决定编辑该页面,我们希望基于实时副本创建草稿,在批准时它将替换旧的实时页面。

我们考虑过要完成版本控制,但相信我们可以通过只有1来简化这个过程。仅仅是一个草稿,2.只是一个活的,或者3.一个草稿,一个活的。

此功能是跨多个“事物”而不仅仅是页面需要的。

最后问题:你认为将这两条记录存储在同一张表中还是镜像表更好会更好?

我想这可能取决于,但我不喜欢具有相同结构的两个表的理想。对于稍微慢一点的操作(因为我们必须在显示数据时始终查询草稿)是否值得呢?

+0

“操作稍慢”您是否测量过?这是事实吗?或者你认为它会变慢? – 2010-03-11 16:13:16

+0

当我还没写完它时,它怎么会是事实?很明显,我假设添加一个where子句,而不是仅仅从一个活动表中选择所有记录会比较慢,但我很乐于了解为什么我错了。 – tsdbrown 2010-03-12 09:31:00

+0

如果你还没有写它,那么你需要建立两个秒杀解决方案,并衡量差异。假设是不好的。测量很好。 – 2010-03-12 10:53:47

第一个实体类型,一个表。

理由重新考虑:

  1. 记录草案由成千上万的因素多于现场记录之一。

  2. 安全条件要求访问数据库的某些用户直接对GRANT/REVOKE级别的草稿或活动记录拥有某种权限,但不得超过其他类型的记录。

的第二个设计考虑是对项目和LiveItems第二表的一个表。第二个表格仅包含活动项目的ID。这样你就可以维护你的单表设计,但是你可以通过将你的单列表连接回主表来找到LiveItems。

+0

谢谢你。 – tsdbrown 2010-03-12 09:41:53

当状态发生变化时,将东西从表格移动到表格是一个坏主意。

当您想要将其他状态添加到工作流程时,您必须添加更多表格。

这只是一种状态变化 - 这就是关系数据库的优化对象。

一个表,多个状态是标准方法。

如果您发现事情非常缓慢 - 并且您可以证明基于状态的查询是完整的原因 - 您可以诉诸于“物化视图”或类似的技术状态改变(以及由此产生的移动)由RDBMS处理。

Table-per-state是一个坏主意。

  1. 您不能轻松添加状态。你必须添加表格,并且使它变得很痛苦。此外,您必须使用新的表名更新代码以反映新的工作流程。

    如果一个状态只是一个列,那么添加新的状态就是在代码中添加新的值和新的if语句。状态更改只是更新,而不是“删除 - 插入”。

    数据永远存在,每当用户有一个聪明的想法时,工作流程都会来去去去。不要因为想改变工作流而惩罚他们。

  2. 你不容易有子状态。许多状态机实际上是多个嵌套的状态机。用每个表的状态添加一个子状态可以创建更多的规则更多的表。

    如果一个状态只是一个列,那么嵌套的子状态就是代码中带有新的if语句的另一列。状态更改只是更新,而不是“删除 - 插入”。

  3. 你不容易有并行状态机。很多时候,有许多并行状态代码更改。有时会有手动工作流程(审批)和自动化的工作流程(归档,复制到数据仓库等)。)对于每个状态表和并行状态机,没有办法合理地实现它

    如果每个状态只是一个列,那么并行状态机就是并行更新。

+0

总的来说,我同意你的意见,但你知道这是不是只有一个记录经历了一系列状态?这将是初步的,但随后草案将需要与现场相关记录一起存在,并可能在批准后稍后进行替换。 – tsdbrown 2010-03-12 09:36:15

+0

@rsdbrown:“添加记录”。听起来很奇怪。如果它不是一个记录,请更新这个问题。重要的是更新多个记录或更新单个记录并不重要。每个状态表是一种糟糕的设计,当您尝试添加状态时会迅速恶化。状态只是该行的状态码。 – 2010-03-12 10:55:24

+0

看,我们同意这两张表是不好的设计,我甚至在我的问题上暗示了我的想法!我问这个问题的原因是因为我已经看到其他人如何在rails插件中实现这一点,例如acts_as_versioned和has_draft。我不认为你理解我的问题,这可能是我的做法。不过其他人似乎明白这个想法,我相信这个问题已经足够清楚了。谢谢您的意见。你的,其他人和我自己的想法已经证实我不会有两张桌子。 – tsdbrown 2010-03-12 12:00:06

同意上面给出的所有意见:只有一个表。
通过scopes,您可以轻松获取已发布的帖子或草稿。

我不会为它推荐。
但是,如果您确实希望草稿和发布的条目有两种不同的模型,则还有其他解决方案:STI

你就会有两个型号:

class Post < ActiveRecord::Base 
end 

class Draft < Post 
end 

任何对象草案从表后采取的。
Type参数使其成为帖子或草稿。

每当你要发布一个帖子你那么要做的:

@draft = Draft.first 
@draft[:type] = 'Post' 
+0

STI是我一直在考虑的东西,具有范围的状态列几乎与具有类型列的状态列相同。你会说范围/地位的方式会更好吗?我喜欢STI的想法,因为控制器就像LivePost.all和DraftPost.all – tsdbrown 2010-03-12 09:41:19

我刚刚作出了一个宝石这样的使用情况。它在单独的表格中存储草稿: https://github.com/ledermann/drafting