Tinyint против бит

Я не хочу прикоснуться к религиозной войне здесь, но, похоже, есть две школы мыслей о том, как представлять логические значения в базе данных. Некоторые говорят, что bit - соответствующий тип данных, в то время как другие утверждают, что tinyint лучше.

Единственные различия, о которых я знаю, следующие:

  • bit: размер хранилища - 1 бит, возможные значения - 0 или 1
  • tinyint: размер хранилища составляет 1 байт, возможные значения: 0-255

Какой тип данных лучше, когда вам нужно представлять логические значения? Является ли tinyint дополнительными накладными расходами "на всякий случай" вам нужны значения > 1?

Ответ 1

Когда вы добавляете столбец бит в свою таблицу, он будет занимать целый байт в каждой записи, а не только один бит. Когда вы добавляете второй бит-столбец, он будет храниться в том же байте. Столбец в девятом столбце потребует второй байт хранилища. Таблицы с 1-битовым столбцом не получат преимущества для хранения.

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

Ответ 2

Бит... если вы не из клана "true/false/file not found"

Если вы не получили ссылку...

И в случае Linq2SQL бит работает с true/false, что упрощает программирование. Там преимущества для обоих.

И там также должно быть рассмотрено программирование. Что произойдет, если вы (или младший стажер-программист) используете 2, 3, 25, 41, 167, 200 и т.д.? Где это документировано? Биты являются самодокументируемыми и довольно универсальными.

Ответ 3

Я использую биты, когда это необходимо. Помимо семантического правильного типа (семантика count!), Несколько битовых полей (до 8) в одной строке (на SQL Server, во всяком случае) могут быть объединены в один байт хранилища. После восьмого требуется дополнительный байт для следующих 8 и т.д.

Литература:

Ответ 5

Предыдущее сообщение StackOverflow: В чем разница между BIT и TINYINT в MySQL?

При добавлении нового столбца "BOOL" MySQL фактически использует TINYINT.

Я бы просто придерживался BOOL (aka TINYINT) и продолжал жизнь.

Ответ 6

Я использую бит, потому что это избавляет меня от необходимости использовать ограничение проверки, и потому что мой ORM автоматически преобразует бит в нулевое значение boolean (С#), которое я очень ценю после кодирования.

Ответ 7

Все эти теоретические обсуждения велики, но на самом деле, по крайней мере, если вы используете MySQL и действительно для SQLServer, лучше всего придерживаться недвоичных данных для ваших логических элементов по той простой причине, что проще работать когда вы выводите данные, запросы и т.д. Это особенно важно, если вы пытаетесь достичь интероперабельности между MySQL и SQLServer (т.е. Синхронизируете данные между ними), поскольку обработка двух типов данных BIT отличается от двух. Так на практике у вас будет намного меньше проблем, если вы придерживаетесь числового типа данных. Я бы рекомендовал MySQL использовать BOOL или BOOLEAN, который хранится как TINYINT (1). Даже то, как MySQL Workbench и администратор MySQL отображают тип данных BIT, не являются приятными (это маленький символ для двоичных данных). Так что будьте практичны и спасите себя от суеты (и, к сожалению, я говорю по опыту).

Ответ 8

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

Ответ 9

Я просто пытался группировать бит (SQL Server 2k5), и он отлично работал у меня. Мне нравится использовать правильный тип данных для приложения. Если это поле true/false, то бит - это то, что я использую...

Ответ 10

Я не думаю, что видел это выше, но проблема в том, что вы не можете заполнить столбцы BIT (например, MIN, MAX и особенно SUM). Я только что тестировал 2008 год, и проблема все еще там. Это самая большая причина, по которой я использую tinyint в последнее время - другой, мне нравится, как tinyint весы - это всегда боль, когда вашему двузначному биту бит вдруг нужны более возможные значения.

Ответ 11

Нулевое пространство для False

Каким бы ни был ваш выбор, вы можете установить NULL вместо 0, и он не займет лишнего места (поскольку база данных почти всегда имеет флаг NULL для каждого поля каждой строки, просто сидит там; дополнительная информация здесь). Если вы также убедитесь, что значение по умолчанию/наиболее вероятное значение false, вы сэкономите еще больше места!

Некоторое пространство для True

Значение для представления true требует пространства, определенного типом поля; использование BIT будет сохранять только пространство, если таблица имеет несколько таких столбцов, поскольку он использует один байт на 8 полей (по сравнению с TINYINT, который использует один байт на поле).

TINYINT имеет то преимущество, что вы можете настроить 8-значение bitmask, не беспокоясь об управлении множеством дополнительных столбцов, и поиск теоретически быстрее (одно целое поле по сравнению с несколькими битовыми полями). Но есть некоторые недостатки, такие как медленный порядок, причудливый кросс-индексирующий материал и отсутствие названий полей. Который для меня - самая большая потеря; вашей базе данных потребуется внешняя документация, чтобы отметить, какие биты сделали то, в чем битмаски.

В любом случае избегайте соблазна использовать поля TEXT для хранения логических или наборов из них. Поиск через текст - это намного больше работы для сервера, и произвольные схемы именования, такие как "включено, выключено, выключено", могут повредить функциональную совместимость.

Ответ 12

Мы строим все наши таблицы с полем "вектор". Затем мы используем это поле как набор из 32 бит, которые мы можем назначить для любых целей. (Потенциально используя группу бит для набора состояний). Избегает того, что нам нужно добавлять поля флага, если мы забудем.

Ответ 13

@Kevin: Я считаю, что вы можете использовать group by в полях бит (SQL Server 2005):

declare @t table (
    descr varchar(10),
    myBit1 bit, 
    myBit2 bit
)
insert into @t values ('test1', 0, 1)
insert into @t values ('test2', 1, 0)
insert into @t values ('test3', 1, 1)
insert into @t values ('test4', 0, 0)

select myBit1, count(myBit1) from @t group by myBit1
select myBit2, count(myBit1) from @t group by myBit2

Результаты:

myBit1 
------ -----------
0      2
1      2

myBit2 
------ -----------
0      2
1      2

Ответ 15

Мне нравится использовать char (1) с 'T' или 'F'. Да, его можно злоупотреблять с другими значениями, но, по крайней мере, его легко просматривать в отчетах или в других местах, где сложнее работать с битовыми или двоичными значениями.