"Упакованное" хранение до 32-х стандартных логических полей (Boolean) в одном числовом поле таблицыИсточник: vbnet
Вынашивал я одну мыслю - почему при достаточно большом количестве логических полей в таблице (а их обычно бывает более двух) не организовать упаковку в числовое поле? Ведь что такое числовое поле типа Byte? Это массив из 8 битов, которые выглядит так: 8 7 6 5 4 3 2 1 - вот эти биты и составляют число типа Byte. Обратите внимание - самый младший бит идет под номером 1, а самый старший под номером 8. Вот такой обратный отсчет зародится на заре компьютеростроения, когда даже Биллу Гейтсу казалось, что 640 Кб (Килобайт!!!) ОЗУ хватит на всё и больше просто не потребуется никогда. А что хранит логическое поле типа Boolean ? Да только логическую информацию, типа, да/нет, включено/выключено, мужчина/женщина ;). Для хранения такой информации достаточно одного бита, который принимает состояния 0 и 1 соответственно. То есть, для хранения 8-ми логических полей достаточно 1 байта, для хранения 16 - двух байтов, 32 логических полей - четырех байтов. Правда, в справке Access XP указывается, что размер логического поля 1 бит. Хм.... если значение True принимает -1, а значение False - 0, то тогда для хранения информации о данном бите все равно необходим хотя бы один байт. Непонятно, чтение литературы по данному вопросу тоже ничего не прояснило. Буду рад услышать аргументированное мнение по данному вопросу.
По моему, тут ошибка в справке заключается в том, что для хранения логической информации действительно необходим лишь один бит, но само-то логическое поле должно занимать, как минимум, байт. Биты же не могут храниться отдельно, а только в составе байта, такова архитектура компьютеров x86. Мы рассмотрим возможность хранения до 8 логических полей в одном поле типа Byte (0-255, занимает 1 байт, во что охотно верится ;). Вы легко сможете расширить пример и для хранения до 32 логических полей, которые будете должны хранить в поле типа Long (0-2147483647, занимает 4 байта). В отдельный модуль вставьте три функции: Public Function SetBitField(lngValue As Long, lngFieldNumber As Long) As Boolean Public Function WipeBitField(lngValue As Long, lngFieldNumber As Long) As Boolean Public Function CheckBitField(lngValue As Long, lngFieldNumber As Long) As Boolean Затем в модуле формы создадим кнопку и в событие [Нажатие кнопки] вставляем данный код: Private Sub Кнопка0_Click() If Not SetBitField(bytValueBoolField, 2) Then MsgBox "Бит не хочет устанавливаться" If Not WipeBitField(bytValueBoolField, 1) Then MsgBox "Бит не хочет сбрасываться" MsgBox CheckBitField(bytValueBoolField, 1) Теперь в любой момент можно узнать состояние любого бита - достаточно передать требуемой функции два параметра: самое числовое значение и номер позиции бита. Обратите внимание: несмотря на то, что биты считаются компьютером справа налево, номер позиции передается "нормальным человеческим языком", то есть считая слева направо (для этого в функциях есть необходимое преобразование (8 - lngFieldNumber) ). Конечно, если логических полей в таблице два-три, то может быть возня не стоит свеч ;). Но уже при количестве полей, приближающихся к 8, надо будет серьезно задуматься о таком вот "упакованном" хранении информации. Еще одна идея: если в числовом значении типа Long хранится 32 бита, то есть 32 отдельных поля, которые можно рассматривать как массив - в них можно хранить дни любого месяца, например: дежурство сотрудника по дням месяца. В свою очередь, в 8-битном массиве можно хранить дни недели. Проверку, сброс, установку всех битов легко организовать в цикл. При работе с такими массивами битов полезно будет держать в голове способы управления битами с помощью логических операторов And, Eqv, Imp, Not, Or, Xor, например: инверсия (Not) оптимальна для переключения состояния всех битов (команда - инвертировать выделенное). Преимущества: индексация для каждого логического поля не нужна, т.к. логических полей не существует - выигрыш в размере базы, вместо 8-32 байтов (логических полей) используется один-четыре - выигрыш в 7 раз. Меньше полей - меньше путаницы и захламления конструктора и таблиц. Недостатки: необходимо дополнительное вычисление для получения результата, необходимо планирование и документирование диапазона битов (а где оно не нужно?) Вывод: при грамотном подходе можно умело и красиво использовать данные функции с целью оптимизации размеров баз. |