Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Есть таблица пользователей и у каждого пользователя может быть несколько заранее заданных вариантов характера, интересов, хобби.
Что лучше сделать: в таблице с пользователями использовать такие поля:
harakter set('1','2','3','4','5') not null,
interesy set('1','2','3','4','5','6') not null,
hobbi set('1','2','3','4','5','6,'7') not null
Или завести ещё одну таблицу и использовать join?
Будет использоваться поиск по указанным выше полям. А поле с типом "set" нельзя сделать индексом (точнее можно, но использовать такой индекс будет невозможно).
Как думаете: что быстрее будет работать 2 связанные таблицы (где есть нормальные ключи) или одна с полями set, но без ключей. Пользователей много (миллионы) и будет производиться поиск среди них.
Заранее спасибо за ответы.
Неактивен
1. Делать SET из чисел смысла нет никогда - делайте просто числа
2. Если делать по разумным строкам, то SET стоит делать тогда, когда значений немного. В случае 7 вариантов, стоит делать SET.
3. Индекс с полем типа SET использовать возможно, почему нет?
4. Быстрее будет работать одна таблица с ключом
Неактивен
Если использовать числа, то придется возводить двойку в указанную степень и суммировать по всем элементам множества. Индекс не работает, так как для него это просто целые числа, а не набор битов.
Если людей с указанным интересом будет очень много (около 10% от общего числа или выше), то полный скан таблицы будет быстрее, чем JOIN или использование индекса. Джойн будет иметь смысл, если различных интересов много и они разнообразны
Неактивен
paulus написал:
1. Делать SET из чисел смысла нет никогда - делайте просто числа
В поле set у разных пользователей могут быть разные значения: "1,3,5", "1,2,3", "3" и т.д. Просто числа не очень понимаю как тут сделать. Если только двойку в степень возводить (как написал rgbeast).
paulus написал:
3. Индекс с полем типа SET использовать возможно, почему нет?
А как его использовать этот индекс? Вот мне нужно найти пользователей у которых в поле set есть значения: 1 и 2. Я пишу where find_in_set('1',pole_set) and find_in_set('2',pole_set). Индекс тут mysql не использует.
Неактивен
Для таких случаев - не использует. Я думал, что Вы ищете конкретные комбинации.
Сделать несколько колонок с отдельными битами и индексом - это тоже не способ. Индекс
с двумя значениями не будет селективным - все равно будете откатываться до full table scan.
Неактивен
Есть 10 000 000 пользователей. У каждого свой набор из заданных интересов. Нужно найти пользователей, среди интересов которых встречаются искомые.
Т.е. вот такой вариант будет похоже сильно тормозной:
create table users(
id int unsigned not null auth_increment,
name varchar(255) not null,
interesy set ('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15') not null,
primary key (id)
);
select name from users where find_in_set('1',interesy) and find_in_set('3',interesy) and find_in_set('8',interesy) and find_in_set('11',interesy);
А как его можно улучшить?
Неактивен
Боюсь, что Вы в любом случае откатитесь до full table scan. Улучшить можно, например,
так:
1. Сделать отдельную таблличку, которая будет содержать два поля: id и interests.
2. Над этой табличкой проводить full table scans (они будут быстрее за счет того, что
не нужно будет читать ненужную информацию типа имени и других пользовательских
данных).
3. К результату FTS присоединять уже основную таблицу с данными о пользователях.
Альтернативный вариант - сделать по табличке на интерес с одним полем - id человека
(ключевое). Так Вы одним запросом типа
SELECT id FROM int_1 JOIN int_2 USING (id) JOIN int_3 USING(id)
выберете всех пользователей с первыми тремя интересами.
Как будет работать быстрее - зависит от реального количества пользователей и интересов.
Неактивен
Страниц: 1