2012-12-06 77 views
9

我有4种类型的用户,都有具体的数据,但他们也分享COMMUN数据,如usernamepassword ..关系数据库设计多种用户类型

我首先想到的是创建一个主usersuser_type栏。然后,当查询用户数据时,我可以先选择他们的user_type,然后根据output运行不同的查询来获取“用户类型”特定数据。 我不喜欢这个,因为我希望我可以用一个查询并理想地使用外键来获取所有用户相关的数据。

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

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

非常感谢

+0

如果我理解你,你只需要在你的SQL语句中使用JOIN子句。类似于'SELECT * FROM users U LEFT JOIN user_details D ON U.id = D.user_id WHERE U.id =?' –

+0

用户可以一次有多种类型吗? –

+0

@Catcall否在这种情况下,用户只能有一种类型,但我很好奇在这两种情况下有什么可能性 – silkAdmin

回答

14

您的情况看起来像是类/子类的实例。

有两种经典的方法来设计SQL表来处理子类。各有优点和缺点。

单程被称为“单表继承”。在这个设计中,所有类型的用户都只有一张桌子。如果给定的列不属于给定的行,则交集保留NULL。可以添加一列来指示用户类型。

另一种称为“类表继承”的方法。这很像Nanego给出的答案,只做了一些小的改动。有一个用户表,包含所有常用数据和一个id字段。每个子类都有一个表,其中的数据与该子类相关。 id字段通常设置为用户表中匹配行中id字段的副本。通过这种方式,子类密钥可以执行双重任务,充当引用用户表的主键和外键。这最后一项技术被称为“共享主键”。它在插入时需要一点编程,但它非常值得。它强化了这种关系的一对一性质,并加速了必要的联结。

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

+2

感谢您放弃这些条款,使用Google搜索并已经学到了很多东西 – silkAdmin

0

我的方式来做到这本来是创建一个表“人”与普通的字段,以及用于与外键“为person_id”每种类型的用户一个表。

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

你有几种类型的用户?

+0

4但我想保持这种灵活性。我提到的第二种解决方案其实就是你所建议的。 – silkAdmin

2

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

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

如果你得到另一个用户类型,它也很容易扩展 - 添加列比添加表要容易得多,而且当你添加更多的用户类型时,新列的需求会减少t关于用户需要存储的许多不同的东西)

+2

我不喜欢这个,因为它只是觉得马虎,但它确实是事实。 –

+0

我同意,这将使代码更清洁,以避免连接,但我希望有与PHP类匹配的表,它只是会感觉更优雅 – silkAdmin

+1

另外我看到一个缺点是,该表松散的完整性,因为我必须使所有可以导致后端代码错误的字段为空。 – silkAdmin