在关系型数据库中将用户表与人员表分离

11

我已经完成了许多Web应用程序,在这些应用程序中,第一件事情就是创建一个用户表格,其中包括用户名、密码、姓名、电子邮件和所有其他通常的杂项。我的当前项目提出了这样的情况,即非用户记录需要与用户类似地发挥作用,但不需要成为一级用户。

创建第二个表people_tb作为主要的关系表和数据存储是否合理,并且仅使用users_tb进行认证?将user_tbpeople_tb分离是否会带来任何问题?如果这是常见的做法,那么有哪些策略、解决方案以及缺点呢?

7个回答

10

这绝对是一个好主意,因为你在规范化数据库。我在正在编写的应用程序中做了类似的设计,其中有一个员工表和一个用户表。用户可以来自外部公司或员工,所以我有单独的表,因为员工总是用户,但用户不一定是员工。

你将遇到的问题是,每当使用用户表时,你几乎总是想获取人员表中的姓名或其他常用属性,以便显示出来。

从编码的角度来看,如果您使用纯SQL,就需要更多的精力来解析select语句。如果您使用ORM库,则可能会更加复杂。我对这些没有足够的经验。

在我的应用程序中,我正在使用Ruby on Rails编写它,所以我不断地在做像employee.user.name这样的事情,如果我把它们放在一起,只需写employee.name或user.name即可。

从性能方面来看,你要访问两个表而不是一个表,但是如果有适当的索引,这应该是可以忽略不计的。例如,如果你有一个包含主键和人名的索引,那么数据库将首先访问用户表,然后访问人员表上的索引(几乎直接命中),所以性能几乎与只有一个表相同。

你还可以在数据库中创建视图,将两个表连接起来以获得额外的性能增强。我知道在Oracle的后期版本中,甚至可以在视图上放置索引(如有需要)以提高性能。


3

我经常这样做,因为对我来说,“用户”(用户名、密码、创建日期、最后登录日期)的概念与“个人”(姓名、地址、电话、电子邮件)是不同的。你可能会发现其中一个缺点是,你的查询通常需要更多的连接才能获取所需的信息。例如,如果你只有一个登录名,你需要连接“people”表来获取名字和姓氏。如果你基于用户ID主键构建所有内容,这会减轻一些问题,但仍然会出现。


1
如果user_tb有认证信息,我会非常希望将其与people_tb分开。但是我会保持两者之间的关系,并且大多数用户信息将存储在people_tb中,除了所有用于认证所需的信息(我猜这些信息不会用于其他任何事情)。我认为这是设计和效率之间的一个不错的折衷方案。

1

这正是我们所做的,因为我们有数百万人员记录,但只有数千个用户。我们还将地址、电话和电子邮件分别存储在关系表中,因为许多人拥有多个这些信息。关键是不要依赖姓名作为标识符,因为姓名并不唯一。确保通过某种类型的代理键(最好是整数或GUID)而不是姓名连接表。


2
请注意,UUID(在 MS 中称为 GUID)在许多情况下实际上并不是很适合作为键,因为它们的随机性和大小会破坏索引机制。如果可能的话,最好使用简单的整数作为键。 - mr. w

0
我总是尽量避免数据重复。如果不是所有人都需要登录,你可以有一个通用的“people”表格,其中包含适用于人员和用户的信息(例如名字,姓氏等)。
然后对于登录的人,您可以有一个与“people”具有1~1关系的“users”表格。该表格可以存储用户名和密码。

0
我建议采用规范化设计(两个表),只有当在后续的开发中真正需要时,才将其非规范化(降至一个用户/人员表)。但是,如果几乎所有人都是用户,那么最好一开始就进行非规范化处理。这取决于你自己;我已经使用规范化方法而没有遇到问题。

0

非常合理。

例如,看看 aspnet_* 服务表 这里

它们内置的模式具有 aspnet_Usersaspnet_Membership,后者表格包含有关给定用户的更多扩展信息(哈希密码等),但是 aspnet_User.UserID 在模式的其他部分中用于引用完整性等。

总之,如果属性是不同的实体,则将其放在单独的表中非常常见且良好的设计,就像您的情况一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接