Bits vs Char - Какой лучший способ хранить 3 взаимоисключающих флага? - PullRequest
4 голосов
/ 26 сентября 2011

У меня есть таблица, которая предназначена для отслеживания различных предметов. Среди других свойств предметами могут быть либо A, B, либо C, каждый из которых взаимно исключает остальные. Рекомендуется ли хранить эту информацию как символ или как 3 набора битов (isA isB, isC и т. Д.) Или каким-либо другим методом? Я мог бы понять использование символа, если мне, возможно, понадобится больше типов данных в будущем, однако для меня также имеет смысл, что использование типов битовых данных будет занимать меньшие объемы памяти. Или я переоцениваю это, и разница будет настолько незначительной, что даже не будет иметь значения?

Ответы [ 5 ]

4 голосов
/ 26 сентября 2011

Или я переоцениваю это, и будет ли разница настолько незначительной, что даже не будет иметь значения?

Немного, да.

Но вы должны понимать, что между вашими проектными предложениями есть принципиальное различие: наличие столбца char сделает исключительную работу исключением.Наличие IsX полей (одного) не будет.Объяснено: имея столбцы IsA и IsB, можно потенциально установить оба значения в одну и ту же запись, если только вы не используете другой механизм для предотвращения этого (триггер, проверка ограничения и т. Д.)

Кроме того, наличие нового столбца каждый раз, когда возможно новое значение, не является хорошим дизайном БД.

2 голосов
/ 26 сентября 2011

Просто используйте Char.

В отношении пространства, вы будете использовать дополнительные 625 КБ на миллион строк (при условии 5 битов, сэкономленных на строку, что является наилучшим вариантом для экономии сценария).

Это не очень много.

Для сравнения: 625 MB на МИЛЛИАРД строк.Когда вы переходите к таблицам такого размера, вас не волнуют какие-либо блоки, которые не начинаются с giga, tera или peta.

Внутренне SQL Server сохраняет их все какнезависимо от байта (до 8 битовых полей).

К тому времени, когда пространство имеет значение, любые изменения архитектуры (от использования битовых полей к чему-то более гибкому) будут чрезвычайно болезненными.

1 голос
/ 26 сентября 2011

Если подумать, это действительно сложный, но довольно сумасшедший способ реализовать ваш сценарий - хранить его в обнуляемом бите.

"Целочисленный тип данных, который может приниматьзначение 1, 0 или NULL. "

, но я не совсем понимаю, как они справляются с этим, поскольку

" Механизм базы данных SQL Server оптимизируетхранение битовых столбцов. Если в таблице 8 или менее битовых столбцов, столбцы сохраняются как 1 байт. "

Оба из http://msdn.microsoft.com/en-us/library/ms177603.aspx

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

1 голос
/ 26 сентября 2011

Я бы использовал один символ, байт, перечисление, что угодно. Если состояния являются взаимоисключающими, тогда это не лучшее использование для флагов.

0 голосов
/ 26 сентября 2011

Я бы использовал small int , в основном однобайтовое число от 0 до 255. Когда вы расширяете свои возможные значения, вы заканчиваете тем, что используете сумасшедшие буквы, которые ничего не значат.Итак, я просто начинаю с цифр.Сохранение трех битов взаимоисключающими не стоит хлопот, они все равно займут байт памяти.

...