:: Не фоксом единым
Хранение разного набора атрибутов в виде битовой маски
sphinx
Автор

Сообщений: 31178
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Допустим есть таблица такой структуры:

TABLE1
-------
ID I
CODE_MODIFY VARCHAR2(10)
PRICE_IN N(10,4)
PRICE_OUT N(10,4)
PRICE_EXT N(10,4)
COMMENT VARCHAR2(100)

TABLE2
ID I
TEXT_MODIFY VARCHAR2(100)

1 - Изменение точки доставки
2 - Изменение пункта отправки
3 - Изменение транспорта
4 - Изменение количества в партии
5 - Изменение веса партии
6 - Проблемы с документацией
7 - Технические неисправности
8 - Финансовые проблемы
9 - Форс-мажорные изменения непреодолимой силы
0 - Прочие изменения

В TABLE1 в поле CODE_MODIFY может через пробел храниться 2-3 состояния (теоретически больше!) ОДНОВРЕМЕННО. Например, указаны сразу две причины - 4(изм.количества) и 5 (изм.веса). Хочется сделать битовую маску вместо поля CODE_MODIFY, где номер ID - это номер бита, а 1 и 0 - есть эта причина или нет.

Но как потом из этой битовой маски сделать запрос? Другими словами, хочется сделать представление (VIEW), которое денормализует все данные и представит их в том виде, в каком они хранятся сейчас..

Или не туда копаю? Но ведь хранить словать всевозможных состояний - это куда накладнее.


------------------
"Veni, vidi, vici!"(с)




Исправлено 1 раз(а). Последнее : sphinx, 14.06.17 20:33
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
sphinx
Но ведь хранить словарь всевозможных состояний - это куда накладнее.
Да какая тут накладность.
Мне кажется обычная связь много ко много.
И никаких проблем с выборками)
Чо тут экономить, не ассемблер)


------------------
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
PaulWist

Сообщений: 14614
Дата регистрации: 01.04.2004
Ну дык:

1. Сделай табличку Типов Изменений

Create table CODE_MODIFY (ID int PRIMARY KEY, Name varchar(100), Comment varchar(max))

2. Сделай промежуточную табличку

cerate table TABLE1_CODE_MODIFY
(ID int PRIMARY KEY,
TABLE1_ID int not null
FOREIGN KEY
REFERENCES TABLE1 (ID) ,
CODE_MODIFY int not null
FOREIGN KEY
REFERENCES CODE_MODIFY (ID)
)


Правда тут придётся сначала всё привести в нормальный вид.

3. Если хочется оставить всё как есть, то городи вычисляемое поле либо в таблице, либо во view.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
ry

Сообщений: 2113
Дата регистрации: 24.09.2007
Можно было бы хранить состояние в виде суммы степеней двойки вида 2^ID, например, CODE_MODIFY=2^4+2^5 (по сути, это и есть битовая маска). Отдельные биты проверять через bittest(CODE_MODIFY,ID+1). Но как связать это запросом с таблицей состояний, не знаю. Разве что, если перечень состояний не меняется, лепить в запросе нечто наподобие: select ..., iif(bittest(CODE_MODIFY,1),"Прочие изменения"," ")+iif(bittest(CODE_MODIFY,2),"Изменение точки доставки"," ")+... as Reason, ...
Только вряд ли это чем-то лучше или проще, чем анализировать строку из разделенных пробелами значений.
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
sphinx
В TABLE1 в поле CODE_MODIFY может через пробел храниться 2-3 состояния (теоретически больше!) ОДНОВРЕМЕННО.
Это УЖЕ денормализованная структура. Напрямую "связать" такое поле-список со справочником нельзя в любом случае. Будь там "строка чисел через пробел", будь там битовое поле.
sphinx
Хочется сделать битовую маску вместо поля CODE_MODIFY, где номер ID - это номер бита, а 1 и 0 - есть эта причина или нет.
Это вполне логично.
sphinx
Но как потом из этой битовой маски сделать запрос? Другими словами, хочется сделать представление (VIEW), которое денормализует все данные и представит их в том виде, в каком они хранятся сейчас.
Ну используй UDF преобразующую битовую маску в тот же "набор чисел через пробел" - это тривиальное выражение (просто слишком длинное чтобы пихать его просто в текст запроса - да и изменяться может, я полагаю, "набор флагов" - и снова лезть в текст запроса не очень хорошо). По аналогии как ry написал, только не "расшифровки" а те же самые числовые коды + пробел и слепляй (потом PADR-ом до 10-ти символов и дополни/урежь - кстати в 10 символов не более 5-ти кодов одновременно поместится, можно было бы вместо чисел использовать любые символы - это убирает нужду в разделителе-пробеле и позволяет хранить до 10 разных "флагов" в одном 10-символьном поле. По сути это тоже некоторый суррогат битовой маски).

