gpt4 book ai didi

mysql - 当默认情况下所有内容映射到所有内容时,多对多的正确设计

转载 作者:行者123 更新时间:2023-11-29 20:05:59 25 4
gpt4 key购买 nike

所以我通常使用连接表方法来实现 M2M。

但是我现在面临着大规模映射的麻烦(例如:默认情况下所有内容都映射到evreything)

因此,M 个对象将连接到 N 个对象,并且当创建新的 M 个对象时,将向该表添加新的 N 行(反之亦然)。

这种情况是我系统的默认行为,显然任何 M 都可以删除任何映射连接(反之亦然)。

我应该坚持“传统”联结表方法吗?或者有更好的设计模式吗?

一个例子是:
我有一个包含大量用户和文件的文件系统。
所有用户默认都可以查看所有文件,但管理员可以决定删除某些用户对某些文件的查看权限。

谢谢。

最佳答案

“全部到全部”关系是通过交叉联接完成的,为此您不需要联结表:

select * from M cross join N;

如果您还希望能够排除特定组合,则可以添加“连接”表并检查该组合是否不存在。在查询中可以使用多个选项来执行此操作(左连接不存在不在、...):

create table M (id int);
create table N (id varchar(1));
create table MN_excluded (idM int, idN varchar(1));

insert into M (id) values (1), (2), (3);
insert into N (id) values ('A'), ('B'), ('C');
insert into MN_excluded (idM, idN) values (2,'A'), (3,'B');

select * from M
cross join N
left join MN_excluded
on MN_excluded.idM = M.id and MN_excluded.idN = N.id
where MN_excluded.idM is null;

select * from M
cross join N
where not exists (
select 1 from MN_excluded
where MN_excluded.idM = M.id and MN_excluded.idN = N.id);

但请注意(在您的文件系统示例中)添加新用户将允许他完全访问所有内容。因此,如果您有一个文件 /etc/passwd 并为除 root 之外的所有 201 个现有用户定义了限制,则添加新用户将允许他访问该文件,除非您明确添加组合来否认它。在大多数现实世界的问题中,这种行为是不受欢迎的。

仍然“允许”组合但不要求您添加所有 M * N 组合的设计是使用(访问)组。你可以例如使用联结表 M_groupN_group,您可以在其中添加 MN 的每个条目一次(使用同一组ALL)以允许每个人完全访问。可以通过将一些文件和用户添加到组 ADMIN 中,并删除这些文件的组 ALL 来解决异常(exception)情况。如果您将这些关系之一(可能是"file"侧)设置为 1:1 关系,那么您甚至可以对所有表使用简单的join 来获取所有允许的组合;否则你将不得不使用 exists,因为用户和文件可能属于多个组,因此 join 可能会返回一些 (user, file)-组合多次。

这只是为了给您提供替代设计的想法。如果您确实只需要一个“全部到全部”关系(但有一些异常(exception)),那么交叉联接就是正确的选择。

关于mysql - 当默认情况下所有内容映射到所有内容时,多对多的正确设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40349372/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com