数据库多对多关系中质数分解法的应用
质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数。
100以内的质数总共有25个
2、3、5、7、11、13、17、19、23、29、31、37、41、43、47、53、59、61、67、71、73、79、83、89、97
了解一下质数是什么以后开始讨论我遇到的一些问题。
1.需求介绍
简化一下需求,需要对一系列图片进行打标签并将结果记录在数据库当中,方便根据标签查询图片。请问怎么设计这个数据库表结构。
2.设计实现
标签和图片之间是一个多对多的关系,那么就需要三张表,标签表(Tag),图片表(Image)和标签图片关联表(ImgTagRes)。
CREATE TABLE `tag` (
`Id` int(11) NOT NULL,
`Name` varchar(255) ,
PRIMARY KEY (`Id`) USING BTREE
)
CREATE TABLE `image` (
`Id` int(11) NOT NULL,
`Name` varchar(255) ,
PRIMARY KEY (`Id`) USING BTREE
)
CREATE TABLE `imagetagres` (
`tagid` int(11) NOT NULL,
`imgid` int(11) NOT NULL,
PRIMARY KEY (`Id`) USING BTREE
)
#获取所有打了2标签的图片
select imgid from imagetagres where tagid = 2
#获取所有同时打了2和3标签的图片
select imgid from imagetagres where tagid in (2,3)
Group by imgid Having count(*) =2
那么有没有别的实现方式了呢?感觉表还是太多了,能不能把关联表给删除了,只要一个图片表一个标签表?
当然,不需要把标签Id拼接然后存放到图片表字段中的处理方式,毕竟也要保证查询时候的效率的。
3.质数分解法
当一个数字是由多个质数相乘而成的时候。如105=3 * 5 * 7
,那么对这个数字进行质因数分解,也只会由这几个数字构成。话说回来,这个理论如何应用在这个地方呢?
首先构建标签表的时候,++所有标签的Id都用质数替代(2、3、5、7....)
。同时在图片表中,新增一个Tag
字段记录给他打的所有标签的Id乘积。++
#获取所有打了2标签的图片
select ImgId from Image where Mod(Tag,2) = 0
#获取所有同时打了2和3标签的图片
select ImgId from Image where Mod(Tag,2*3) = 0
速度真的超级快。
质数相乘取代关联表的缺陷
1.质数乘积是有使用限制的,当多个质数相乘的时候,很容易一不小心就爆掉int.MaxValue
甚至是long.MaxValue
。
2.无法快速反向获取到数字是由哪几个质因数乘积构成的。(当然可以通过加字段记录下,或者维护一个质因数序列来分解质因数)
总结
不是所有的多对多关系都可以使用这种方式的,这里只是提供一个思路,在一些特定场景下可以采用这种方法。继续使用上面的标签来举这个例子:
1.标签数量是相对比较固定的,且个数不会很多。
2.对图片打标签的时候,有个数限制,尽量不要出现对一个图片打很多标签,导致最后的乘积超出int.MaxValue
的情况出现
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构