我对如何重构我的数据库感到有点困惑,目前我参与了三个表:
项目:包含“项目”的基本信息(user.id,名称,描述,feature_1(bool),feature_2(bool)等等)
Feature_1:其中包含“item”的一些可选值,因此如果用户决定将Feature 1设置为其项目,我们将在Feature_1中创建一条记录并填写这些值。 1个项目在“Feature_1”表中不能有多个记录,因此它有1个记录或没有记录。
Feature_2:与Feature_1相同但具有不同的可选值,因此用户可以将Feature_1添加到其项目和/或Feature_2中。同样,每个项目可以有0或1个Feature_2记录。
我不确定它是否是最佳实践,其中一个选项是将1个表“Items”中的所有值混合为多个NULL值。
任何建议和指示都将不胜感激。
答案 0 :(得分:3)
在处理锁定问题方面,分离出这样的值可能会有所帮助。如果您正在运行多个正在更新的守护进程/脚本以及那些表并对其进行锁定,那么将所有这些值保存在一个表上可能是一个问题。当然,现在'item'的值被分成三个表,如果/当你需要所有这些表时,你会遇到追逐它们的问题。一般来说,将这些表格分开就可以了。
另外,在任何人分开这样的数据之前,通常最好尝试/排除以下各项:
尽可能使用'with(nolock)'来防止锁定问题。
修改维护此数据的脚本,以尽可能少地使用“begin tran”类型的事务。
修改维护数据的脚本的执行,以便它们更可能被顺序调用,而不是同时调用。例如把他们放在同一份工作中。
答案 1 :(得分:2)
我倾向于同意这三个表格。因为您说项目只能链接到零个或一个Feature_1以及零个或一个Feature_2,所以您可以向项目表添加两列,并引用Feature_1和Feature_2主键。您可以对这些列使用外键约束,并使它们无效以指示该功能不存在。这也意味着您可以放弃布尔值并保留检查类型1或2功能是否可用而无需连接表的好处。
答案 2 :(得分:1)
纯粹主义者会说你应该将每个功能都作为单独的表,每个表都有一个到Items表的外键。而且,一般来说,我同意,虽然如果相当小比例的项目不具备这两个功能,并且功能记录的大小很小,则可能值得消除必须加入表格的开销。
答案 3 :(得分:1)
对于这些类型的问题,没有一个通用的解决方案。但是,您已经描述了两种非常常见且适当的解决方案。
理论上,您实际上可以从主表中删除feature_x
布尔字段。那个事实'隐含在要素表中记录的存在与否中。让它们变得不好,它是一种缓存/非规范化,增加了复杂性,以便潜在地提高性能。
我唯一可能避免这种设置的方法是用户可以创建新功能,或者您拥有不可靠的大量功能。然后,您可能需要实体 - 属性 - 值设置。 EAV非常灵活,但它有自己的重大问题。同样,没有一个尺寸适合所有。
简而言之,如果你拥有的是为你工作,你所拥有的就好了。