0

我正在设计一个具有多种用户类型的数据库,即管理员、编辑、教师和学生。现在,所有这些用户都有一些公共字段 (CF) 和一些与他们关联的唯一字段 (UF)。我想知道这是不是一个好的设计?

表用户:[user_id (PK), CF1, CF2,..., CFN, user_type (enum)]

表管理员:[id (PK), UF_A1, UF_A2, ... , U_AN, user_id(FK)]

表编辑器:[id (PK), UF_E1, UF_E2, ... , U_EN, user_id(FK)]

表教师:[id (PK), UF_T1, UF_T2, ... , U_TN, user_id(FK)]

学生表:[id (PK), UF_S1, UF_S2, ... , U_SN, user_id(FK)]

其中 UF_A、UF_E、UF_T 和 UF_S 是每个相应表的唯一字段。

现在我的问题是:

  1. 这是一个好的设计吗?如果没有,你将如何设计它?
  2. 例如,如何确保 user_type 教师的用户不存储在学生表中?

PS:如果它们可能有助于获得更好的洞察力,请多加点:

  1. 该数据库将与 codeigniter 一起使用。
  2. CF 的示例是:用户名、密码、电子邮件、个人资料图片
  3. 唯一字段的示例包括:学生(年龄、注册号)、教师(大学名称、大学徽标、学位)
4

3 回答 3

1

您的设计是在关系数据库中建模继承关系的 3 种普遍认可的方法之一;其他是“每个表的类”,其中每个子类都有自己的完整表,或“一个表来统治所有表”,其中所有可能的列都位于一个表中。

其他替代方法是使用实​​体-属性-值或文档(例如 JSON 或 XML)来存储数据。

您的设计具有以下优点:

  • 一致性:共同的数据被一致地存储和管理;一旦您编写了密码规则,您就会知道它们将被应用到任何地方。
  • 可维护性:很清楚哪些数据存在于何处,并且它允许您对子类使用细微不同的实现(存储教师的姓名可能需要包含一个头衔——“博士”,存储学生的姓名可能不需要)。
  • 性能:在数据结构上运行关系查询应该很快(“查找所有 12 到 14 岁之间没有注册号的学生”);这在 EAV 或文档解决方案上会变得非常棘手。

缺点:

  • 创建一个新的子类可能需要创建一个新表(这是 EAV 和文档解决方案经常获胜的地方)。
  • 跨子类查询可能很棘手(“查找所有 1990 年之后出生或拥有斯坦福大学学位的用户”)。这就是“一张大桌子”经常获胜的地方。
  • 使用“标准”关系工具(如唯一键、外键等)不容易对某些关系进行建模 - 例如,您的“您是学生或教师,但不是两者兼而有之”的示例。您可以改用触发器或应用程序逻辑。
  • 多重继承——例如,一个用户可能既是编辑又是老师——可能会变得混乱。
于 2013-05-09T08:46:29.137 回答
0

您的设计 (Users.user_type) 意味着某个特定的人可以是管理员,或者该人可以是编辑器,但不能两者兼而有之。这也意味着教师不能成为编辑。那是你的意图吗?

Admin.user_id、Editors.user_id、Teachers.user_id、Students.user_id 列通常是您所描述的结构类型中的主键。如果 CodeIgniter 不允许你将它们设为主键,你仍然需要声明它们是唯一的。

唯一字段的示例是 . . . 教师(大学名称、大学标志、学位)

这可能不是真的。

例如,如何确保 user_type 教师的用户不存储在学生表中?

具有重叠约束、默认值、检查约束和外键引用。这比听起来容易。看到这个答案。但我不相信你真的想这样做。

于 2013-05-08T12:24:08.583 回答
0

您的设计说明了一种称为的设计技术。
此标签有一个概述该技术的信息选项卡。

正如信息所说,还有另一种可能有用的技术,即

于 2013-05-08T09:50:46.527 回答