SQL一对一关系与单个表的关系

问题描述 投票:12回答:5

考虑如下所示的数据结构,其中用户具有少量固定设置。

用户

[Id] INT IDENTITY NOT NULL,
[Name] NVARCHAR(MAX) NOT NULL,
[Email] VNARCHAR(2034) NOT NULL

UserSettings

[SettingA],
[SettingB],
[SettingC]

将用户的设置移动到单独的表中,从而与用户表建立一对一关系是否正确?与将其存储在与用户相同的行中时,这是否具有任何真正的优势(明显的劣势是性能)。

sql database-design rdms
5个回答
8
投票

通常,当表格变得非常宽(即有很多列)时,您会将表格分成两个或多个1:1相关的表格。对于程序员而言,很难处理具有太多列的表。对于大公司,此类表可以轻松拥有100多个列。

所以想象一个产品表。有一个售价,也许还有另一个仅用于计算和估计的价格。拥有两个表,一个用于实际值,一个用于计划阶段,这不是很好吗?因此,程序员永远不会混淆这两种价格。或进行产品的物流设置。您想插入产品表中,但其中具有所有这些逻辑属性,是否需要设置其中一些?如果是两个表,您将插入到产品表中,而另一个负责后勤数据的程序员将关心物流表。不再混乱。

具有多列表的另一件事是,具有150列的表的全表扫描当然比只有一半或更少的表的全表扫描慢。

最后一点是访问权限。使用单独的表,您可以对产品的主表和产品的物流表授予不同的权限。

总而言之,很少见到1:1关系,但是它们可以提供更清晰的数据视图,甚至可以帮助解决性能问题和数据访问。

编辑:我正在接受Mike Sherrill的建议,并(希望)弄清有关规范化的内容。

归一化主要是关于避免冗余和相关的一致性缺乏。是否只在一个表中保存数据还是在多个1:1相关表中保存数据的决定与此无关。您可以决定将一个用户表拆分为一个表,以存储个人信息(例如名字和姓氏),以及另一个表以供其学校,毕业和工作使用。由于没有比以前更多或更少的数据,所以两个表都将保持原始表的正常形式。唯一使用过两次的列是用户ID,但这不是多余的,因为在两个表中都需要用它来标识一条记录。

因此,询问“将设置标准化到一个单独的表中是否正确?”这不是一个有效的问题,因为您无法通过将数据放入与1:1相关的单独表中来规范化任何事情。


2
投票

创建具有1-1关系的新表不是一个合理的解决方案。您有时可能需要这样做,但是通常没有理由拥有两个表,其中用户ID是主键。

另一方面,将设置分成一个单独的表,每个用户/设置组合一行,可能是一个好主意。这将是一个三表解决方案。一种用于用户,一种用于所有可能的设置,一种用于它们之间的连接表。

联结表可能非常有用。例如,它可能包含设置的生效日期和结束日期。

但是,从SQL的意义上讲,这些设置彼此“相似”。如果设置不同,例如:

  • 首选位置为纬度/经度
  • 首选在一天中的时间接收电子邮件
  • 标记将从某些联系人中排除

然后将它们存储在表中时,就会遇到数据类型问题。因此,答案是“取决于”。很多答案取决于设置的外观,使用方式以及对它们的约束类型。


0
投票

通常不练习将表拆分为具有1:1关系的不同表,因为:

如果关系是really 1:1,则完整性强制归结为“在所有相关表中插入,或根本没有插入”。要在服务器端实现这一点,就需要支持延迟约束检查的系统,而AFAIK是高端系统的功能。因此,在许多情况下,1:1强制实施被推到了应用程序一侧,这种方法有其明显的缺点。

尽管如此,建议还是在有安全性的情况下(即并非所有用户都可以更新所有列的情况下拆分表)。但是请注意,根据定义,在这种情况下,表之间的关系永远不能严格 1:1。

((我还建议您仔细阅读[[认真地]])Thorsten / Mike之间的讨论。您使用了“规范化”一词,但规范化与您的情况几乎没有关系-除非您考虑使用6NF,否则我认为是不太可能。)


0
投票
你们都错了:)开玩笑。

-1
投票
UserSettings
© www.soinside.com 2019 - 2024. All rights reserved.