数据库中权限表的设置
今天被分配到看权限表也就是平常我们所说的,User表,Role表以及User_Role表,今天碰到的问题是:
1.以前从未在数据库设计中见过的数据类型
1.bit数据类型,以前在数据库中真的没用到过,只是知道这是一个比特位能够表示的值有0或者1,但是
数据库中式这么显示的
字段'status' 就是bit类型存储的时候他会被标记为b'1',学习到了,存储的时候正常存储就可以,下
面我把表结构以及Sql贴出来
CREATE TABLE t_bit ( id INT PRIMARY KEY, NAME VARCHAR(30), STATUS BIT, -- 主要是为了测试后面这个东西 address VARCHAR(30) ) INSERT INTO t_bit(NAME,STATUS,address) VALUES('小白',1,'哈尔滨');
2.下面我们来探讨下为什么要进行权限控制以及为什么要添加中间表
1.我们来看下不加中间表会出现哪些情况
我们需要分配的权限如下:
a.张飞 -----> 武将
b.关羽 -----> 武将,军师
c.赵云 -----> 武将,军师
d.马超 -----> 武将
我们看图以及对应关系就可以大概了解到
一个用户可能对应多个角色,就像上面的赵云既可以是武将又可以是军师(我感觉他比较足智多谋),同时,一个角色也可能被多个用户所具有
就像上面的军师这个角色,可以张飞,关羽,赵云等角色所拥有,他们的关系就是 多对多的关系M:N(我们用 M:N 来表示多对多的关系).
2.1下面我们来尝试下在M:N的情况下,建立两张表会发生什么
首先,我们来建立两张表 User表与Role表
CREATE TABLE USER( userid INT PRIMARY KEY, NAME VARCHAR(30), roleid INT ) CREATE TABLE role( roleid INT PRIMARY KEY, NAME VARCHAR(30), userid INT ) -- 看看表结构对不对,之后分别将 user表的userid 和 role表的roleid分别改为 主键自增 SELECT * FROM USER; SELECT * FROM role; -- 构造出上面所叙述的用户所对应的角色 -- insert into USER(name,roleid) 出现的第一种小情况: 名义上的外键不存在,我们> 也可以以后在添加这个roleid这个字段 INSERT INTO USER(NAME) VALUES('张飞'); INSERT INTO USER(NAME) VALUES('关羽'); INSERT INTO USER(NAME) VALUES('赵云'); INSERT INTO USER(NAME) VALUES('马超'); INSERT INTO role(NAME) VALUES('武将'); INSERT INTO role(NAME) VALUES('军师');
之后我们表里面的内容为如下所示:
+ 1.User表
- 2.Role表
2.2下面我们进行简单的分析
-- 写着写着发现了一个问题,不应该将userid放置到role表中,如果说像我这么设计的话,那么roleid就不 能作为主键去使用
-- 因为这样做的话,就起不到唯一标识的作用打个比方,在role表中roleid = 1可以代表武将可以是张飞,roleid = 2可以代表军师赵云,
-- 那么当我存储roleid = 3时 我想存关羽的时候,我该怎么去定义?无法去定义 解决的办法有两个 1. 将roleid当成非主键字段 2.建立关系关联表
-- 如果说采取第一种解决方法的话,那么第一种隐藏的问题也就解决了,那就是一个用户可能具有多个权限,只需要按上role表那样将userid字段设置成非主键,就可以了
-- 但是这样子存在一个问题:
-- 表的结构会变得很复杂很复杂约产生M*N条数据
2.3如何解决这个问题
我们可以添加一张中间表,在前面我们已经知道了,User于Role是 M:N的关系,那么我们就将关系变成这样M:1于N:1的关系,是这样的我们将User与Role的
两张表不变,添加一个中间表User_Role表
表结构如下:
分析下:建立中间表的好处以及为何会变成M:1以及N:1,就上面的实例进行分析,将结构进行分析
1.插入张飞以及其他角色的信息并且查找出来
INSERT INTO user_role(userid,roleid) VALUES(1,1); INSERT INTO user_role(userid,roleid) VALUES(2,1); INSERT INTO user_role(userid,roleid) VALUES(2,2); INSERT INTO user_role(userid,roleid) VALUES(3,1); INSERT INTO user_role(userid,roleid) VALUES(3,2); INSERT INTO user_role(userid,roleid) VALUES(4,1);
查询语句如下:
SELECT u.`name`,r.`name` FROM USER u LEFT JOIN user_role ur ON u.`userid` = ur.`userid` LEFT JOIN role r ON ur.`roleid` = r.`roleid`;
2.4 展示效果如下:
如果不动用中间表会产生的效果我们分析如下:
1.User表与Role表会多产生id,以及分别对应出roldid与userid的字段
2.需要产生大约M*N个条数据
3.表结构很垃圾(我也不知道怎么解释好)
动用了中间表的好处
1.当添加一个新的Role的话,我们只需要在Role表中添加字段,当User表中需要进行关系映射的时候我们仅仅需要在中间表中添加一条映射就好,
假设添加一个Role为"骠骑将军的角色",仅仅需要在user_role表表添加一条关系映射就好了,很方便。
可以自己按照代码仔细体会下,仅仅是看没什么用,领悟一下就明白了。