队伍里的小伙子这样设计表,应该怎么评价

2021 年 8 月 27 日
 sivl6p

项目里有几个多对多关系,需要表达到关系数据库。

比如:用户 角色 权限; 用户与角色是多对多关系;角色与权限是多对多关系;

一般人会分别创建 [用户角色表]、[角色权限表],来存储多对多关系,这个没啥好说的。

现在队伍里一个小伙子嫌麻烦,就创建了一张 [数据关系表],大致字段有:[第一个 id],[第二个 id],[表名]。

大家分析下,这种做法,要如何评价

16207 次点击
所在节点    程序员
106 条回复
mmdsun
2021 年 8 月 27 日
还有表名称? 关系数据库 Mysql 这种要怎么查询 ?
seakingii
2021 年 8 月 27 日
反直觉
不过就这个场景来说,是能满足要求的,也能扩展应用到所有这种简单多对多的其它表.数据量不大的话性能也不是问题
akira
2021 年 8 月 27 日
这样的优点是 少创建一个表,嗯。 应该就这个了吧
luckyc
2021 年 8 月 28 日
还行啊, 没啥毛病. 我更倾向于把所有配置全写一个表里面去.

```
CREATE TABLE `system_config` (
`id` mediumint UNSIGNED NOT NULL AUTO_INCREMENT,
`userid` char(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`module` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`section` char(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`key` char(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`value` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `unique`(`userid`, `module`, `section`, `key`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 2680 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
```
cp19890714
2021 年 8 月 28 日
谁最终为该系统负责,那就听谁的。当然,还是要以理服人,举例说明该方式在未来的隐患。
WilliamYang
2021 年 8 月 28 日
从业 6 年了,某些人总能找到说服你和他自己的理由。你不是他上级,能听就听,不听就算了
chih758
2021 年 8 月 28 日
不是本科毕业的?数据库的范式没学?
entro
2021 年 8 月 28 日
真实,本公司项目某模块的表就是老板亲自用这种方式设计的#(笑)
hst001
2021 年 8 月 28 日
数据量稍微多点,更新的时候就知道厉害了,后面让他再去拆表,长长教训
2i2Re2PLMaDnghL
2021 年 8 月 28 日
重新发明图数据库
把不同表(实际上就是不同的命名空间)的 id 放在一起,需要保证表间 id 仍然唯一(实质达成命名空间合并)。
这种情况下 MySQL 性能可能捉鸡
TimPeake
2021 年 8 月 28 日
套娃?
wqtacc
2021 年 8 月 28 日
看起来是把角色权限和用户角色写到了一个表里?那描述应该是下面这样子?

id1 | id2 | 表名
角色 id1| 权限 id1 | 用户权限表名 角色权限?
角色 id1| 权限 id2 | 用户权限表名 角色权限?
角色 id2| 权限 id1 | 用户权限表名
用户 id1| 角色 id1 | 用户角色表名
用户 id1| 角色 id2 | 用户角色表名
Biwood
2021 年 8 月 28 日
乍一看,还以为是什么数据库层面的高度抽象,专门存储表与表之间的关系?太高级了吧
看到“第一个 id”、“第二个 id”这里,有点懵逼了,这是用一个表解决整个系统的对应关系?有种用 0 和 1 写程序的感觉,按照这种写法,那数据库要“主键”、“外键”干嘛用
Biwood
2021 年 8 月 28 日
@avastms
我一开始也以为像是你说的邻接表,把数据之间的关系存储起来,但是你在细读一下楼主的描述跟他的回复,根本没那么高大上,他是反向操作,纯粹是把三张表之间两两排列组合,把每一条关系都存储在一个表里面。

打个比方,就像你本来可以用 for 循环打印 10 次数据,他偏偏不用 for 循环,而是硬写了 10 次打印数据的代码。
changdy
2021 年 8 月 29 日
原谅我..没 get 到点. 虽然这个操作的确不教条主义... 但是我觉得 还 ok 吧....


@l4ever 你这个就太过分了... 只是系统配置范畴的 可以.但是权限表什么的 就很不合适了.
encro
2021 年 8 月 29 日
没有问题,
其实 yii 框架的默认 rbac 差不多也是这么建立的。基于 NIST RBAC model,性能没有问题,且可以多级用户角色和权限继承。


DbManager 使用 4 个数据库表存放它的数据:

itemTable: 该表存放授权条目(译者注:即角色和权限)。默认表名为 "auth_item" 。
itemChildTable: 该表存放授权条目的层次关系。默认表名为 "auth_item_child"。
assignmentTable: 该表存放授权条目对用户的指派情况。默认表名为 "auth_assignment"。
ruleTable: 该表存放规则。默认表名为 "auth_rule"。


有个要求就是需要封装很好。
encro
2021 年 8 月 29 日
下面是表结构,可以不考虑 rule 表

create table `auth_rule`
(
`name` varchar(64) not null,
`data` blob,
`created_at` integer,
`updated_at` integer,
primary key (`name`)
) engine InnoDB;

create table `auth_item`
(
`name` varchar(64) not null,
`type` smallint not null,
`description` text,
`rule_name` varchar(64),
`data` blob,
`created_at` integer,
`updated_at` integer,
primary key (`name`),
foreign key (`rule_name`) references `auth_rule` (`name`) on delete set null on update cascade,
key `type` (`type`)
) engine InnoDB;

create table `auth_item_child`
(
`parent` varchar(64) not null,
`child` varchar(64) not null,
primary key (`parent`, `child`),
foreign key (`parent`) references `auth_item` (`name`) on delete cascade on update cascade,
foreign key (`child`) references `auth_item` (`name`) on delete cascade on update cascade
) engine InnoDB;

create table `auth_assignment`
(
`item_name` varchar(64) not null,
`user_id` varchar(64) not null,
`created_at` integer,
primary key (`item_name`, `user_id`),
foreign key (`item_name`) references `auth_item` (`name`) on delete cascade on update cascade,
key `auth_assignment_user_id_idx` (`user_id`)
) engine InnoDB;
kiracyan
2021 年 8 月 30 日
其实就是把多个 map 表合在一起了吧
wowbaby
2021 年 8 月 30 日
@encro yii2 rbac 虽然方便,权限一多,随便几十条 sql
blackshow
2021 年 8 月 30 日
@Casbin #79 casbin 在哪描述的数据库设计?没有找到

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/798305

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX