我一开始是故意让这个很模糊的。我正在寻找讨论以及哪些问题比我寻找硬性答案更重要。
我正在设计一个执行投资组合管理之类的应用程序。我到目前为止的设计是
- 问题:需要解决的问题
- 解决方案:针对一个或多个问题提出的解决方案
- 关系:两个问题、两个解决方案或一个问题和一个解决方案之间的关系。进一步细分为:
- 父子 - 某种分类/树层次结构
- 重叠 - 两个解决方案或两个问题真正解决同一概念的程度
- 地址 - 问题解决解决方案的程度
我的问题是关于这些事物的时间性质。问题突然出现,然后消失。解决方案有一个预期的解决日期,但在开发过程中可能会进行修改。随着问题和解决方案的发展,关系的程度可能会随着时间而改变。
那么问题来了:对这些东西进行版本控制的最佳设计是什么,这样我就可以同时了解我的投资组合的当前和历史观点?
后来:也许我应该提出一个更具体的问题,尽管@Eric Beard 的回答值得一提。
我考虑了三种数据库设计。我将充分展示它们的缺点。我的问题是:选择哪个,或者你能想出更好的东西吗?
1:问题(以及单独的解决方案)在版本控制中是自引用的。
table problems
int id | string name | text description | datetime created_at | int previous_version_id
foreign key previous_version_id -> problems.id
这是有问题的,因为每次我想要一个新版本时,我都必须复制整行,包括那个长description
列。
2:新建关系类型:版本。
table problems
int id | string name | text description | datetime created_at
这只是将关系从问题和解决方案表移动到关系表中。同样的重复问题,但可能有点“干净”,因为我已经有了一个抽象的关系概念。
3:使用更类似于Subversion的结构;将所有问题和解决方案属性移动到单独的表中并对其进行版本控制。
table problems
int id
table attributes
int id | int thing_id | string thing_type | string name | string value | datetime created_at | int previous_version_id
foreign key (thing_id, thing_type) -> problems.id or solutions.id
foreign key previous_version_id -> attributes.id
这意味着要加载问题或解决方案的当前版本,我必须获取属性的所有版本,按日期对它们进行排序,然后使用最新版本。那可能并不可怕。对我来说真正糟糕的是我无法在数据库中对这些属性进行类型检查。该value
列必须是自由文本。我可以将该name
列作为对具有列的单独attribute_names
表的引用type
,但这不会强制表中的类型正确attributes
。
稍后:回复@Eric Beard 关于多表外键的评论:
唉,我所描述的很简单:只有两种类型的事物(问题和解决方案)。我实际上有大约 9 或 10 种不同类型的事物,因此在您的策略下我将有 9 或 10 列外键。我想使用单表继承,但事物的共同点太少了,将它们组合到一个表中会非常浪费。