Только смысл в этом какой? Не менять старую программу? Но её не получится не менять, т.к. заполнять то уже это поле нужно по другому...

sphinx
Или не туда копаю? Но ведь хранить словать всевозможных состояний - это куда накладнее.
Какой ещё "словарь всевозможных состояний"? На кой чёрт он нужен? В нормализованном виде такая информация хранится при помощи таблицы связи много-ко-многим как показывает Павел.
Но и битовые поля тоже используются - правда обычно сами "расшифровки" в БД не вносят - ну разве что "справочно" в виде метаинформации. Т.к. сам бит в такой маске это УЖЕ и есть значение совершенно понятного признака.
Грубо говоря, битовая маска это "свёрнутый" в одно число набор логических полей типа is_delivery_address_changed, is_sending_point_changed, ... И для этой структуры как таковая "таблица возможных флагов" не требуется вообще.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
sphinx
Автор

Сообщений: 31178
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Igor Korolyov
Ну используй UDF преобразующую битовую маску в тот же "набор чисел через пробел"

ry
Можно было бы хранить состояние в виде суммы степеней двойки вида 2^ID, например, CODE_MODIFY=2^4+2^5 (по сути, это и есть битовая маска). Отдельные биты проверять через bittest(CODE_MODIFY,ID+1). Но как связать это запросом с таблицей состояний, не знаю. Разве что, если перечень состояний не меняется, лепить в запросе нечто наподобие: select ..., iif(bittest(CODE_MODIFY,1),"Прочие изменения"," ")+iif(bittest(CODE_MODIFY,2),"Изменение точки доставки"," ")+... as Reason,


Вот этого мне и не хватало для полного счастья! Написать UDF, в нее запихать проверку битов через BITTEST().


ry
Только вряд ли это чем-то лучше или проще, чем анализировать строку из разделенных пробелами значений.
Хранить нормализованные данные - это хорошо и правильно.

Igor Korolyov
В нормализованном виде такая информация хранится при помощи таблицы связи много-ко-многим как показывает Павел.

А вот это без примера не понял.


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
of63

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Я в фоксе часто храню в поле I битовые поля (до 31 бит), в фильтрах указываю как BITTEST(поле, № бита), изображаю... классjv типа List, с отметками на каждой позиции. В метаданных проги есть массивы человеческих обозначений этих полей-наборов бит. Метода примерно такая - при запуске проги эти метаданные превращаются в 1-массив (одномерный), есть класс, который умеет эти 1-массиывы изображать в List, всякие заморочки, типа "если в метаданных название начинается с \, то это устаревший элемент", или в классе изображения этих полей бит в человеческом виде - "не показывать устаревшие элементы"... и т.п. Как художник художнику )
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
pasha_usue

Сообщений: 3649
Откуда: Е-бург
Дата регистрации: 06.10.2006
sphinx
Igor Korolyov
В нормализованном виде такая информация хранится при помощи таблицы связи много-ко-многим как показывает Павел.

