Поиск идентификаторов общего списка в таблице MySQL с использованием побитовых операндов - PullRequest
0 голосов
/ 07 июня 2010

Я хочу найти общие элементы из столбца "follow_list" в таблице пользователей:

+----+--------------------+-------------------------------------+
| id | name               | following_list                      |
+----+--------------------+-------------------------------------+
|  9 | User 1             | 26,6,12,10,21,24,19,16              | 
| 10 | User 2             | 21,24                               | 
| 12 | User 3             | 9,20,21,26,30                       | 
| 16 | User 4             | 6,52,9,10                           | 
| 19 | User 5             | 9,10,6,24                           | 
| 21 | User 6             | 9,10,6,12                           | 
| 24 | User 7             | 9,10,6                              | 
| 46 | User 8             | 45                                  | 
| 52 | User 9             | 10,12,16,21,19,20,18,17,23,25,24,22 | 
+----+--------------------+-------------------------------------+

Я надеялся, что смогу отсортировать по количеству совпадений для данного идентификатора пользователя. Например, я хочу сопоставить всех пользователей, кроме # 9, с № 9, чтобы увидеть, какие из идентификаторов в столбце "follow_list" у них общие.

Я нашел способ сделать это через тип данных "SET" и немного хитрости:
http://dev.mysql.com/tech-resources/articles/mysql-set-datatype.html#bits

Однако мне нужно сделать это с произвольным списком идентификаторов. Я надеялся, что это можно сделать полностью через базу данных, но это немного не в моей лиге.


РЕДАКТИРОВАТЬ: Спасибо за помощь всем. Мне все еще интересно, может ли работать подход, основанный на битах, но соединение с тремя таблицами работает хорошо.

SELECT a.following_id, COUNT( c.following_id ) AS matches
FROM following a
LEFT JOIN following b ON b.user_id = a.following_id
LEFT JOIN following c ON c.user_id = a.user_id
  AND c.following_id = b.following_id
WHERE a.user_id = ?
GROUP BY a.following_id

Теперь я должен убеждать себя не преждевременно оптимизировать.

Ответы [ 3 ]

2 голосов
/ 07 июня 2010

Ваша проблема была бы упрощена, если бы вы могли разбить столбец following_list на дочернюю таблицу, например,

TABLE id_following_list:

id | following
--------------
10 | 21
10 | 24
46 | 45
...| ...

Вы можете прочитать больше здесь .

2 голосов
/ 07 июня 2010

Если вы нормализуете свой столбец follow_list в отдельной таблице с user_id и follower_id, вы обнаружите, что COUNT () чрезвычайно прост в использовании. Вы также найдете логику для выбора списка подписчиков или списка пользователей, за которыми следуют гораздо проще

1 голос
/ 07 июня 2010

Нормализовать таблицу, отбросить столбец following_list, создать таблицу following:

user_id
following_id

Что приводит к простому запросу (непроверенный, вы получаете точку):

SELECT b.user_id, COUNT(c.following)
FROM following a
JOIN following b -- get followings of <id> 
ON b.following_id = a.following_id
AND b.user_id = a.following_id
JOIN following c -- get all (other) followings of <id> again, match with followings of b
ON b.following_id = c.following_id
AND c.user_id = a.user_id
WHERE a.user_id = <id>
GROUP BY b.user_id
ORDER BY COUNT(b.following) DESC

Производительность может очень сильно зависеть от индексов и размера набора данных, возможно, добавьте столбец «сходство», который обновляется через регулярные интервалы или изменяется только для быстрого извлечения данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...