11

我有 4 种类型的用户,每一种都有特定的数据,但他们也共享公共数据,比如usernamepassword..

我的第一个想法是创建一个带有列的主users表。user_type然后在查询用户数据时,我可以先选择他们user_type,然后根据output运行不同的查询来获取“用户类型”特定数据。我不喜欢这个,因为我希望我可以通过一个查询获取所有与用户相关的数据,并且最好使用外键。

第二个想法是在表中没有user_type列,users而是使用来自特定用户类型表的外键将指向主users表的一行。我更喜欢这样,但我想我将不得不运行 N 个查询,其中 N 是每次我需要获取用户数据时的用户类型数。

还有其他选择吗?在这种情况下,好的做法是什么?

非常感谢

4

3 回答 3

22

您的案例看起来像类/子类的实例。

有两种经典的方式来设计 SQL 表来处理子类。每个都有优点和缺点。

一种方式称为“单表继承”。在此设计中,所有类型的用户都只有一个表。如果给定列不属于给定行,则交集为 NULL。可以添加一列来指示用户类型。

另一种方式称为“类表继承”。这很像 Nanego 给出的答案,只是做了一些小改动。有一个用户表,包含所有常见数据和一个 id 字段。每个子类都有一个表,其中包含与该子类相关的数据。id 字段通常设置为用户表中匹配行中 id 字段的副本。这样子类键就可以起到双重作用,既作为主键又作为引用用户表的外键。最后一种技术称为“共享主键”。它需要在插入时进行一些编程,但非常值得。它加强了关系的一对一性质,并加速了必要的连接。

您可以将所有这三种设计作为 SO 中的标签或作为网络上的文章查找。

于 2012-12-06T20:50:36.290 回答
5

虽然它更有效地利用了磁盘空间,但拆分成单独的表的问题是您实际上需要条件连接 - 基于 user_type 连接到用户类型特定的表。编写 SQL 代码是一件很痛苦的事情,而现在谁在乎磁盘空间?

更好的选择是让一个用户表具有足够的列来存储有关任何用户类型的信息,因为知道某些列不会用于某些用户类型。具有未使用列的“低效率”将在执行速度和查询简单性方面得到补偿。

它也很容易扩展,以防您获得另一种用户类型 - 添加列比添加表要容易得多,并且随着您添加更多用户类型,对新列的需求会减少(只是没有那么多不同关于您需要存储的用户的信息)

于 2012-12-06T18:17:27.967 回答
1

我的做法是创建一个包含公共字段的表“Person”,并为每种类型的用户创建一个表,并使用外键“person_id”。

在您的请求中,您只需使用 foreign_key 连接两个表,即可获取一种类型用户的所有数据。

你有多少类型的用户?

于 2012-12-06T18:08:04.610 回答