А вот это без примера не понял.
Саш. Тут элементарно. Нормальная структура для твоей задачи это 3 таблицы. 1 - Table1, 2 - Table2, 3 - то, что произошло с Table1, но содержится в справочнике Table2. И выборки по этой тройной структуре работают априори быстро. Если ты вводишь битовое поле, то тебе придётся подпереть это битовое поле индексами так, будь-то у тебя уже есть эта table3. Какие-то реализации SQL уже содержат оптимизированные индексы под твой запрос. В каких-то тебе придётся выделить каждый бит в отдельный индекс (если это ключевое поле для индекса, конечно). А вообще, твоё битовое поле в "стандарте" это сразу же денормализация. И либо ты поддерживаешь нормализованную структуру параллельно к этому полю, либо ловишь издержки денормализации (а тут надо серьезно думать).



Исправлено 1 раз(а). Последнее : pasha_usue, 15.06.17 22:04
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Влад Колосов

Сообщений: 22664
Откуда: Ростов-на-Дону
Дата регистрации: 05.05.2005
Битовая маска - не реляционно. Надо создавать отдельный атрибут для каждого вкл/выкл.


------------------
Совершенство - это не тогда, когда нельзя
ничего прибавить, а тогда, когда нечего убавить.
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
В некоторых серверах возможно "физически" хранить набор логических полей в виде битовой маски (т.е. логически это разные поля, а физически - несколько байт). Там где такой возможности нет вполне можно использовать и "вручную" вынимаемые биты из одного поля - благо в большинстве СУБД есть битовые операции для этого. Это уже вопросы тонкой оптимизации - держать 10-15 байт в структуре хранения для этих "флагов", или уместить всего в 2 байта.
"Работать" всё одно можно именно с отдельными флагами из такого поля.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
pasha_usue
И выборки по этой тройной структуре работают априори быстро.
Это более чем спорное утверждение. Как раз таки "в общем случае" выборки по соединению таблиц работают ЗАМЕТНО медленнее чем по одной таблице где "денормализованно" хранятся данные. Иначе и смысла никакого в денормализации не было бы - мало того что "лишняя работа", так оно ещё и медленнее
В некоторых СУБД есть специальные типы индексов работающие как раз для "соединения" и не имеющие смысла применимо к одной таблице. Если очень грубо, это примерно как фоксовый индекс по table1, где в выражении индекса участвуют поля из table2 - и всё работает в предположении что между table1 и table2 всегда установлена определённая SET RELATION... В общем это всё достаточно "тонкие материи".

pasha_usue
Если ты вводишь битовое поле, то тебе придётся подпереть это битовое поле индексами
Не обязательно. По отдельным логическим полям вообще весьма нечасто нужно делать индексы - в большинстве случаев они не помогут в ускорении работы. Только в особых случаях они могут быть полезны. Ну, к примеру, если в данных 60% "отмеченных" записей и 40% "неотмеченных", то доступ по индексу скорее всего будет невыгоден - проще сканировать таблицу целиком и просто выбрасывать "неподходящие" записи (те или иные). Вот если "отмеченных" всего 0.01% и нужны именно они в запросе - ну тогда выгода от индекса будет заметной... Но для таких "сильно перекошенных" распределений и введение дополнительной таблицы связей много-ко-многим уже не будет столь замедляющим и неудобным процессом. Если на 100к записей в "основной" таблице будет всего 100 записей в этой таблице "дополнительных параметров", то "перевернув" порядок доступа к таблицам оптимизатор достаточно эффективно их извлечёт.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
AlexK

Сообщений: 2114
Откуда: Королев,Москва
Дата регистрации: 11.12.2000
сделать доп.таблицу
ID, MODIFY
1, 1
1, 3
2, 1
2, 5
3, 4
3, 1
3, 5

и забыть про маску


