我为基于角色的访问控制设置了四个基本表:
CREATE TABLE roles (
role_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
role_name VARCHAR(20) NOT NULL,
valid ENUM('Y','N') DEFAULT 'Y',
PRIMARY KEY (role_id)
);
CREATE TABLE permissions (
perm_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
perm_desc VARCHAR(20) NOT NULL,
valid ENUM('Y','N') DEFAULT 'Y',
PRIMARY KEY (perm_id)
);
CREATE TABLE role_perm (
role_id INTEGER UNSIGNED NOT NULL,
perm_id INTEGER UNSIGNED NOT NULL,
valid ENUM('Y','N') DEFAULT 'Y',
FOREIGN KEY (role_id)
REFERENCES roles(role_id),
FOREIGN KEY (perm_id)
REFERENCES permissions(perm_id)
);
CREATE TABLE user_role (
user_id VARCHAR(20) NOT NULL,
role_id INTEGER UNSIGNED NOT NULL,
valid ENUM('Y','N') DEFAULT 'Y',
FOREIGN KEY (user_id)
REFERENCES users(user_id),
FOREIGN KEY (role_id)
REFERENCES roles(role_id)
);
现在说我要删除一个特定的角色以及与之相关的所有关联。我可以单独执行每个查询:
$sql = "UPDATE roles
SET valid = 'N'
WHERE role_id = :role_id";
$sql2 = "UPDATE user_role
SET valid = 'N'
WHERE role_id = :role_id";
$sql3 = "UPDATE role_perm
SET valid = 'N'
WHERE role_id = :role_id";
如果找到role_id
,此代码将执行第一个查询 ,同样执行其他查询。
我想知道的是,如果我可以将所有三个查询组合成一个具有完全相同结果的语句,例如(我认为这不会起作用):
$sql = "UPDATE roles, user_role, role_perm
SET roles.valid = 'N', user_role.valid = 'N', role_perm.valid = 'N'
WHERE roles.role_id = :role_id AND user_role.role_id = :role_id AND role_perm.role_id = :role_id";
或者,我最好将查询分开/使用某种类型的JOIN?
答案 0 :(得分:1)
虽然以下内容在MySQL中有效,但我怀疑你真的想要扩展你的FOREIGN KEY引用并阅读ON UPDATE CASCADE ......
UPDATE roles r
JOIN user_role ur
ON ur.role_id = r.role_id
JOIN role_perm rp
ON rp.role_id = r.role_id
SET r.valid = 'N'
, ur.valid = 'N'
, rp.valid = 'N';
答案 1 :(得分:0)
您显然没有测试的最后一个查询应该可以正常工作。
作为旁注:我认为有比枚举更好的选项来表示布尔值('Y'/'N')。您可以通读这个主题,看看哪个对您有好处:Which mysql datatype to use for storing boolean values