Задавайте вопросы, мы ответим
Вы не зашли.
Всем привет!
Делаю базу товаров. У каждого товара задается возрастная группа.
Например,
от 0 до 1
от 1 до 3
и т.д.
Вопрос в том, как лучше это реализовать. Интересует максимальная скорость выборки по возрасту.
варианты
1) Делается таблица `продукт_возраст`
с полями id_продукта, id_возрастной группы.
И выборку делаем SELECT * FROM `продукты` as п, `продукт_возраст` as в WHERE п.id=в. id_продукта AND в.id_возрастной группы = нужное_число
2) Поскольку возрастных групп не так много (5), создаем пять полей в таблице с продуктами, соответствующих этим группам .
Например, v1,v2,v3,v4,v5. И если товар в этой группе ставим 1, если нет 0.
И выборка делается так SELECT * FROM `продукты` WHERE v2 = 1; (циферку 2 подставляет php скрипт)
Может есть еще варианты?
Как сделать максимально быстрый запрос?
Спасибо!
Неактивен
быстрее всего одну таблицу продукты, в которой ENUM поле возраст
SELECT * не очень хорошо, так как у Вас будет order by и limit. В случае order by будет сортироваться вся выборка (включая описания и.т.д.)
Можно было бы написать
SELECT * FROM product WHERE id IN ( SELECT id FROM products WHERE vozrast=4 ORDER BY X LIMIT Y,Z)
но, к сожалению, внутри запроса IN в текущей версии MySQL, использовать LIMIT нельзя, поэтому данный составной запрос лучше всего реализовать на языке программирования (например PHP) или в хранимой процедуре.
На PHP вы сначала выбираете id внутренним запросом (он будет включать WHERE, ORDER BY и LIMIT), а затем делаете SELECT * FROM products WHERE id in ($idlist); Этот запрос будет быстрым, так как отображаемых товаров на странице немного, а выборка будет идти по ключу
Неактивен
За $idlist спасибо!
Насколько я понимаю, ENUM предполагает только одно значение, а мне нужна возможность выбирать несколько. На этот случай есть SET. Но будет ли это оптимально, и как делать запрос?
Неактивен
Производительность 5 полей или поля SET будет сравнимой, так как если всего 5 вариантов, то эффективность ключей будет низкой и все сведется к перебору. Если использовать поле SET, то перебор потребует меньше памяти (и, если поле будет ключем, можно ключ загрузить в отдельный кэш, перебор будет в памяти). Поэтому предпочительнее использовать поле SET.
Альтернативно, можно для каждого товара хранить минимальный и максимальный возраст, что даст производительность того же порядка.
Неактивен
Пардон а запрос, что LIKE'ом делать? Это я про SET
Неактивен
У поля типа SET есть побитовое (числовое) представление.
Например animals SET('cat', 'dog', 'bird')
поле двоичное_число десятичное число
cat 0001 1
dog 0010 2
bird 0100 3
Сравнение можно делать побитовой операцией. Например animals & 0001 - есть ли кошка, animals & 0101 - есть ли кошка или птица, (animals & 0001) && (animals & 0011) - есть ли и кошка и птица
Можно использовать FIND_IN_SET() или в крайнем случае LIKE. LIKE работает со строками, так что надо ожидать, что будет медленно.
Рекомендую http://www.vbmysql.com/articles/mysql/t … -datatype/. Там про битовые действия тоже написано.
Неактивен
Григорий, спасибо большое за ответы и за ссылку!
Насколько я понял в запросах по умолчанию используется десятеричное представление.
Т.е. animals & 1, animals & 5
Значит у меня будет заппрос WHERE age & 1 или WHERE age & 4
Является ли это оптимальным?
Может пять полей? В этом случае в клиентской части выборка всегда будет к одному полю.
А если хранить max и min возраст, какой будет запрос? WHERE 2>=age_min AND 2<=age_min; Такой?
Или тут можно BETWEEN использовать?
Принципиальна ли вообще разница между этими способами? Может я зря заморачиваюсь?
Неактивен
Разница может быть принципиальной, если будете использовать MySQL Cluster, так как там не все операции выполняются на датанодах. А в случае innodb или myisam отличие будет какое-то, но понять можно будет уже только эмпирически. 5 полей или одно поле - все равно перебор будет идти. Одно поле меньше памяти в кэше ключей займет. Все зависит от того сколько товаров - 1000 или 1000000. И вообще - преждевременная оптимизация - корень всех зол.
Неактивен
Согласен! Товаров будет в районе 10000.
Сделаю, как будет удобней. Еще не решил, как. В целом, основная задача была не использовать LIKE, как это сделано сейчас.
Спасибо большое за ответы!
Неактивен