- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 sql 的新手,我想在这里遵循这个例子: http://net.tutsplus.com/tutorials/php/a-better-login-system/
所以问题的要点是,
权限
角色
可以拥有多个权限
用户
可能有多个角色
和多个权限
数据库表如下:
权限
角色
用户
role_permissions
user_roles
和user_permissions
下面是创建表格的代码:
CREATE TABLE "permission" (
"id" SERIAL PRIMARY KEY,
"permission_key" VARCHAR(32) NOT NULL UNIQUE,
"permission_name" VARCHAR(32) NOT NULL);
CREATE TABLE "role" (
"id" SERIAL PRIMARY KEY,
"role_name" varchar(32) NOT NULL);
CREATE TABLE "role_permissions" (
"id" SERIAL PRIMARY KEY,
"role_id" INTEGER NOT NULL,
"permission_id" INTEGER NOT NULL,
"value" BOOLEAN NOT NULL DEFAULT FALSE,
"created_date" DATE NOT NULL,
UNIQUE ("role_id","permission_id"));
CREATE TABLE "user" (
"id" SERIAL PRIMARY KEY,
"username" VARCHAR(32) UNIQUE);
CREATE TABLE "user_permissions" (
"id" SERIAL PRIMARY KEY,
"user_id" INTEGER NOT NULL,
"permission_id" INTEGER NOT NULL,
"value" BOOLEAN NOT NULL DEFAULT FALSE,
"created_date" DATE NOT NULL,
UNIQUE ("user_id","permission_id"));
CREATE TABLE "user_roles" (
"id" SERIAL PRIMARY KEY,
"user_id" INTEGER NOT NULL,
"role_id" INTEGER NOT NULL,
"created_date" DATE NOT NULL,
UNIQUE ("user_id", "role_id"));
我希望能够在一条sql语句中写出如下内容:
“为我找到 ROLE
的所有 PERMISSIONS
,其 NAME
是 ________
”
“为我找到用户
的所有PERMISSIONS
,其NAME
是________
”
我知道我可以使用 ID 来匹配所有内容,但我想改用名称,因为对我来说“找到用户 x 的所有权限”更有意义
另外,对于第二个问题,请注意用户可以通过两种方式获得权限:
User > Role > Permission
User > Permission
为了简洁起见,我更愿意在单个语句中获得结果。
此外,如果有人知道如何将其翻译成 Korma查询,我将非常感激。
最佳答案
我不得不做出一些选择。如果同时存在用户和角色权限,则以用户权限为准。我把user和role换成了zuser和zrole,因为他们是postgres中的保留字,我不喜欢引用。该查询在其当前形式下不是很容易理解,但它似乎有效。数据是虚构的。
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path='tmp';
CREATE TABLE permission
( id SERIAL PRIMARY KEY
, permission_key VARCHAR(32) NOT NULL UNIQUE
, permission_name VARCHAR(32) NOT NULL
);
INSERT INTO permission(id,permission_key, permission_name) VALUES
(1, 'Eat', 'Eat' ) , (2, 'Drink', 'Drink' )
,(3, 'Shit', 'Shit' ) , (4, 'Urinate', 'Urinate' )
;
CREATE TABLE zrole
( id SERIAL PRIMARY KEY
, role_name varchar(32) NOT NULL
);
INSERT INTO zrole(id, role_name) VALUES
(1, 'Manager'), (2, 'Employee'), (3, 'Client') , (4, 'Visitor')
;
CREATE TABLE zuser
( id SERIAL PRIMARY KEY
, username VARCHAR(32) UNIQUE
);
INSERT INTO zuser(id, username) VALUES
(1, 'Jan Kees de Jager'), (2, 'Wildplasser'), (3, 'Joop') , (4, 'Mina')
;
CREATE TABLE role_permissions
( id SERIAL PRIMARY KEY
, role_id INTEGER NOT NULL REFERENCES zrole(id)
, permission_id INTEGER NOT NULL REFERENCES permission(id)
, created_date DATE NOT NULL
, value BOOLEAN NOT NULL DEFAULT FALSE
, UNIQUE (role_id,permission_id)
);
INSERT INTO role_permissions( id, role_id, permission_id, created_date, value) VALUES
(1,1,1, '2012-01-01', True )
,(2,1,2, '2012-01-01', False )
,(3,2,2, '2012-01-01', True )
,(4,2,3, '2012-01-01', False )
,(5,2,4, '2012-01-01', True )
,(6,3,2, '2012-01-01', True )
,(7,3,3, '2012-01-01', True )
,(8,3,4, '2012-01-01', True )
,(9,4,2, '2012-01-01', True )
,(10,4,3, '2012-01-01', True )
,(11,4,4, '2012-01-01', True )
;
CREATE TABLE user_permissions
( id SERIAL PRIMARY KEY
, user_id INTEGER NOT NULL REFERENCES zuser(id)
, permission_id INTEGER NOT NULL REFERENCES permission(id)
, created_date DATE NOT NULL
, value BOOLEAN NOT NULL DEFAULT FALSE
, UNIQUE (user_id,permission_id)
);
INSERT INTO user_permissions( id, user_id, permission_id, created_date, value) VALUES
(1,1,1, '2012-01-01', False )
,(2,1,2, '2012-01-01', False )
,(3,2,2, '2012-01-01', True )
,(4,3,2, '2012-01-01', True )
,(5,4,1, '2012-01-01', True )
;
CREATE TABLE user_roles
( id SERIAL PRIMARY KEY
, user_id INTEGER NOT NULL REFERENCES zuser(id)
, role_id INTEGER NOT NULL REFERENCES zrole(id)
, created_date DATE NOT NULL
, UNIQUE (user_id, role_id)
);
INSERT INTO user_roles (id, user_id, role_id, created_date) VALUES
(1,1,1, '2010-01-01' )
,(2,2,2, '2010-01-01' )
,(3,3,4, '2010-01-01' )
,(4,4,3, '2010-01-01' )
-- uncomment the next line to add a duplicate role
-- ,(5,2,4, '2010-01-01' )
;
WITH lutser AS (
SELECT up.user_id AS user_id
, up.permission_id AS permission_id
, up.value AS uval
FROM user_permissions up
)
, roler AS (
SELECT
ur.user_id AS user_id
, rp.permission_id AS permission_id
, rp.value AS rval
FROM user_roles ur
JOIN role_permissions rp ON rp.role_id = ur.role_id
)
SELECT us.username
, pe.permission_name
, pe.id AS permission_id
, lu.uval AS uval
, ro.rval AS rval
, COALESCE(lu.uval , ro.rval) AS tval
FROM lutser lu
FULL JOIN roler ro ON ro.user_id = lu.user_id
AND ro.permission_id = lu.permission_id
JOIN zuser us ON us.id = COALESCE(lu.user_id ,ro.user_id)
JOIN permission pe ON pe.id = COALESCE(ro.permission_id , lu.permission_id)
;
结果:
username | permission_name | permission_id | uval | rval | tval
-------------------+-----------------+---------------+------+------+------
Jan Kees de Jager | Eat | 1 | f | t | f
Jan Kees de Jager | Drink | 2 | f | f | f
Wildplasser | Drink | 2 | t | t | t
Wildplasser | Shit | 3 | | f | f
Wildplasser | Urinate | 4 | | t | t
Joop | Drink | 2 | t | t | t
Joop | Shit | 3 | | t | t
Joop | Urinate | 4 | | t | t
Mina | Eat | 1 | t | | t
Mina | Drink | 2 | | t | t
Mina | Shit | 3 | | t | t
Mina | Urinate | 4 | | t | t
(12 rows)
顺便说一句:上面的查询仍然不正确。如果一个用户属于多个角色,则查询将为该用户生成多行。角色子查询需要添加distinct/max()。
更新:为了解决每个人的重复角色问题,我创建了这个双重嵌套的 CTE:
WITH lutser AS (
WITH aggr AS (
WITH rope AS (
SELECT DISTINCT
ur.user_id AS user_id
, rp.permission_id AS permission_id
, rp.value AS value
FROM user_roles ur
JOIN role_permissions rp ON rp.role_id = ur.role_id
GROUP BY ur.user_id , rp.permission_id , rp.value
)
SELECT user_id,permission_id, value
FROM rope yes
WHERE yes.value = True
UNION ALL
SELECT user_id,permission_id, value
FROM rope nono
WHERE nono.value = False
AND NOT EXISTS (SELECT * FROM rope nx
WHERE nx.user_id= nono.user_id
AND nx.permission_id= nono.permission_id
AND nx.value = True
)
)
SELECT COALESCE(up.user_id , ag.user_id) AS user_id
, COALESCE(up.permission_id , ag.permission_id) AS permission_id
, up.value AS uval
, ag.value AS rval
FROM user_permissions up
FULL JOIN aggr ag ON ag.user_id = up.user_id AND ag.permission_id = up.permission_id
)
SELECT us.username
, pe.permission_name
, lu.uval AS uval
, lu.rval AS rval
, COALESCE(lu.uval , lu.rval) AS tval
FROM lutser lu
JOIN zuser us ON us.id = lu.user_id
JOIN permission pe ON pe.id = lu.permission_id
;
可以通过向 user_role 表添加/取消注释数据行 ,(5,2,4, '2010-01-01' )
来显示其功能。同样,我必须做出选择:如果一个用户存在两个角色,且真值相互冲突,则 True
获胜。我认为可以简化/美化查询,但至少它现在可以正常工作。
关于sql - 在访问控制列表中按名称查询记录(在 sql 和 korma 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11166131/
我有三张 table 。表 A 有选项名称(即颜色、尺寸)。表 B 有选项值名称(即蓝色、红色、黑色等)。表C通过将选项名称id和选项名称值id放在一起来建立关系。 我的查询需要显示值和选项的名称,而
在mysql中,如何计算一行中的非空单元格?我只想计算某些列之间的单元格,比如第 3-10 列之间的单元格。不是所有的列...同样,仅在该行中。 最佳答案 如果你想这样做,只能在 sql 中使用名称而
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 7 年前。 Improve this ques
我正在为版本7.6进行Elasticsearch查询 我的查询是这样的: { "query": { "bool": { "should": [ {
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 7 年前。 Improve this ques
是否可以编写一个查询来检查任一子查询(而不是一个子查询)是否正确? SELECT * FROM employees e WHERE NOT EXISTS (
我找到了很多关于我的问题的答案,但问题没有解决 我有表格,有数据,例如: Data 1 Data 2 Data 3
以下查询返回错误: 查询: SELECT Id, FirstName, LastName, OwnerId, PersonEmail FROM Account WHERE lower(PersonEm
以下查询返回错误: 查询: SELECT Id, FirstName, LastName, OwnerId, PersonEmail FROM Account WHERE lower(PersonEm
我从 EditText 中获取了 String 值。以及提交查询的按钮。 String sql=editQuery.getText().toString();// SELECT * FROM empl
我有一个或多或少有效的查询(关于结果),但处理大约需要 45 秒。这对于在 GUI 中呈现数据来说肯定太长了。 所以我的需求是找到一个更快/更高效的查询(几毫秒左右会很好)我的数据表大约有 3000
这是我第一次使用 Stack Overflow,所以我希望我以正确的方式提出这个问题。 我有 2 个 SQL 查询,我正在尝试比较和识别缺失值,尽管我无法将 NULL 字段添加到第二个查询中以识别缺失
什么是动态 SQL 查询?何时需要使用动态 SQL 查询?我使用的是 SQL Server 2005。 最佳答案 这里有几篇文章: Introduction to Dynamic SQL Dynami
include "mysql.php"; $query= "SELECT ID,name,displayname,established,summary,searchlink,im
我有一个查询要“转换”为 mysql。这是查询: select top 5 * from (select id, firstName, lastName, sum(fileSize) as To
通过我的研究,我发现至少从 EF 4.1 开始,EF 查询上的 .ToString() 方法将返回要运行的 SQL。事实上,这对我来说非常有用,使用 Entity Framework 5 和 6。 但
我在构造查询来执行以下操作时遇到问题: 按activity_type_id过滤联系人,仅显示最近事件具有所需activity_type_id或为NULL(无事件)的联系人 表格结构如下: 一个联系人可
如何让我输入数据库的信息在输入数据 5 分钟后自行更新? 假设我有一张 table : +--+--+-----+ |id|ip|count| +--+--+-----+ |
我正在尝试搜索正好是 4 位数字的 ID,我知道我需要使用 LENGTH() 字符串函数,但找不到如何使用它的示例。我正在尝试以下(和其他变体)但它们不起作用。 SELECT max(car_id)
我有一个在 mysql 上运行良好的 sql 查询(查询 + 连接): select sum(pa.price) from user u , purchase pu , pack pa where (
我是一名优秀的程序员,十分优秀!