假设我们有一个这样的数据库:
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中完成它,或者以更好更快的方式完成它?
********更多信息和注意事项:**
我仅限于PHP和MySQL。
这只是一个例子,在我的真实项目中,表超过20个,因此解决方案应该具有高性能。
这个问题是这个问题的补充问题:如果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)复杂性,因为你必须检查所有数据。