我目前正在开发我的第一个严重的网络应用程序(它是一个ERP系统)。我现在正在管理系统中的权限功能,并且我计划将权限与用户数据一起保存在用户表中。但我拥有超过70个可以授予用户的权限。在我的短暂体验之前,我从来没有遇到过这么大的桌子而且我不知道后来当我把系统投入生产时会有什么后果,我也知道如果我做错了我以后编辑应用程序会非常困难,所以我觉得如果我在开始之前就问过这个问题会很好。
可以像这样更换表吗
CREATE TABLE `user` (
`id` int(6) unsigned NOT NULL,
`name` varchar(70) NOT NULL,
`type` ENUM('admin','user'),
PRIMARY KEY (`id`)
)
并添加约70个这样的列
`p_insertSales` TINYINT(1) NOT NULL,
`p_insertPurchases` TINYINT(1) NOT NULL,
`p_insertCollections` TINYINT(1) NOT NULL,
`p_deleteSales` TINYINT(1) NOT NULL,
`p_deletePurchases` TINYINT(1) NOT NULL,
`p_manageInventory` TINYINT(1) NOT NULL,
`p_insertEntries` TINYINT(1) NOT NULL,
`p_manageAccountingSystem` TINYINT(1) NOT NULL,
`p_deleteEntries` TINYINT(1) NOT NULL,
`p_approveEntries` TINYINT(1) NOT NULL,
`p_seeFinancialReports` TINYINT(1) NOT NULL,
`p_seeLedger` TINYINT(1) NOT NULL,
`p_manageCashAccounts` TINYINT(1) NOT NULL,
`p_insertCurrentAccounts` TINYINT(1) NOT NULL,
`p_seeVisitorsMessages` TINYINT(1) NOT NULL,
`p_seePurchaseOrders` TINYINT(1) NOT NULL,
-- ... more than 60 more privileges.
在性能和软件设计方面可以吗?
因为我发现这样做对我来说更容易维护,因为我在前端控制器区域的请求处理开始时加载客户端数据无论如何我可以更改以后的权限(通过添加新的或删除)在一个地方。
答案 0 :(得分:8)
可能不是个好主意。你应该有一个每个权限有一行的表:
create table Privileges (
privilegeId int auto_increment primary key,
name varchar(255)
);
和一个联结表:
create table UserPrivileges (
userId int not null,
privilegeId not null,
constraint fk_UserPrivileges_userid foreign key (userid) references users(userid),
constraint fk_UserPrivileges_privileges id foreign key (privilegeid) references users(userid)
);
这些表可以包含其他列。例如,Privileges
可能包含有关该权限的其他信息。 UserPrivileges
可能包含插入/更新日期以及谁进行了更改。
这种结构可以很容易:
答案 1 :(得分:1)
另一种方法(可能更慢,可能更快,但肯定更紧凑):
以某种逻辑方式对权限进行分组。 (唯一必要的是将单个/fs/proc/stat.c
中的perms数量设置为低于64.)然后创建一个SET
已授予/拒绝的项目:
SET
或者,另一种方式(如果它更符合逻辑或简化应用程序编码):
CREATE TABLE ... (
user_id SMALLINT UNSIGNED NOT NULL,
insert_privs SET ('sales', 'purchases', 'collections', ...) NOT NULL,
delete_privs SET ('sales', 'purchases', 'collections', ...) NOT NULL,
...
(或任何有意义的事情)。
请参阅CREATE TABLE ... (
user_id SMALLINT UNSIGNED NOT NULL,
sales_privs SET ('insert', 'delete', ...) NOT NULL,
purchases_privs SET ('insert', 'delete', ...) NOT NULL,
...
作为测试正在设置的标记的便捷工具。
另见布尔运算符。