Предложение 1: поскольку поля с фильмами представляют собой биты, то имеет смысл хранить их в виде чисел. Максимальное целое в mysql — 8-байтовый BIGINT. То есть, если всего фильмов тысяча, то потребуется полтора-два десятка таких чисел в каждой записи. Пусть N — количество таких чисел-1, userF0, ..., userFN — эти числа в записи выбранного пользователя. Тогда поиск 10
похожих пользователей в таблице с полями (user_id, f0, ..., fN) будет выглядеть так:
SELECT user_id FROM таблица
ORDER BY (BIT_COUNT(f0 & userF0) + ... + BIT_COUNT(fN & userFN)) DESC LIMIT 10;
Минусы подхода: пробегать при запросе будет все записи, при добавлении новых фильмов нужно вызывать ALTER TABLE. За скорость тоже ручаться не могу.
Предложение 2: создать 1 таблицу с юзерами и столько таблиц, сколько фильмов, в каждой из которых хранить список id юзеров, выбравших фильм. Тогда поиск похожих юзеров сведется к:
SELECT tmp.user_id FROM (SELECT user_id FROM таблица1
UNION ALL
SELECT user_id FROM таблица2
UNION ALL
...
UNION ALL
SELECT user_id FROM таблицаN) AS tmp
GROUP BY tmp.user_id ORDER BY COUNT(tmp.*) DESC LIMIT 10;
Минусы подхода: большое количество подзапросов, группировка.
Предложение 3: создать 1 таблицу с юзерами (users) и 1 таблицу с юзеро-фильмами (user_films), т.е. с записями о предпочтениях юзеров следующего вида (user_id, film_id). Тогда для списка фильмов выбранного юзера (film_id0, ..., film_idN) поиск похожих юзеров сведется к:
SELECT user_id FROM user_films
WHERE film_id IN (film_id0, ..., film_idN)
GROUP BY user_id ORDER BY COUNT(*) DESC LIMIT 10;
Минусы подхода: группировка.
Хотя при индексированном поле film_id может будет и не сильно медленно.