我正在构建一个rails应用程序,数据应该重置每个"季节",但仍然保留。换句话说,从任何表中检索的唯一数据应该是当前季节的数据,但如果您想访问以前的季节,您可以。
我们基本上需要整个数据库的多个实例,每个季节一个。
客户的想法是在赛季结束时导出数据库并保存它,然后重新开始。这样做的问题是我们不能一次查看所有的数据。
我唯一的想法是为每个模型添加一个season_id
列。但是在这个场景中,每个查询都需要有where(season_id: CURRENT_SEASON)
。我应该把它作为每个模型的默认作用域吗?
是否有好的方法来做到这一点?
如果您希望将所有数据放在一个数据库中,那么您必须对其进行过滤,这样您就走上了正确的道路。这是完全可以的,因为数据总是被过滤的,所以这不是什么大问题。此外,你所描述的听起来非常类似于将数据标记为存档(其中任何不在当前季节的内容基本上都是存档的),这是非常常见的,通常通过在每个记录上设置一个布尔标志为真或假来完成(我相信),以隐藏它,或一些等效的方法。
您可能需要scope
或default_scope
,其中default_scope
的主要缺点是您必须在想要访问当前季节之外的数据的所有地方使用.unscoped
,而不使用默认作用域意味着您必须在每个调用上指定作用域。默认作用域似乎也可以不时地被应用在有趣的地方,根据我的经验,我更喜欢总是明确地说明我正在使用的作用域(即,我因此从不使用default_scope
),但这更多的是个人偏好。
就如何设计数据库而言,你可以为每条记录添加布尔标志,告诉数据是否在当前季节,或者正如你所指出的,你可以包括一个season_id
,它将根据当前季节ID进行检查并以这种方式过滤它。无论哪种方式,某种作用域都是一种很好的方法。
如果使用一个简单的布尔值,那么在当前赛季结束或新赛季开始时,您将不得不将任何当前赛季记录标记为不再是当前的。这可能需要一个rake任务或类似的东西来方便,但增加了少量的维护。
如果在代码中使用season_id
加上一个常量来指示当前的季节(可能通过配置文件),那么将事物标记为当前季节会更容易,因为不需要从一个季节到另一个季节进行数据库更新。
[免责声明:我不熟悉Ruby,所以我将从数据库的角度进行注释]
这样做的问题是我们不能一次查看所有的数据。
如果您需要保持旧版本的可访问性,那么您应该将它们保存在同一个数据库中。
设计"版本化"(或"时态"或"历史化")数据模型是一种黑色艺术——让我知道你的模型现在是什么样子的,我可能会有一些如何"版本化"它的建议。当处理版本化对象之间的连接时,事情会变得特别复杂。
同时,看看这篇文章,这是一个这样的模型的例子(与你的领域无关,但希望能提供一些想法)。
或者,您可以尝试使用特定于dbms的机制,如Oracle的闪回查询,但这显然不是对每个人都可用,并且可能不适合保持永久的历史记录…