我有一个经典的用户表,其中包括以下数据
userid name userName email lastlogin
--------------------------------------------------------------
1 Buffer Stack s@overflow.com 1312565858
此外,我需要在每个用户的基础上保持设置。这些设置将主要涵盖布尔字段,可能看起来像这样。
quickSave showInfo showOnlineStatus sendNews sendRemainder
---------------------------------------------------------------------------
0 1 1 1 0
话虽如此,我至少看到了两个(通常的)选项
我构建事物的倾向使我成为后者。
对于拆分表是否是一种有效的方法,如果它们与上述严格一对一相关,如果是这样,是否存在阈值,何时这样做?
答案 0 :(得分:4)
我的偏好是我读取/写入活动的基础。
例如
如果你的用户表不经常写WRITEN但经常阅读,我会将它与设置表分开,这可能会更频繁地写入。
如果您使用myISAM表,因为它们具有表级锁定,这一点更为重要。 InnoDB使用行级锁定(但您仍然可以锁定整个表格)但仍然很高兴能够根据读/写频率选择移动存储
答案 1 :(得分:3)
我认为“它取决于”是唯一可以给出的完全真实的答案 - 问题有点像问“第6种正常形式比第5种正常形式好吗?”
单独表格的好处主要是灵活性:
- 能够以最小的影响进行设计更改
例如,您可能希望开始维护旧值和当前值,一切越不紧密,就越容易进行更改。
但最极端的版本是每个字段都有一个单独的表格。而且我看不到很多人暗示那会是一个好主意。特别是从可维护性的角度来看;它可能很灵活,但拥有十亿个表格远非易于理解。
关于何时使用单独表格的基本经验法则是逻辑上认为字段明显不同。有关用户(姓名,地址等)及其应用程序设置(快速保存等)的详细信息似乎足以满足我的要求。这可能无关紧要,但您可能会避免争用,其中一个进程正在尝试处理用户地址,另一个进程正在更新用户应用程序设置。
也就是说,如果您发现总是在数据可用之前将两个表连接在一起,那么它就是一个强有力的指标,它们不应该分开。我怀疑你可以通过在一个用户的登录详细信息中查找并加入另一个来使用这些表。
我个人的选择,从这个问题的狭隘角度来看? - 将它们放在一张桌子上 - 直到你找到不
的理由您可以随时将它们分开,并在视图中重新组合它们,以保持代码兼容性。
答案 2 :(得分:2)
我会选择第三种选择:
创建一个authentication
表,用于存储lastLogin
,userName
等信息,然后将所有这些列添加到user
表中。
此信息 描述用户,因此为了维护数据库实体,我会将列添加到user
表。
另一方面,如果在一个实体周围有一个明确定义的边界,你可以描述为settings
,那么一对一的关系就没有错。
答案 3 :(得分:2)
数据库理论可能会匆忙失控。答案是在做出决定时是合理的。
真的,硬核DBA会认为电子邮件不属于用户表,因为用户可能有多个....并且可能会改变....而且你可能必须保留历史......等等。实际上,这很愚蠢。如果您的应用只需要一个电子邮件地址,那么它适合您。关键是,做出这些决定不仅仅是理论。
同样,在实际操作中,您提出的任何解决方案都将起作用。没有人会在表现上产生显着的差异。如果是我,我可能会将其保存到一个单独的表中,该表具有包含其他UI元素的所有用户首选项。再次,这取决于您和您的需求。
答案 4 :(得分:2)
你需要权衡。您目前有一系列与用户一对一的关系。通过将它们保存在同一个表中,可以使查询更容易,但是当您想要添加另一个字段时更加困难。通过添加设置表,您可能会使数据更难查询,并可能根据设计创建性能噩梦。
您可以通过两种方式创建表,创建一个与用户一对一关系的表。如果您的用户表已经很宽并且在用户表的大多数查询中不需要这些设置,那么这很好。如果您现在的情况是1-1,那么这也可以是好的,但是您希望它们之后变为1-many。如果您需要添加新设置,则仍需要更改表格。
另一种方法是创建一个包含Userid,SettingType,Value之类的EAV表。这是一种非常差的存储查询大多数数据的方法。现在,您需要查询第一个表并多次连接到第二个表以获取所有数据,而不是查询一个表。你甚至可能不知道加入了多少次。这种结构应该谨慎使用,永远不要用于您事先需要的设置。它适用于客户定义的字段。然后只有你期望很少使用它。这是一个性能杀手。