预先查询.对mysql中最相关的字段进行排名


Advance query. Rank most related fields in mysql

假设我们有一个这样的数据库:

Project_tbl:

-----------------id |项目名称-----------------1|A2|B3|C-----------------

personel_project_tbl:

--------------------user_id |项目_id--------------------1|12|23|13|22|3--------------------

instrument_project_tbl:

--------------------------instrument_id |项目_id--------------------------1|11|22|22|11|3--------------------------

现在,我需要对项目列表进行排序,并根据它们与项目A的相似性对它们进行排序。

例如:

A和B在3个用户中有1个共同用户,在2个仪器中有2个仪器,因此它们的相似性排名为(1/2+2/2)/2=75%

A和C没有共同的用户,但有两个以上的仪器,因此它将是(1/2)/2=25%

所以B比be更相似,输出应该是

--------------项目|排名--------------2|753 | 25

这是我想到的第一个解决方案
如果我在PHP和MySQL中这样做,它将类似于:

 for all tables as table_x
    for all projects (except A) as prj_y
         unique = (Select distinct count(items) from table_x where project is A)
         count += (Select distinct count(items) from table_x
                   where project is prj_x and items are in
                     (select distinct items from table_x where project is a)
                  )/unique

因此,复杂性将是O(n2),并且在索引的情况下,选择也将花费O(logn),这是不可承受的。

你有没有想过完全在MySQL中完成它,或者以更好更快的方式完成它?

********更多信息和注意事项:**

  1. 我仅限于PHP和MySQL。

  2. 这只是一个例子,在我的真实项目中,表超过20个,因此解决方案应该具有高性能

  3. 这个问题是这个问题的补充问题:如果yr解决方案可以同时用于或应用于MySQL数据库中重复次数最多的相似字段(不知何故),那就太棒了。我想将相关项目的价值与项目的相似性相乘,以获得最佳选择。。。

总之,这两个问题将:获得最相关的项目,获得所有项目的相似项目,并找到当前项目最相似的项目,其中项目也与当前项目相似!yo


感谢您的智慧回答,如果您能对情况有所了解,我们将不胜感激

你可以这样做:

SET @Aid = (SELECT id
            FROM Project_tbl
            WHERE Project_name = 'A');
SELECT P.id
  , (IFNULL(personel.prop, 0) +
     IFNULL(instrument.prop, 0)
    )/2*100 Rank
  , personel.prop AS personell
  , instrument.prop AS instrument
FROM Project_tbl P
LEFT JOIN
  ( SELECT B.Project_id pid, COUNT(*)/C.ref prop
    FROM personel_project_tbl A,
         personel_project_tbl B,
         (SELECT COUNT(*) AS ref
          FROM personel_project_tbl
          WHERE Project_id = @Aid
         ) AS C
    WHERE A.user_id = B.user_id
    AND A.Project_id = @Aid
    GROUP BY B.Project_id
  ) personel ON P.id = personel.pid
LEFT JOIN
  ( SELECT B.Project_id pid, COUNT(*)/C.ref prop
    FROM instrument_project_tbl A,
        instrument_project_tbl B,
         (SELECT COUNT(*) AS ref
          FROM instrument_project_tbl
          WHERE Project_id = @Aid
         ) AS C
    WHERE A.instrument_id = B.instrument_id
    AND A.Project_id = @Aid
    GROUP BY B.Project_id
  ) instrument ON P.id = instrument.pid
WHERE P.id <> @Aid
ORDER BY Rank DESC

其想法是每个表都有一个子查询,每个子查询都映射给定表的项目id与对应率。

我对表演一点也没说。你必须试着看看它是否足够快来满足你的需求,但在我看来,没有办法击败你提到的O(n2)复杂性,因为你必须检查所有数据。