zoukankan      html  css  js  c++  java
  • 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的记录集。

    这个算法的核心就是第一次要得到最小的记录集(也许保存为了最大化比对的数目),然后逐步将记录集变小,直到对准完成。

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4664083.html
Copyright © 2011-2022 走看看