------------------
Береги природу, мать Вашу. Моя страничка www.genrep.net
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Vedmak

Сообщений: 5966
Откуда: CiTY
Дата регистрации: 30.10.2003
А цель какая сего исследования ?

Сама по себе концепция сжатия набора флаговых параметров в битовую маску уместна при передаче этих параметров "по проводу". Т.е. если надо внешнюю систему передать 32 (например) флага. Конечно короче и быстрее передать это в 4 байта.

Если же речь идет о системе на одном хосте или же в локальной нормальной сети... то о чем вопрос ? Рядом передать 32 или 1024 блока разница копеешная.

Коллеги! Главный вопрос любой задачи: а чего требуеться достичь? ТехЗадание какое?


------------------
Говорить стоит лишь для тех, кто слушает.




Исправлено 2 раз(а). Последнее : Vedmak, 11.08.17 20:43
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Хранить в бд 10гб данных или 80 - "какая разница".
Ожидать выполнения запроса 5 секунд или 40 - тоже ведь "не важно".
И архитекторы СУБД, придумывающие всякие хитрые способы для объединения кучи логических полей во внутренне хранящиеся битовые маски, тоже "просто идиоты"


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Vedmak

Сообщений: 5966
Откуда: CiTY
Дата регистрации: 30.10.2003
Igor Korolyov
Хранить в бд 10гб данных или 80 - "какая разница".
Ожидать выполнения запроса 5 секунд или 40 - тоже ведь "не важно".
И архитекторы СУБД, придумывающие всякие хитрые способы для объединения кучи логических полей во внутренне хранящиеся битовые маски, тоже "просто идиоты"

Уважаемый! Вы передергиваете! Бодание теориями прошу оставить для последующего обсуждения когда автор ветки соизволит, если соизволит, озвучить цель.

Igor Korolyov
Хранить в бд 10гб данных или 80 - "какая разница"

Граф, вам не кажется, что хранить такой объем данных можно лишь с цель сжатия накопительных данных. Например историю показаний некоего устройства. Т.е. в моменте эти данные идут только на вставку. Тут сжатие только в помощь. Но последующая аналитика становится сложноватой. Например как построить динамический график изменения состояния одного флага из такой базы. Т.е. придется каждую секунду (refresh timeout) из базы выдергивать весь фрейм и тратить время на декодирование одного замера из каждого полученного фрейма. Далее вступает теория больших чисел, т.е. то, что незначительно для десятка измерений, может оказаться фатальным при выполнении задачи многомиллионных повторений.

Igor Korolyov
Ожидать выполнения запроса 5 секунд или 40 - тоже ведь "не важно".

Зависит от контекста задачи, ибо запрос выполняемый раз в месяц может и не иметь критичных требований к скорость в рамках одной минуты.

Igor Korolyov
И архитекторы СУБД, придумывающие всякие хитрые способы для объединения кучи логических полей во внутренне хранящиеся битовые маски, тоже "просто идиоты"

Не думаю, что чужие болезни психики стоит квалифицированно оценивать на этом форуме. Тут "больных" своих еще не всех излечили.

В конечном счете, Граф, согласитесь, что сравнительная скорость принятия решения на основании выборки флагов в виде битовой маски из 500 гигабайтной БД (у меня уже есть 300+ Гб база) супротив выборки 8 битовых полей из таблички в сотню килобайт не стоит даже обсуждать на коленке.

Советы данные вне озвучивания преследуемой цели сильно теряют в своей ценности.

PS. Микроскопом давить мух ведь не требуется или забивать гвозди экскаватором ?


------------------
Говорить стоит лишь для тех, кто слушает.




