设计具有多个用户角色的数据库

时间:2014-12-23 18:15:26

标签: sql ruby-on-rails ruby-on-rails-4 database-design

我们中的许多人可能遇到过这种情况。我想构建一个支持多个用户角色的应用,并且不想在该过程中使用宝石。

我有4种类型的用户:

Admin
Teacher
Student
Librarian

Admin很简单,他只需要两列,usernamepassword。开头的用户表仅包含以下值:

username, password, admin, teacher, student, librarian

admin, teacher, student, librarian是布尔值,用于定义用户是否具有特定角色。管理员将admintrue,其他所有列均为false。

当我们引入仅特定于一个角色的其他列时,问题就出现了。我们为用户表提供了以下列:

id
username
password
admin
teacher
student
librarian
teacher_column1
teacher_column2
teacher_column3
student_column1
student_column2
student_column3
etc...

创建用户时,我们需要使用空值填充许多列。如果我们创建一个教师,只有图书管理员和学生需要的所有列都填充空值。

在人们问起这个问题的几个地方,他们被建议做STI,所以他们会以这样的结局结束:

class User < ActiveRecord::Base

end

class Admin < User

end

class Teacher < User

end

class Student < User

end

这看起来好多了,但仍会引入很多空值。

其他想法是为不同的用户类型细节引入4个新表。像这样:

用户表:

id
username
password
admin
teacher
student
librarian

教师表:

user_id
teacher_column1
teacher_column2
teacher_column3

学生表:

user_id
username
password
student_column1
student_column2
student_column3

对于图书管理员和管理员来说也是如此。在检查角色后的用户创建过程中,将创建该用户的特定表中的新行。

您如何看待这最后一种方法?缺点和优点?

这是创建具有多个用户角色的系统的正确方法吗?谢谢。

1 个答案:

答案 0 :(得分:4)

不要为每个权限使用不同的列。

为具有以下列的用户创建一个表:

username
password
user_type

user_type将是%w{admin teacher student librarian}中的值,然后使用您在帖子中提到的单表继承。

为Role创建一个表:

name

然后创建一个表格以将角色与用户联系起来:

role_id
user_id

为Permission创建一个表:

name

然后创建一个表以将权限绑定到角色:

permission_id
role_id

最后你会得到:

  • 包含表格的3个模型:UserRolePermission

  • 4个没有表格的模型,从User开始:AdminTeacherStudentLibrarian

  • 2个没有型号的表:users_rolesroles_permissions

此外,如果有许多列对每个用户类型都是唯一的,那么我建议为每个用户使用不同的模型+表格,并使user成为Role多态。

通过这种方式,您可以轻松创建新角色/权限,修改特定角色的权限,以及轻松添加/删除特定用户的角色。