我是否应该让FK指向很少更改的数据,或者只是直接粘贴数据?

时间:2011-06-03 12:02:50

标签: sql

假设我有一些永不改变的表格,例如“州”(指美国州)或“国家”表。如果我有一个Customer表来存储CustomerState,CustomerCountry等信息,是否真的有必要将它们作为FK存储到相应的表中?

这些值是从从州或国家/地区提取相应数据的表单中填充的(即状态将始终作为正确的双字母代码输入 - 用户无法输入自定义输入或类似的任何内容)。

我问,因为似乎为某些事情添加额外的连接只会减慢查询速度。这对我来说不是问题,因为我在一个小小的数据库上工作......但总有一天我可能不会。它甚至重要吗?性能损失是如此微不足道,我应该这样做吗?

8 个答案:

答案 0 :(得分:3)

是的,将它们存储为单独的表格。密钥(和外键)可以是char(2)。

某些点,您将拥有:

  • 数据修改异常
  • 另一个数据录入客户端
  • 批量上传
  • 一个新州(Baja Arizona,有人吗?)
  • 要添加到状态实体​​的状态表的一些额外信息
  • a bollixed release
  • ...

答案 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关系。