PHP MySQL用于MySQL表中的排列

我有一个包含7列的mysql表,每行包含整数值。

我有一个简单的网站接收用户的值,我必须尝试查看用户发送的值是否与表中的任何行匹配或相似。

因此,用户将例如1 2 3 4 5 6 7写入为输入。

我必须查明我的表中的任何行是否与没有订单的行类似。 所以1 2 3 4 5 6 7 = 7 6 5 4 3 2 1等等。 我的表格包含40,000多行数据。

我还必须看到,如果它们共享至少567中共同的数字。

这意味着使用排列来找到所有可能的组合。 然而,对于这样的问题最好的办法是什么?

  • 从用户获取输入并获取所有排列,并匹配第一行,第二行等,如果找到则报告? 或者,做相反的事情,从表中获取一行并获取所有排列,并根据用户输入进行匹配?

  • 在经历如此巨大的排列如此巨大的桌子时,记忆和CPU使用情况如何?

  • 感谢您的任何提示! Souciance


    在完整的规范化模式中,这是一个具有查询的单个模式

    让我们假设你的表与pk一样:

    create table T1 
    ( pk char (1), a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int);
    
    insert into T1 values 
    ('a',1,2,3,4,5,6,7),
    ('b',2,3,4,5,6,7,8),
    ('z',10,11,12,13,14,15,16);
    

    目前,我们可以将数据标准化为:

    select
       pk, 
       case a
        when 1 then a1
        when 2 then a2
        when 3 then a3
        when 4 then a4
        when 5 then a5
        when 6 then a6
        when 7 then a7
       end
       as v
    from T1   
    cross join 
       (select 1 as a from dual union all
        select 2 as a from dual union all
        select 3 as a from dual union all
        select 4 as a from dual union all
        select 5 as a from dual union all
        select 6 as a from dual union all
        select 7 as a from dual ) T2
    

    在之前的查询中,很容易将您的需求与单个查询匹配:

    select pk
    from
    (
    select
       pk, 
       case a
        when 1 then a1
        when 2 then a2
        when 3 then a3
        when 4 then a4
        when 5 then a5
        when 6 then a6
        when 7 then a7
       end
       as v
    from T1   
    cross join 
       (select 1 as a from dual union all
        select 2 as a from dual union all
        select 3 as a from dual union all
        select 4 as a from dual union all
        select 5 as a from dual union all
        select 6 as a from dual union all
        select 7 as a from dual ) T2
    ) T
    where
       T.v in ( 4,5,6,7,8,9,10)
    group by pk
    having                                           <-- The Having
       count( pk ) > 4
    

    结果:

    | PK |
    ------
    |  b |
    

    一个简单的方法可能是在数据库中添加一个额外的字段,这是所有7个字段组合的数字排序版本。

    例如。 如果数据库中的数据是2 4 7 6 5 1 3,那么组合字段将是1234567

    然后在比较时,用数字排序用户响应,并与数据库中的组合字段进行比较。

    根据你在做什么,你可以写这样的查询

    select * from table where combination like '12%' or combination like '123%' 
    

    如果您知道匹配数字的最小数量需要达到什么程度,那么会减少查询

    要找出他们写的与数据库中的内容有多相似。 你可以使用levenshtein PHP函数:http://php.net/manual/en/function.levenshtein.php

    $result = levenshtein($input,$combination);
    

    恐怕你不能真正有效地建立这样的问题。

    你可以像下面这样构建WHERE子句:

    (`1` IN ARRAY(1,2,3,4,5,6,7) 
        AND `2` IN ARRAY(1,2,3,4,5,6,7)
        AND `3` IN ARRAY(1,2,3,4,5,6,7)
        AND `4` IN ARRAY(1,2,3,4,5,6,7)
        AND `5` IN ARRAY(1,2,3,4,5,6,7))
    OR
    (`1` IN ARRAY(1,2,3,4,5,6,7) 
        AND `2` IN ARRAY(1,2,3,4,5,6,7)
        AND `3` IN ARRAY(1,2,3,4,5,6,7)
        AND `4` IN ARRAY(1,2,3,4,5,6,7)
        AND `6` IN ARRAY(1,2,3,4,5,6,7))
    -- Each combination
    

    但那将是一种状况。 另一方面,您可以尝试使用以下组合:

  • IN()
  • IF()
  • HAVING
  • 首先检查,如果列1中包含的信息:

    IF( `1` IN ARRAY(1,2,3,4,5,6,7), 1, 0)
    

    然后总结所有这些数据:

    SELECT (
        IF( `1` IN ARRAY(1,2,3,4,5,6,7), 1, 0) +
        IF( `2` IN ARRAY(1,2,3,4,5,6,7), 1, 0) +
        IF( `3` IN ARRAY(1,2,3,4,5,6,7), 1, 0) +
        IF( `4` IN ARRAY(1,2,3,4,5,6,7), 1, 0) +
        IF( `5` IN ARRAY(1,2,3,4,5,6,7), 1, 0) +
        IF( `6` IN ARRAY(1,2,3,4,5,6,7), 1, 0) +
        IF( `7` IN ARRAY(1,2,3,4,5,6,7), 1, 0)
    ) AS `matches_cnt`
    FROM t1
    HAVING `matches_cnt` >= 5
    

    这将重复遍历所有行,条件非常复杂(因此床的性能)。

    您也可以尝试用二进制字符串替换值,例如:

    1,2,7 = 01000011
    

    然后计算检查记录和数据库之间的汉明距离,但这只会降低条件的复杂度,但需要迭代槽的所有记录将保持不变。

    在mysql中的实现使用:

  • XOR
  • BIT_COUNT
  • 将用以下代替第一部分:

    SELECT (
        $MAX_NUMBER$ - BIT_COUNT( XOR( `binary_representation`, $DATA_FROM_USER$))
    ) AS `matches_cnt`
    
    链接地址: http://www.djcxy.com/p/66473.html

    上一篇: PHP MySQL for permutations on MySQL Table

    下一篇: Qt5 posting data to server using QUrl / QNetworkRequest