Исправлено 7 раз(а). Последнее : Vedmak, 18.08.17 22:48
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Естественно что для объёмов порядка 1-2Мб нет смысла париться с "упаковкой", разница будет ничтожна. И тут нет предмета для спора. Возражение вызывает лишь категоричное:
Vedmak
Сама по себе концепция сжатия набора флаговых параметров в битовую маску уместна при передаче этих параметров "по проводу"...
Если же речь идет о системе на одном хосте или же в локальной нормальной сети... то о чем вопрос ? Рядом передать 32 или 1024 блока разница копеешная.
Ибо нет, не только "сеть" может быть узким местом. И обращения к HDD, и даже просто кушаемая кэшем БД физическая память - тоже могут очень серьёзно выиграть за счёт 8-кратного сокращения объёмов (на деле, если там 3-значная логика, т.е. "поле-флаг" помимо true/false ещё и null может содержать, то сокращение будет "всего лишь" 4-кратным).
И для БД разница между "колупанием" в 32 блоках и 1024-мя (на самом деле 256 - если брать "чистую" битовую маску) просто колоссальная. Ведь эти "лишние" 248 блоков займут место в кэше, вытеснив оттуда что-то полезное. Да и считать их с диска ещё надо.

Кстати, фокс в процессе оптимизации из древовидного индексного файла, где пусть и в упакованном виде, но хранятся таки полноценные пары "значение":"номер записи" создаёт именно битовые маски - под каждое оптимизируемое условие - т.к. для "всего лишь" таблицы со 100 тыс. записей битовая маска займёт всего то 12.5Кб. И даже десяток таких масок построить, потом через битовые операции "слить воедино", и, наконец "побитово пройтись" оказывается весьма выгодно.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Vedmak

Сообщений: 5966
Откуда: CiTY
Дата регистрации: 30.10.2003
Уважаемый Мастер! "Чистая теория" страдает одним "практическим" недостатком. Пока "Теория" формулирует свое мнение оцениваемая реальность меняется. В следствии этого "теория считает биты" уже для себя. Я долек от критики самой методики.

Господа мастеровые! Нам надо пилить сейчас, но потом академика нам расскажут где мы ошиблись. Наши дети получат карандаши в школу и я не буду рассказывать им как я заработал на эти карандаши.

Академики уже "своих детей отправили в школу". Они свободны в своих рассуждениях. Как может сытый рассказывать голодному о правилах разделки пекинской утки ?

Вам шашечки или ехать ?


------------------
Говорить стоит лишь для тех, кто слушает.
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Ведьмак опять накатил не по-детски
Ratings: 0 negative/1 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Vedmak

Сообщений: 5966
Откуда: CiTY
Дата регистрации: 30.10.2003
Господин профессор прав про теорию. Это замечательно работает когда у вас одна задача и вы призваны (вам платят) за оптимизацию одного процесса. Вы сидите на берегу одного ручья финансирования и вдумчиво облизываете (извините за оллегорию) один камень. Тихонько бит за битом снижаете расходные показатели некого процесса... Но когда ваша семья кушает мясо только когда ты сам его настиг в лесу и принес в дом, обсуждение "капельного приемущества" становится несколько раздражающим. Мясо детям "сейчас" гораздо ценнее, чем профессорская мантия деду "потом".
У "профессоров" конечно есть свои дети...


------------------
Говорить стоит лишь для тех, кто слушает.
Ratings: 0 negative/0 positive
Re: Хранение разного набора атрибутов в виде битовой маски
Taran

Сообщений: 13623
Откуда: Красноярск
Дата регистрации: 16.01.2008
Vedmak
Господа мастеровые! Нам надо пилить сейчас, но потом академика нам расскажут где мы ошиблись. Наши дети получат карандаши в школу и я не буду рассказывать им как я заработал на эти карандаши....

Именно так. Бабла срубить и похер. Это нормально. Для организма желающего только жрать.

Но есть другие организмы. Они радеют за чистоту кода и достойность звания "программист".
Их мало, но они есть.
Ratings: 0 negative/1 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 3 (Гостей: 3)

© 2000-2024 Fox Club 
Яндекс.Метрика