添加多对多表的默认配置

时间:2018-04-05 03:25:57

标签: mysql sql many-to-many ansi-sql

MySQL在这里。我有以下users表:

describe users;
+----------------------------------+---------------------+------+-----+---------+----------------+
| Field                            | Type                | Null | Key | Default | Extra          |
+----------------------------------+---------------------+------+-----+---------+----------------+
| user_id                          | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| user_status_id                   | bigint(20) unsigned | NO   | MUL | NULL    |                |
| profile_id                       | bigint(20) unsigned | YES  | MUL | NULL    |                |
+----------------------------------+---------------------+------+-----+---------+----------------+

我想知道在其中添加一个简单的RBAC模型:

  • 用户可以拥有0+角色
  • 角色拥有0+权限

我建议的表结构:

[roles] table
---
role_id : BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT
role_name : VARCHAR(50)

[permissions] table
---
permission_id : BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT
permission_name : VARCHAR(50)

[roles_x_permissions] many:many table
---
roles_x_permissions_id : BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT
role_id : BIGINT UNSIGNED FOREIGN KEY to [roles] table
permission_id : BIGINT UNSIGNED FOREIGN KEY to [permissions] table

[users_x_roles] many:many table
---
users_x_roles_id : BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT
user_id : BIGINT UNSIGNED FOREIGN KEY to [users] table
role_id : BIGINT UNSIGNED FOREIGN KEY to [roles] table

实际角色&应用程序支持的权限(至少最初):

INSERT INTO permissions (
  permission_name
) VALUES (
  'CanDoSomeBasicStuff'
);

INSERT INTO roles (
  role_name
) VALUES (
  'BasicUser'
);

INSERT INTO roles_x_permissions (
  role_id,
  permission_id
) VALUES (
  1,    // BasicUser
  1     // CanDoSomeBasicStuff
);

INSERT INTO users_x_roles (
  user_id,
  role_id
) VALUES (
  ???
);

我苦苦挣扎的是:默认情况下,所有现有用户都将拥有BasicUser角色。我需要一种优雅的方法在单个命令中将所有现有用户分配给此BasicUser角色,但我无法确定SQL命令需要的样子:

INSERT INTO users_x_roles uxr (
  user_id,
  role_id
) VALUES (
  ???,   # How to do this for each user record in the users table?
  ???    # How to fetch the correct role_id for the BasicUser role?
)

有什么想法这个SQL命令可能是什么样的?

2 个答案:

答案 0 :(得分:1)

INSERT ... VALUES语法会插入单个记录。您需要使用INSERT ... SELECT语法,如下所示:

INSERT INTO users_x_roles (
  user_id,
  role_id
)
 SELECT 
  user_id, 
  (SELECT MAX(role_id) FROM roles where role_name='BasicUser')
 FROM users;

或者,如果您不喜欢子查询:

INSERT INTO users_x_roles (
  user_id,
  role_id
)
 SELECT 
  u.user_id, 
  r.role_id 
 FROM users u CROSS JOIN roles r where r.role_name='BasicUser';

更新:输入错误是在INSERT语句中。我复制了您的代码并使用了如下语法:INSERT INTO users_x_roles uxr,这是无效的:您不能在Insert Into子句中使用别名。

现在一切正常。查看SQL Fiddle

答案 1 :(得分:0)

  

如何为users表中的每个用户记录执行此操作?

编写一个只选择一个用户的查询,例如:

SELECT user_id FROM users WHERE name = 'John'
  

如何为BasicUser角色获取正确的role_id?

编写一个只选择一个所需角色的查询,例如:

SELECT role_id FROM roles WHERE role_name='BasicUser'

最后以这种方式将这两个查询放入INSERT语句中(使用括号):

INSERT INTO users_x_roles uxr (
  user_id,
  role_id
) VALUES (
  ( SELECT user_id FROM users WHERE name = 'John' ) ,
  ( SELECT role_id FROM roles WHERE role_name='BasicUser' )
)