在MySQL中,如果我有一定数量的categories
永远不会改变,我应该在他们分类的东西的表中创建bool字段,还是应该使用映射表?如果是这样,为什么?
案例A:
t_stuff
id (int)
name (string)
category_a (bool)
category_b (bool)
category_c (bool)
category_d (bool)
category_e (bool)
category_f (bool)
案例B:
t_stuff
id (int)
name (string)
t_categories
id (int)
name (string)
t_stuff_category
id (int)
stuff_id (int)
category_id (int)
虽然A看起来并不像B那样“好看”,但就所需的查询而言似乎更简单了吗?
编辑:我觉得我应该补充说我需要做的就是:
答案 0 :(得分:3)
绝不使用案例A
。它违反了关系数据库的原则。了解normalization。
假设您要查找id
的{{1}},则需要检查category = 1
中的每一列:
A
这种设计不仅难以查询,而且也是聚合的噩梦。如果您想获得特定SELECT id
FROM t_stuff
WHERE category_a = 1
OR category_b = 1
OR category_c = 1
OR category_d = 1
OR category_e = 1
OR category_f = 1
的{{1}}类别,该怎么办?
如果是COUNT(*)
,您只需查询一个属性:
id
要获取B
,您只需替换SELECT stuff_id
FROM stuffCategory
WHERE category_id = 1
。
此外,COUNT(*)
下您不需要id
。 (id
)的复合主键就足够了。
答案 1 :(得分:1)
这里最重要的是“永不言败” - 在问题和评论中,你自信地说:
随着时间的推移,需求会发生变化,并且基于预测某些事情从不发生而设计系统可能会在以后导致挫败感,因为您必须解决设计中的限制。
当然,去标准化版本有一些优点(只有布尔列),但实际上只有你有一个非常少的“类别”(我会说< = 3),这样你才可以将它们视为“属性”而不是“类别”:
JOIN
子句的影响。JOIN
子句。您可以使用标准化设计而不是一组布尔列来执行以下操作:
COUNT()
同样,您可能不想做任何现在这些事情,但除非您计划在一周内丢弃该应用程序,您无法预测未来的要求。软件设计的很大一部分是使代码可维护,并在简单性和灵活性之间进行合理的折衷。