Задавайте вопросы, мы ответим
Вы не зашли.
Вопрос №1
Есть некоторая сущность, которая имеет большое кол-во параметров, которые могут принимать значения 1 и 0.
Сколько может быть таких параметров в будущем не известно (100 думаю наберется. 200 вряд ли. 500 скорей всего нет).
Будем считать что их 100-200. Но выставленными у каждой сущности оказываются около 10.
Причем наблюдается некоторая сгруппированность. Во избежании, избыточности я сделал несколько таблиц, каждая из которых хранит группу флагов.
Т.е. грубо говоря 10 таблиц по 10 столбцов TINY INT(1) в каждой (не считая ID по, которому JOIN делается).
Соответсвенно, та группа флагов, которая выставленная в 0, просто не записывается в соответвующую таблицу.
Таким образом выборку я предполагал осуществлять, делая JOIN только тех таблиц флаги в которых меня интересуют.
Но оказалось я не всё предусмотрел. И мне нужно делать выборку по такой маске, в которой меня интересуют определенные флаги, а все остальные должны быть 0.
Т.е. мне нужно делать JOIN всех таблиц.
Всё должно работать очень быстро. Т.к. будут частые запросы по различным маскам.
Вот я и думаю а может свести все флаги в одну таблицу. Но меня почему-то пугает большое кол-во столбцов для таблицы.
Или 100-200 столбцов TINY INT(1) это нормальная таблица? A 100-200 столбцов просто INT(11)? (это я спрашиваю до кучи, т.к. вижу в перспективе и необходимость в такой таблице).
---------------------------
Вопрос №2
Что если у меня будет большое кол-во запросов, типа
Неактивен
Само по себе большое количество столбцов в таблице — не так плохо, но вот индекс
над битовым полем Вы не натянете. В случае со sparse данными имеет смысл хранить
индексы установленных полей, а не матрицу битов — получается меньше места и
большое производительность.
Подзапросы не кэшируются. Можете сделать денормализационную табличку (или даже
временную просто на цикл запросов).
Неактивен
paulus написал:
... но вот индекс
над битовым полем Вы не натянете.
Поясните пожалуйста. Я вкурсе, что если бы 11100101 я хранил в одном поле, то индекс по такому полю мне ничего не дал бы. Но я намерен хранить каждый бит в отдельном поле TINY INT(1). А может и BIT(1), т.к. он на поверку оказался компактнее.
И что индекс по таким полям мне ничего не даст?
paulus написал:
В случае со sparse данными имеет смысл хранить
индексы установленных полей, а не матрицу битов — получается меньше места и
большое производительность.
Тоже хотел бы услышать пояснение. не знаю что такое sparse данные. И что подразумевается под индексами. Поле PRIMERY KEY?
Покажите пожалуйста наглядно в поле какого типа и каким образом вы предлагаете мне хранить индексы.
Неактивен
что такое sparse (или разреженные) данные почитал. Я так понял вы предлагаете хранить это дело так
Неактивен
ещё вот, что. объекты у меня похожи все, но есть некоторое различие. и я уже изначально разделил их на две групп.
и теперь я понял следующее. что для объектов одной группы будут делаться запросы, где нужно лишь удостовериться, что те или иные флаги выставлены. а для объектов другой группы наоборот, важно вести поиск по сброшенным флагам.
но у той и другой группы объектов матрица флагов одинаково разрежена (т.е. преобладают нули).
Сейчас у меня так:
Отредактированно mybd (05.11.2010 00:20:09)
Неактивен
Индекс — это способ быстро достать какие-то данные. Но это никакая не
магическая сущность — это просто сортированное дерево, по которому
можно угадать, какие строки нам нужны, а какие заведомо нет.
При выборке из таблицы за один раз Вы можете использовать только один
индекс. То есть если Вы сделаете сотню индексов каждый над своим столб-
цом — реально будет использоваться только один из них.
Второе ограничение — смысловое. Если у Вас есть столбец, который прини-
мает только два значения — как правило, смысла в индексе над ним нет:
если по индексу в среднем Вы выбираете половину строк — эффективнее
оказывается прочитать все данные последовательно, а потом отсеять ненуж-
ные не используя индекс вообще. Единственное исключение — когда по
индексу Вы вытащите лишь очень небольшое количество строк — в этом слу-
чае он действительно будет эффективным.
Про sparse — да, Вы поняли меня правильно. Просто если у Вас 99% значе-
ний нули, то хранить их бесполезно. Кстати, в Вашем примере третий столбец —
лишний, он всегда хранит единицы
Касательно отсутствующих строк — почитайте про внешние объединения
(например, LEFT JOIN).
Касательно скорости в целом — не пытайтесь понять, где будет bottleneck на
этапе первичного создания базы. Сделайте базу каким-то простым способом.
Напишите базовое приложение, которое попробует работать с этой базой. Оце-
ните, хватает ли Вам производительности. В случае, если не хватит — тогда
уже оценивайте производительнось системы и ищите методы ускорения.
Неактивен
paulus написал:
Про sparse — да, Вы поняли меня правильно. Просто если у Вас 99% значе-
ний нули, то хранить их бесполезно. Кстати, в Вашем примере третий столбец —
лишний, он всегда хранит единицы
Это да я сразу понял, просто поленился убирать этот столбец
Но ведь, когда мне нужно делать выборки по флагам, которые равны 0, то получается, что эти нули сразу обретают смысл(значимость). Относительность, своего рода получается, понимаете? Всё зависит то выбранной системы. И было бы конечно супер если бы я смог хранить только единицы, и при этом на основе этой информации быстро делать выборки на основе отсутствующих записей.
paulus написал:
Касательно отсутствующих строк — почитайте про внешние объединения
(например, LEFT JOIN).
За эти слова, спасибо. Наводит уже на кое-какие мысли.
Был бы благодарен, если бы вы подсказали как из sparse таблицы сделать следующие выборки.
Отредактированно mybd (05.11.2010 15:48:46)
Неактивен
SELECT t1.objectID
FROM tablename t1 JOIN tablename t2 USING(objectID)
WHERE t1.flagID = 2 AND t2.flagID = 3.
Во втором случае — Вам понадобится общая таблица объектов,
иначе ничего не выйдет
SELECT o.objectID
FROM objects o
LEFT JOIN tablename t1 ON o.objectID = t1.objectID AND t1.flagID = 1
LEFT JOIN tablename t2 ON o.objectID = t1.objectID AND t1.flagID = 1
WHERE t1.objectID IS NULL OR t2.objectID IS NULL;
Неактивен
Неактивен
Если принять во внимание, что в первоначальном запросе (в отличии от вашего варианта) нет опечатки, то работает
Неактивен
видимо у нас разные исходные данные..
я так понимаю, что предполагается наличие двух таблиц.
в одной только id объектов.. а в другой id объектов и флаги, так?
у меня по крайней мере так.. и на такой запрос выдается ошибка что нет в таблице t1 поля flagID
или я что-то не понимаю? покажите какие таблицы используются в качестве исходных?
аааа, или это запрос к одной таблице? а если условий больше? то как будет выглядеть запрос?
Отредактированно mybd (08.11.2010 15:21:14)
Неактивен
Исходные данные приведены в вашем посте http://sqlinfo.ru/forum/viewtopic.php?pid=19985#p19985
Если условий n, то придется делать n раз самообъединение
Неактивен