ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL快速检查哈希是否存在

2019-10-26 06:14:54  阅读:263  来源: 互联网

标签:performance combinations permutation sql mysql


我正在尝试创建一个MySQL函数,该函数将n和m作为输入,并从查询结果中生成m个id的随机n个唯一组合.

该函数将在每次调用时返回一个组合,并且该组合必须与所有先前的组合都不同.

在生成期间,它必须检查另一个表:如果组合已经存在,则要继续循环直到每个组合保持唯一.以破折号分隔的ID形式返回组合,或者如果没有空间让唯一组合返回false.

所以我得到了100个像这样的随机物品:

SELECT
    `Item`.`id`
FROM
    `Item`
LEFT JOIN `ItemKeyword` ON `Item`.`id` = `ItemKeyword`.`ItemID`
WHERE
    (`Item`.`user_id` = '2')
AND(`ItemKeyword`.`keywordID` = 7130)
AND(`Item`.`type` = 1)
ORDER BY RAND()
LIMIT 100

过去的组合通过-存储为itemID的串联的md5.

因此,我需要通过-连接此查询的结果,并为其创建md5.然后将另一个查询发送到名为Combination的第二个表中,并使用哈希列检查是否存在.并继续此循环,直到得到n个结果.

我不知道如何正确,快速地实现这一目标.有什么建议吗?

更新:

整个SQL转储在这里:https://gist.github.com/anonymous/e5eb3bf1a10f9d762cc20a8146acf866

解决方法:

排列

DROP FUNCTION IF EXISTS unique_perm;

DELIMITER //
CREATE FUNCTION unique_perm()
    RETURNS VARCHAR(255) CHARACTER SET ascii
    NOT DETERMINISTIC
    SQL SECURITY INVOKER
BEGIN
SET @n := 0;
iterat: LOOP
    SELECT SUBSTRING_INDEX(
             GROUP_CONCAT(province ORDER BY RAND() SEPARATOR '-'),
             '-', 3) INTO @list   -- Assuming you want M=3 items
        FROM world.provinces;
    SET @md5 := MD5(@list);
    INSERT IGNORE INTO md5s (md5) VALUES (@md5);  -- To prevent dups
    IF ROW_COUNT() > 0 THEN  -- Check for dup
        RETURN @list;       -- Got a unique permutation
    END IF;
    SET @n := @n + 1;
    IF @n > 20 THEN
        RETURN NULL;    -- Probably ran out of combinations
    END IF;
END LOOP iterat;
END;
//
DELIMITER ;

输出:

mysql> SELECT unique_perm(),  unique_perm(),  unique_perm()\G
*************************** 1. row ***************************
unique_perm(): New Brunswick-Nova Scotia-Quebec
unique_perm(): Alberta-Northwest Territories-New Brunswick
unique_perm(): Manitoba-Quebec-Prince Edward Island
1 row in set (0.01 sec)

笔记:

>我对M = 3进行了硬编码;根据需要进行调整. (它可以作为arg传递.)
>根据需要更改列名和表名.
>如果不使用@n进行测试,则如果组合用完,可能会陷入循环. (但是,如果N适度较大,那是“不可能的”,因此您可以删除测试.)
>如果M足够大,则需要增加@@ group_concat_max_len.另外,RETURNS.
>创建表md5s(md5 CHAR(32)CHARACTER SET ascii PRIMARY KEY)ENGINE =需要InnoDB.并且,您将需要在该函数的批次调用之间截断md5.
>这是一个可行的例子.
>缺陷:它提供独特的排列,而不是独特的组合.如果那还不够,请继续阅读…

组合方式

DROP FUNCTION IF EXISTS unique_comb;

DELIMITER //
CREATE FUNCTION unique_comb()
    RETURNS VARCHAR(255) CHARACTER SET ascii
    NOT DETERMINISTIC
    SQL SECURITY INVOKER
BEGIN
SET @n := 0;
iterat: LOOP
    SELECT GROUP_CONCAT(province ORDER BY province SEPARATOR '-') INTO @list
        FROM ( SELECT province FROM world.provinces
                  ORDER BY RAND() LIMIT 2 ) AS x;   -- Assuming you want M=2 items
    SET @md5 := MD5(@list);
    INSERT IGNORE INTO md5s (md5) VALUES (@md5);  -- To prevent dups
    IF ROW_COUNT() > 0 THEN  -- Check for dup
        RETURN @list;       -- Got a unique permutation
    END IF;
    SET @n := @n + 1;
    IF @n > 20 THEN
        RETURN NULL;    -- Probably ran out of combinations
    END IF;
END LOOP iterat;
END;
//
DELIMITER ;

输出:

mysql> SELECT unique_comb(),  unique_comb(),  unique_comb()\G
*************************** 1. row ***************************
unique_comb(): Quebec-Yukon
unique_comb(): Ontario-Yukon
unique_comb(): New Brunswick-Nova Scotia
1 row in set (0.01 sec)

笔记:

>子查询会增加一些成本.
>请注意,现在(必须)对每个输出字符串中的项目进行了排序.

标签:performance,combinations,permutation,sql,mysql
来源: https://codeday.me/bug/20191026/1934348.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有