将用户和用户个人资料保留在不同的表中?


26

我在几个项目中看到,开发人员更喜欢将基本用户信息保留在一个表中(电子邮件/登录名,密码哈希,屏幕名称),而将其余非必需用户概要文件保留在另一个表中(创建日期,国家/地区等)。所谓非必需,是指仅偶尔需要此数据。明显的好处是,如果您使用的是ORM,则查询较少的字段显然是好的。但是,然后您可以将两个实体映射到同一表,这将使您免于查询不需要的内容(同时更加方便)。有人知道将这些东西放在两个表中还有其他好处吗?



1
@MichaelT谢谢!有趣的是,所有相关问题都没有达成共识。
2014年

这就是为什么我选择链接问题列表而不是尝试自己回答。它实际上归结为具体情况,以及如何构建特定的应用程序。请记住,如果需要,您始终可以使用视图将两个位拉在一起。还考虑取消一个链接(删除帐户)但保持另一个链接的可能性(问题需要链接到一个帐户,但是该帐户并不总是具有个人资料...)。抛入软件工程聊天室或直接进入DBA.SE并在他们的聊天室中提问可能是一个有趣的问题。

1
@MichaelT我正在考虑创建一种将提供用户模型的通用框架。
2014年

在过去的一些项目中,我故意将应经常写入其自己的表中的列移动,以保护主表,以防数据库文件损坏或损坏。
GrandmasterB

Answers:


11

这取决于项目的大小和要求。

我可以看到一种方法,可以将有关用户的数据分为两组,目的和需求不同:

  • 身份数据:用户名,密码哈希,电子邮件地址,上次登录时间等。
  • 用户个人资料数据,包括用户首选项,最新活动,状态更新等。

请注意,关于用户的某些属性可以归入任一类别(例如,用户的出生日期)。但这两组之间的区别在于,第一个是受到严格控制的,只有通过某些工作流程才能对其进行修改。例如,更改密码可能需要提供现有密码,更改电子邮件可能需要验证电子邮件,并且在用户忘记密码的情况下将使用此密码。

首选项不需要这种ACL,并且在理论上可以由用户或其他应用程序修改,只要用户同意即可。如果应用程序恶意或由于错误而破坏了数据或试图对其进行修改(假设采取了其他安全措施),则风险很小。但是,如果可以修改任何用户名,密码或电子邮件,通常将是灾难性的因为它们既可以用来假设用户的身份或拒绝服务,也可以导致管理员的支持费用等。

因此,通常将数据存储在两种类型的系统中:

  • 身份数据通常会放在目录或IAM解决方案中。
  • 首选项数据将最终存储在数据库中。

话虽如此,实际上,人们将违反这些规则,而使用其中一个规则(例如,ASP.NET成员资格提供程序后面的SQL Server)。

随着身份数据变大或使用它的组织变大,各种类型的问题也随之而来。例如,在目录的情况下,它将尝试将密码更改立即复制到多服务器环境中的所有服务器。但是,用户首选项只需要最终的一致性。(仅供参考:这两者都是CAPS定理的不同优化。)

最后,目录(尤其是联机/云目录)还将使用诸如OAUTH(例如Facebook,Google,Microsoft Account,ADFS)之类的协议为其他资源发出访问令牌,而数据库则无此需求。数据库将支持相当复杂的联接和查询结构,不需要该目录。

有关更多详细信息,对身份目录与数据库的一些搜索将有所帮助。

最终取决于您的方案是什么以及将来将要发生什么,包括与任何第三方(以及他们正在使用的)的集成。如果这是一个完备的项目,并且您确信可以保护用户身份数据并正确进行身份验证,则可以使用数据库。否则,可能值得研究身份目录。

如果您选择DB,那么使用一个DB而不是两个DB的IMO最终将归结为用户和应用程序的访问控制。


3

至少有三种情况需要具有基本属性的人员表和具有一对一关系的其他属性的第二个表:

  • BLOB数据就像一张图片。出于性能原因,单独的表允许将数据分别存储在例如单独的表空间中。
  • 不适用于所有人的数据或仅适用于扮演特定角色的人的数据。可以将其视为如果它们是主表的一部分,那么在许多行中为空的列。在诊所的数据库中,您可以有一个人员表,一个患者表和一个医疗表,在第一个数据库中,您将具有基本属性,在第二个数据库中,只有当该人是患者时才相关的属性,例如保险范围。第三张表(当此人是医务人员时),您可以拥有仅适用于医疗人员的医疗专业知识和其他数据。显然,医生可以成为患者。
  • 体现与远程系统中的实体的关系的表。在这种情况下,出于互操作性原因,该表在单独的数据库中的唯一标识符之间建立了对等关系。

我认为您公开的案例适合第二种情况。


1

我将它们分开的主要原因是尝试避免在面向对象编程中称为“神类”的东西。ORM将表和字段与类和属性相关联,因此它也与SQL级别相关(即使没有ORM,通常也有类似的原理在起作用)。

用户类(以及与用户表的关联)通常是成为上帝类的表,具有数百个属性/字段,数十种或数百种方法以及超过1000行的类定义(针对这些方法)。我都看过了 不止一次。

因此,与用户隔离会设法解决这一问题。可能会有人,用户,帐户,并且关注点的分离似乎有点人为的,但这是为了避免复杂性并确保每个对象仅关注数据的一个方面。


2
即使是user肿的用户阶层也不一定是上帝阶层。它可能会因与用户相关的逻辑而(肿(在大型项目中可能会变得复杂),但是如果不包含无关的逻辑,我就不会遇到大问题。我不确定将1类分成2类将如何解决所说的神类问题。
安德烈(Andrey)2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.