![]() |
Задавайте вопросы, мы ответим
Вы не зашли.
Вопрос №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 раз самообъединение
Неактивен