我是SQL新手,请原谅我提出愚蠢的问题。我正在为大学项目创建我的第一个现实应用程序。
其核心是要处理成千上万的用户,除非给予特权,否则这些用户不应该能够互相读取或写入数据。就像Linux对用户和组一样。
在我尝试过的以下模式中,如果用户具有读取权限,则用户可以查看(读取)和编辑(写入)其他用户。(r = 2 w = 1 r + w = 3)。
例如,如果cgroup_1
是管理员,cgroup_2
是管理员,而unixperm
是32,则意味着管理员组中的用户可以读+写(3),而管理员组中的用户只能读(2)
create table cgroups
(
id int unsigned primary key auto_increment,
title varchar(100) not null unique,
cunixperm tinyint unsigned not null default 32 ,# r=2 w=1
cgroup_1 int unsigned not null default 1 references cgroups (id) on delete cascade on update cascade,
cgroup_2 int unsigned references cgroups (id) on delete cascade on update cascade
);
create table users
(
id int unsigned auto_increment primary key,
username varchar(255) not null unique,
cunixperm tinyint unsigned not null default 30, # r=2 w=1 3=r+w
cgroup_1 int unsigned default 1 not null references cgroups (id) on delete cascade on update cascade ,
cgroup_2 int unsigned references cgroups (id) on delete cascade on update cascade
);
create table many_users_in_many_cgroups
(
user_id int unsigned references users(id),
cgroup_id int unsigned references cgroups(id),
primary key (user_id,cgroup_id)
);
insert into cgroups(title)
values ('admins'),('managers'),('writers');
insert into users(username, cunixperm, cgroup_1, cgroup_2)
values ('user1',30,1,null),
('user2',30,1,2),
('user3',22,2,2),
('user4',02,3,3);
insert into many_users_in_many_cgroups
values (1,1),(2,2),(3,3),(4,4);
现在假设用户2已登录我的应用程序,我如何仅向用户显示其具有读取(2)或读取+写入(3)权限的行。
如果上面的模式不是(可能)合适,请给我一个带有合适方案的例子
我目前正在使用MariaDB,但也为其他人开放解决方案。
简单的答案是:访问部分的控件内置在应用程序中。
该机制必须位于SQL外部,因为SQL只能(通常)仅授予表级别的访问权限,而不授予行或列的访问权限。
关于如何精确编程,一种方法是这样。假设您有一个这样的数据表(我使用的是伪SQL,因为我不记得确切的Mysql语法):
Create table data (
rowid unique auto-increment,
datafield text);
Create table data_acl(
rowid foreign key references data (rowid),
cgroup references cgroups(id),
permissions int);
这假定所有用户都在某个cgroup中,因此要授予用户访问权限,您要授予cgroup访问权限。这使操作变得更容易,并且遵循每个用户都有自己的组的Unix理念。
您的用户表只需要列出用户名。
您的cgroups表仅需要列出用户和组。
Create table cgroups (
Id autoincrement int,
name);
Create table cgroup_users (
user_id foreign key references users(id),
cgroup_id foreign key references cgroups(id)
);
现在仅列出用户有权访问的所有数据行:
Select distinct datafield,acl.permissions from data d, data_acl acl, cgroups g
Where d.rowid=acl.rowid and acl.cgroup in (select distinct cgroup_id from cgroup_users where user_id=?)
对不起,请通过手机发布。