代码之家  ›  专栏  ›  技术社区  ›  JD Isaacks

如何从标签创建临时表?

  •  0
  • JD Isaacks  · 技术社区  · 14 年前

    我有一个 product_table 用一个 product_id 在其他几个领域中。

    我正在创建一个 tag_table 有两个字段, tag_id tag_name .

    标签可以是“银色”或“宾夕法尼亚州”等。

    我也在创造一个 product_tag_map 带有的表 产品ID 塔吉德 以便将产品映射到任意数量的标签。

    如果我想创建一个包含所有标记为“银”、“项链”、“钻石”的产品的类别。但也不包括任何标记为“初始”、“旅程”的产品。

    (很明显,我会使用标记“id”而不是标记“name”,所以带有标记[2,4,5]的产品没有标记[3,6])

    A如何创建临时产品表并用匹配的产品填充它?

    更新

    这是我的产品标签地图表:

    CREATE TABLE `product_tag_map` (
     `product_tag_map_id` int(11) NOT NULL auto_increment,
     `tag_id` int(11) NOT NULL,
     `product_id` int(11) NOT NULL,
     PRIMARY KEY  (`product_tag_map_id`),
     UNIQUE KEY `tag_id` (`tag_id`,`product_id`),
     KEY `tag_id_2` (`tag_id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=7897 DEFAULT CHARSET=utf8
    

    注意:我没有使用 product_tag_map_id 为了任何事。我只是习惯于给每张桌子一个这样的主键。所以如果我把它取下来就好了。

    2 回复  |  直到 12 年前
        1
  •  1
  •   Tomalak    14 年前

    问题是,你需要什么样的临时表 对于 ?为什么不直接查询呢?

    SELECT
      p.product_id,
      p.product_name
    FROM
      product_table p
    WHERE
      EXISTS (
        SELECT 1 
          FROM product_tag_map 
         WHERE product_id = p.product_id AND tag_id IN (2,4,5)
      )
      AND NOT EXISTS (
        SELECT 1 
          FROM product_tag_map 
         WHERE product_id = p.product_id AND tag_id IN (3,6)
      )
    

    创建适当的索引(在 (product_tag_map.product_id, product_tag_map.tag_id) 一个分开 (product_tag_map.tag_id) 除了“正常”的pk/fk索引),这应该足够快。


    编辑: 上述的可缓存(就查询计划而言)和更动态的变体是:

    创建 user_searches 桌子 (search_session_id, tag_id, include) 多列索引结束 (search_session_id, include) 一个单独的索引 tag_id . 然后在用户选择条件时填充:

    search_session_id   tag_id   include
                  ...
                 4711        2         1
                 4711        4         1
                 4711        5         1
                 4711        3         0
                 4711        6         0
                  ...
    

    像这样的查询:

    SELECT
      p.product_id,
      p.product_name
    FROM
      product_table p
    WHERE
      EXISTS (
        SELECT 1 
          FROM product_tag_map m INNER JOIN user_searches s ON s.tag_id = m.tag_id
         WHERE m.product_id = p.product_id 
               AND s.search_session_id = 4711 /* this should be a parameter */
               AND s.include = 1
      )
      AND NOT EXISTS (
        SELECT 1 
          FROM product_tag_map m INNER JOIN user_searches s ON s.tag_id = m.tag_id
         WHERE m.product_id = p.product_id 
               AND s.search_session_id = 4711 /* this should be a parameter */
               AND s.include = 0
    
      )
    
        2
  •  1
  •   The Surrican    14 年前

    可以在select语句上创建视图。

    (视图基本上是一个可以轻松查询的虚拟表,但它与来自复杂语句的数据一起弹出。阅读本手册,它在性能和读/写行为方面并不那么简单。)

    但是,您的查询可能如下所示:

    SELECT 
    product_id, count(*) as total 
    FROM tag_map WHERE tag_id IN (2,4,5) 
    AND total = 3 
    AND product_id NOT IN (
    SELECT product_id, count(*) as total FROM tag_map WHERE tag_id IN (3,6) 
    WHERE total = 2 GROUP BY ( product_id )
    )
    GROUP BY ( product_id )
    

    你也可以加入,但我想会慢一些。