我有两个表operation,并source在mysql数据库中.
在operation我有10行(可能性)和source只有3行(可能性)和它们之间有一种many-to-many关系.
问题:是否需要添加此额外表或只添加sourcein 的外键operation.
operation 可以订阅请求,订阅启用,订阅禁用,订阅取消,付款确定,订阅交易确定,订阅开始.
source 可以来自互联网,来自代理商
来源有共同的操作和独立的操作.
操作subscribe enabled可以通过互联网订阅或代理订阅和操作来完成:subscribe deal ok可以只是来自代理商,subscribe request也可以来自互联网.
在关系数据库中,您需要3个表来建立多对多关系.两个包含主键和连接表.别无他法.
对于简短而简短的回答,通常,对于像mysql这样的rdbms,只支持一对多关系,你需要第三个(交叉或交叉引用)表来实现两者之间的多对多关系.实体.
但....
既然你没有太多记录,你可以映射之间的许多一对多的关系source,并operation与只有一个附加列中source,并没有多余的数据存储.但是,您可能会失去一些性能(例如:不那么强大的索引),并且肯定会让您的生活更难以使用这些表...
诀窍是使用特定的二进制值作为operation表中的主键值,并将一个整数列添加到source表中,在该表中使用其位来映射关系.因此,本专栏的一部分描述了实际源记录与相应操作记录之间的一种关系.
对于样本operation表,您可以使用bit类型的pri键创建一个表,其大小等于您的估计行数.你说你将有~10行,所以bit(10)用作数据类型.因为,mysql会将int存储在4个字节上,所以你不会在这里放松存储大小(相反,与int相比,你可能实际上赢了一些,但实际上这是dbe如何能够压缩记录的问题.实际上,如果你愿意的话,你也可以简单地使用int.)
create table operation (id bit(10) primary key, title varchar(50));
insert into operation values (b'0', 'none');
insert into operation values (b'1', 'subscribe request');
insert into operation values (b'10', 'subscribe enabled');
insert into operation values (b'100', 'subscribe disabled');
insert into operation values (b'1000', 'subscribe canceled');
insert into operation values (b'10000', 'payment ok');
insert into operation values (b'100000', 'subscribe deal ok');
insert into operation values (b'1000000', 'subscribe start');
Run Code Online (Sandbox Code Playgroud)
现在,假设您的源表中包含以下内容:
create table source (id int primary key, value int, operations bit(10));
insert into source values (1, 1, b'0');
insert into source values (2, 2, b'1'); -- refers to subscribe request
insert into source values (3, 3, b'10'); -- refers to subscribe enabled
insert into source values (4, 4, b'10011'); -- refers to payment ok, subscribe request, subscribe enabled
insert into source values (5, 5, b'1110011'); -- refers to subscribe deal ok, subscribe start, payment ok, subscribe request, subscribe enabled
Run Code Online (Sandbox Code Playgroud)
现在,如果要选择所有关系,请按以下方式连接这两个表:
select source.id, operation.title
from source
join operation
on (source.operations & operation.id);
id operation.title
2 subscribe request
4 subscribe request
5 subscribe request
3 subscribe enabled
4 subscribe enabled
5 subscribe enabled
4 payment ok
5 payment ok
5 subscribe deal ok
5 subscribe start
Run Code Online (Sandbox Code Playgroud)
如果要添加新关系,可以利用insert 的on duplicate key update子句,因此您不必担心现有关系:
insert into source (id,value,operations)
values (2,2,(select id from operation where title = 'subscribe start'))
on duplicate key update operations = operations
| (select id from operation where title = 'subscribe start');
Run Code Online (Sandbox Code Playgroud)
如果要删除关系:
update source set operations = operations
& ~(select id from operation where title = 'subscribe start') where source.id=2;
Run Code Online (Sandbox Code Playgroud)
总而言之,它不是一个好的,但可能是将多对多关系映射到两个表的可能方式.