S关于使用QL声明 找出同时满足多个tag拍摄条件设置算法
表结构
Tag Table:{tag_id, tag_name} #标签表
News Table:{news_id, title,......} #新闻列表
NewsTags Table:{tag_id, news_id} #新闻的标签关系表
解释:
一条新闻,有多个tag标签,比如:
新闻a{Tag1,Tag2, Tag3, Tag4}
新闻b{Tag1,Tag6, Tag7, Tag8}
新闻c{Tag8,Tag9, Tag10, Tag1}
新闻...{Tag..., .....}
搜索出 同一时候有Tag1,Tag8两个标签的记录。
在MySQL中经过优化后的SQL:
SELECT News.title
FROM(
SELECT news_id
FROM (
SELECT tag_id
FROM Tag
WHERE tag_name IN('Tag1', 'Tag8')
)B LEFT JOIN NewsTags C (B.tag_id = C.tag_id)
GROUP BY news_id
HAVING COUNT(0)=2
)A LEFTJOIN News B ON(A.news_id = B.news_id)
原理:
此为3重嵌套SQL,可最大限度的高速缩小记录集。以最节省内存的方式得到结果集。
1、最内层取出须要比对的tag_id
2、第二层通过Left join联接,找出同一时候拥有这些tag_id的news_id记录;本处理的重点是对news_id做Group by然后在Having中统计出数量为2的news_id(即:同一时候存在这两个tag的记录)
3、最外层依据news_id(这个已经是终于的最小记录集),与News表Left Join求出新闻记录的内容
至此可得到 同一时候符合 多个Tag名称 的记录集的模板,依据查找的tag数量不同。需在最内层的IN(),与第二层的Having做參数改动就可实现对随意数量的Tag交集求解。
此算法并不是最优。可是假设想通过模板方式的一条SQL来实现,基本上这个算是最优的算法(本人愚见哈)。
这个算法的缺点是。假设每一个tag相应的记录集数量巨大,且给了非常多个Tag求交集。那么第二层的LeftJoin运算会消耗大量的内存空间(由于须要对每一个tag_id生成一个news_id的集合。实际上会先得到一个笛卡尔集,然后对这个集合做group,再count)。
假设想把效率与搜索内存资源消耗做极致大致。可做例如以下改动,思路例如以下。
1、改造Tag表,添加一个被引用的数量字段。比如:Tag Table:{tag_id, tag_name, links} (事实上能够把links看成一个人工索引)
2、维护这样的Tag表比較麻烦。考虑到效率。通常会定时的对links字段做全表更新(对于频繁插入或删除记录的news表。可每天临晨,对全记录集的tag做被引用的次数统计并更新links字段)
3、构造动态多层嵌套的SQL语句(即依据tag的数量,生成N层嵌套查询)
实现原理(SQL语句就不写了)
1、依据给定的tag_name找出tag_id,并按对links大小,升序排列
2、首先选取第一个tag_id到NewsTags表求NewsTags.tag_id的交集(此为最小基本记录集)得到news_id,然后对此记录集反复运行这个步骤(逐步缩小记录集),完毕全部tags的比对时就能在最小的范围内找出全部同一时候符合这些tag_id的记录集。
这个算法的核心就是第一次要得到最小的记录集(也许保存为了最大化比对的数目),然后逐步将记录集变小,直到对准完成。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
S关于使用QL声明 找出同时满足多个tag拍摄条件设置算法的更多相关文章
- 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...
- 排序练习——找出前m大的数字 分类: 排序 2015-06-08 09:33 21人阅读 评论(0) 收藏
排序练习--找出前m大的数字 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 给定n个数字,找出前m大的数字. 输入 多组输 ...
- Matlab.NET混编技巧之——找出Matlab内置函数
原文 http://www.cnblogs.com/asxinyu/p/3295309.html Matlab与.NET的混合编程,掌握了基本过程,加上一定的开发经验和算法基础,肯 定不难.反之,有时 ...
- [LeetCode]Palindrome Partitioning 找出所有可能的组合回文
给定一个字符串,切割字符串,这样每个子字符串是一个回文字符串. 要找出所有可能的组合. 办法:暴力搜索+回溯 class Solution { public: int *b,n; vector< ...
- 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 print-all-combinations-of-given-length
// 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 /* Input: set[] = {'a', 'b'}, k = 3 Output: aaa aab aba ...
- 例如找出令人信服的权威C++中间malloc与new
例如找出令人信服的权威C++中间malloc与new 问题: 非常多人都知道malloc与new都是用来申请空间用的,开辟空间来源于堆中. 可是在C++中却非常少用malloc去申请空间,为什么? 以 ...
- Matlab.NET混合编程技巧之——找出Matlab内置函数
原文:[原创]Matlab.NET混合编程技巧之--找出Matlab内置函数 Matlab与.NET的混合编程,掌握了基本过程,加上一定的开发经验和算法基础,肯定不难.反之,有时候一个小错误,可能抓破 ...
- Class 找出一个整形数组中的元素的最大值
目的:找出一个整形数组中的元素的最大值 以下,我们用类和对象的方法来做. #include<iostream> using namespace std; class Array_m ...
- 函数内this指向+排序+找出数组大小项+Math类
解决函数内this指向: 1,可以在函数外提前声明变量 _this/that = this 2,通过apply()和call()来修改函数内的this指向 二者区别: 用法是一样的,参数形式不一样 f ...
随机推荐
- hdu3501
要我们求小于n并且不与n互素的数字的和, 那么可以转化为1->(n-1)的和减去小于n且与n互素的数字的和 首先,有gcd(n,i)=1, 那么gcd(n,n-i)=1, 这是因为如果a%s=0 ...
- TP-LINK telnet远程 重启路由器(转)
突然断网,以前房东的路由器管理页面可以打开,今天突然间就打不开了.ping了下,可以ping通,于是就想起了房东的路由器是TP-LINK的 可以 telnet登陆的.每次,断网,我都会重启房东的路由器 ...
- WebView使用配置文件
录制webview示例使用,以免以后忘记. 布局文件: <WebView android:layout_width="fill_parent" android:layout_ ...
- IM设计与实现的系统模块的聊天记录
到非常多开发IM系统的朋友都想实现聊天记录存储和查询这一不可或缺的功能,这里我就把自己前段时间为傲瑞通(OrayTalk)开发聊天记录模块的经验分享出来,供须要的朋友參考下. 一.整体设计 1.存储位 ...
- c++分割字符串(类似于boost::split)
由于c++字符串没有split函数,所以字符串分割单词的时候必须自己手写,也相当于自己实现一个split函数吧! 如果需要根据单一字符分割单词,直接用getline读取就好了,很简单 #include ...
- setsockopt角色
功能描写叙述: 获取或者设置与某个套接字关联的选 项. 选项可能存在于多层协议中.它们总会出如今最上面的套接字层. 当操作套接字选项时.选项位于的层和选项的名称必须给出.为了操作套接字层的选项,应该 ...
- Android Java 与 C++ 恒调用,路径、文件名、延长的最大长度
/**************************************************************************** ********************* ...
- 【POJ】The Suspects(裸并查集)
并查集的模板题,为了避免麻烦,合并的时候根节点大的合并到小的结点. #include<cstdio> #include<algorithm> using namespace s ...
- UVa 11587 - Brick Game
称号:背景:brick game有N块,给你一个整数的定数S,两个人轮流木: 的木块数是集合S中存在的随意数字.取走最后木块的人获胜.无法取则对方获胜. 题干:如今让你先取,给你一个你的结果序列串T, ...
- BibTex (.bib) 文件的凝视
1) 将某个參考文献所有去掉,能够去掉前面的『@』 样例 @article{##, author = {###}, title = {###}, journal = {###}, ...