假设我有一些永不改变的表格,例如“州”(指美国州)或“国家”表。如果我有一个Customer表来存储CustomerState,CustomerCountry等信息,是否真的有必要将它们作为FK存储到相应的表中?
这些值是从从州或国家/地区提取相应数据的表单中填充的(即状态将始终作为正确的双字母代码输入 - 用户无法输入自定义输入或类似的任何内容)。
我问,因为似乎为某些事情添加额外的连接只会减慢查询速度。这对我来说不是问题,因为我在一个小小的数据库上工作......但总有一天我可能不会。它甚至重要吗?性能损失是如此微不足道,我应该这样做吗?
答案 0 :(得分:3)
是的,将它们存储为单独的表格。密钥(和外键)可以是char(2)。
在某些点,您将拥有:
答案 1 :(得分:3)
这里的设计经验法则是,如果值集的基数较低且其成员稳定(尽管不一定是不可变的),则使用CHECK
约束(例如:ISO 5218 sex codes)。否则,请使用带外键的查找表。
请注意,某些国家/地区(边界和名称)不如其他国家/地区稳定:) CustomerCountry
可能对不同的消费者有不同的含义。想想你可以在蜗牛邮件(英国,英国,大不列颠及北爱尔兰联合王国,Angleterre等)上放置的我国名称的所有变体,并且仍然希望它能够交付,而您的应用程序逻辑可能只想使用值ISO 3166-1 alpha-3 = 'GBR'
请注意,在mySQL中虽然使用CHECK
约束是有效的语法,但它实际上从未被检查过,所以我认为,mySQL的经验法则是始终使用带有外键的查找表! / p>
答案 2 :(得分:1)
建立关系是一种很好的设计方法/实践。
就表现而言,正如你自己所说,它是微不足道的/可忽略的!
答案 3 :(得分:1)
这主要取决于您希望设计的正确程度。我总是创建一个单独的查找表,使用外键查找。只有在提出性能问题时,我才会考虑更改它。但是,我是一名数据库设计师,并认为所有业务规则都应该在数据库中,并从那里强制执行。
答案 4 :(得分:0)
是的,确实如此。并且有很多原因:
可能还有很多其他原因。
答案 5 :(得分:0)
就个人而言,我的设计中并没有两个“州”表。就像你说的那样,用户可能无法进入无效状态,因为输入来自下拉列表。
但是,为了回答你关于表现的另一个问题,我认为如果你加入,你会发现它会减慢速度。您需要记住,SQL会将数据缓存在RAM和非常小的表中,它只会缓存整个表,因此在第一次访问后没有I / O命中。
答案 6 :(得分:0)
不要做早期优化!假设你有一个支持数据库重构的设计/体系结构,我建议你推迟你的性能驱动的非规范化,直到你遇到真正的性能问题。你可能会省去一些头痛。
答案 7 :(得分:0)
我的态度有点不同。 如果我有一张州表,那么无论如何我都会使用官方缩写作为PK。将它定义为char(2),我不希望长字符串索引的(适度)开销。我不会添加标识列。在这种情况下,您现在不必决定是否需要该表。如果以后需要更多的State对象列(例如,销售税率),则可以创建表,只需从长期的Customer表中添加FK关系。