【问题标题】:Relational database design multiple user types关系型数据库设计多用户类型
【发布时间】:2012-12-06 17:52:12
【问题描述】:

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

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

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

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

非常感谢

【问题讨论】:

  • 如果我理解你,你只需要在你的 SQL 语句中使用一个 JOIN 子句。类似SELECT * FROM users U LEFT JOIN user_details D ON U.id = D.user_id WHERE U.id = ?
  • 一个用户可以同时属于多个类型吗?
  • @Catcall no 在这种情况下,用户只能拥有一种类型,尽管我很好奇这两种情况下的可能性是什么

标签: mysql database-design relational-database


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 感谢您放弃这些条款,用谷歌搜索并学到了很多
【解决方案2】:

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

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

它也很容易扩展,以防您获得其他用户类型 - 添加列比添加表要容易得多,并且随着您添加更多用户类型,对新列的需求会减少(只是没有你需要存储关于用户的许多不同的东西)

【讨论】:

  • 我不想赞成这个,因为它只是感觉草率,但它确实是事实。
  • 我同意这会使代码更简洁以避免连接,但我希望有与 PHP 类匹配的表,它会感觉更优雅
  • 我也看到了一个缺点,因为我必须使所有字段都可以为空,这可能导致后端代码中的错误。
【解决方案3】:

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

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

你有多少种用户?

【讨论】:

  • 现在 4,但我想保持灵活性。我提到的第二个解决方案实际上就是您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 2012-12-10
  • 2013-09-06
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多