Какой тип данных MySQL используется для хранения логических значений
====================================================================

Так как MySQL, похоже, не имеет никакого "логического" типа данных, какой тип данных вы "злоупотребляете" для хранения истинной/ложной информации в MySQL?

Особенно в контексте написания и чтения из/в PHP script.

Со временем я использовал и видел несколько подходов:

* tinyint, поля varchar, содержащие значения 0/1,
* поля varchar, содержащие строки '0'/'1' или 'true'/'false'
* и, наконец, перечислить поля, содержащие два параметра: "true" / "false".

Ничто из вышеизложенного не кажется оптимальным. Я предпочитаю вариант tinyint 0/1, поскольку автоматическое преобразование типов в PHP дает мне логические значения довольно просто.

Какой тип данных вы используете? Есть ли тип, предназначенный для булевых значений, которые я забыл? Вы видите какие-либо преимущества/недостатки, используя тот или иной тип?

 

 Для MySQL 5.0.3 и выше вы можете использовать `BIT`. В руководстве сказано:

 
>   Начиная с MySQL 5.0.3, тип данных BIT используется для хранения значений битовых полей. Тип BIT (M) позволяет хранить M-битные значения. М может варьироваться от 1 до 64.
> 
> 

  В противном случае, согласно руководству по MySQL, вы можете использовать bool и boolean, которые на данный момент являются псевдонимами [tinyint](http://dev.mysql.com/doc/refman/5.7/en/integer-types.html) (1):

 
>   Bool, Boolean: Эти типы являются синонимами для [tinyint](http://dev.mysql.com/doc/refman/5.7/en/integer-types.html) (1). Нулевое значение считается ложным. Ненулевые значения считаются истинными.
> 
> 

 .i1a { width: 336px; height: 280px; }
 @media(min-width: 768px) { .i1a { width: 728px; height: 90px; } }
 @media(min-width: 992px) { .i1a { width: 360px; height: 300px; } }
 @media(min-width: 1083px) { .i1a { width: 728px; height: 90px; } }

 (adsbygoogle = window.adsbygoogle || []).push({});

 MySQL также заявляет, что:

 
>   Мы намерены реализовать полную обработку булевых типов в соответствии со стандартным SQL в будущем выпуске MySQL.
> 
> 

  Ссылки: <http://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html>

 

 `BOOL` и `BOOLEAN` являются синонимами `TINYINT(1)`. Ноль `false`, все остальное `true`. Подробнее [здесь](http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html).

 .i2a { width: 336px; height: 280px; }
 @media(min-width: 768px) { .i2a { width: 728px; height: 90px; } }
 @media(min-width: 992px) { .i2a { width: 360px; height: 300px; } }
 @media(min-width: 1083px) { .i2a { width: 728px; height: 90px; } }

 (adsbygoogle = window.adsbygoogle || []).push({});



Это изящное решение, которое я вполне понимаю, потому что он использует нулевые байты данных:

```
some_flag CHAR(0) DEFAULT NULL

```

Чтобы установить значение true, установите `some_flag = ''` и установите для него значение false, установите `some_flag = NULL`.

Затем, чтобы проверить значение true, проверьте, есть ли some\_flag `IS NOT NULL`, и чтобы проверить значение false, проверьте, не some\_flag `IS NULL`.

(Этот метод описан в разделе "Высокопроизводительная MySQL: оптимизация, резервное копирование, репликация и многое другое" Джона Уоррена Ленца, Барона Шварца и Арьена Ленца.)

 

На этот вопрос был дан ответ, но я решил, что брошу свои $0,02. Я часто использую CHAR (0), где '' == true и NULL == false.

От [mysql docs](http://dev.mysql.com/doc/refman/5.0/en/string-type-overview.html)

>   CHAR (0) также очень приятно, когда вам нужен столбец, который может принимать только два значения: столбец, который определяется как CHAR (0) NULL, занимает только один бит и может принимать только значения NULL и '' (пустая строка).
> 
> 
> 

 

Если вы используете тип BOOLEAN, это псевдоним TINYINT (1). Это лучше всего, если вы хотите использовать стандартизованный SQL и не против, чтобы поле могло содержать значение вне диапазона (в основном все, что не равно 0, будет "истинным" ).

ENUM ( "False", "True" ) позволит вам использовать строки в вашем SQL, а MySQL будет хранить это поле внутри себя как целое число, где "False" = 0 и "True" = 1 на основе порядка Указано Enum.

В MySQL 5+ вы можете использовать поле BIT (1) для указания 1-битного числового типа. Я не верю, что это фактически использует меньше места в хранилище, но снова позволяет ограничить возможные значения 1 или 0.

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

 

Я использую TINYINT (1) для хранения логических значений в Mysql.

Я не знаю, есть ли какие-либо преимущества для использования этого... Но если я не ошибаюсь, mysql может хранить логическое значение (BOOL) и хранить его как tinyint (1)

 <http://dev.mysql.com/doc/refman/5.0/en/other-vendor-data-types.html>

 

Бит полезен только по различным байтовым опциям (tinyint, enum, char (1)), если у вас много логических полей. Одно битовое поле по-прежнему занимает полный байт. Два битовых поля вписываются в тот же самый байт. Три, четыре, пять, шесть, семь, восемь. После чего они начинают заполнять следующий байт. В конечном итоге экономия настолько мала, что вам нужно сосредоточиться на тысячах других оптимизаций. Если вы не имеете дело с огромным количеством данных, эти несколько байтов не будут сильно отличаться. Если вы используете бит с PHP, вам нужно придать значения значениям входов и выходов.

 

 До тех пор, пока MySQL не реализует битовый тип данных, если ваша обработка действительно ограничена пространством и/или временем, например, при транзакциях большого объема, создайте поле `bit_flags` именем `bit_flags` для всех ваших логических переменных и маскируйте и `bit_flags` логический бит, который вы хотите в своем SQL-запрос.

  Например, если ваш самый левый бит представляет ваше поле bool, а 7 самых правых битов ничего не представляют, тогда ваше поле `bit_flags` будет равно 128 (двоичный код 10000000). Маскируйте (скрывайте) семь крайних правых битов (используя побитовый оператор `&`) и сдвигайте 8-й бит на семь пробелов вправо, заканчивая 00000001. Теперь все значение (которое в данном случае равно 1) является вашим значением.

 
```
SELECT (t.bit_flags & 128) >> 7 AS myBool FROM myTable t;

if bit_flags = 128 ==> 1 (true)
if bit_flags = 0 ==> 0 (false)

```
  Вы можете запускать такие заявления во время тестирования

 
```
SELECT (128 & 128) >> 7;

SELECT (0 & 128) >> 7;

```
  и т.п.

  Поскольку у вас есть 8 битов, у вас есть потенциально 8 логических переменных из одного байта. Некоторые будущие программисты будут неизменно использовать следующие семь битов, поэтому вы должны замаскировать. Не сдвигайся, иначе ты будешь создавать ад для себя и других в будущем. Убедитесь, что MySQL выполняет маскирование и сдвиг - это будет значительно быстрее, чем это делает язык веб-сценариев (PHP, ASP и т.д.). Также убедитесь, что вы `bit_flags` комментарий в поле комментариев MySQL для своего поля `bit_flags`.

  Вы найдете эти сайты полезными при реализации этого метода:

 * [MySQL - битовые функции и операторы](http://dev.mysql.com/doc/refman/5.0/en/bit-functions.html)
* [Десятичное/двоичное средство преобразования](http://acc6.its.brooklyn.cuny.edu/~gurwitz/core5/nav2tool.html)

 

Мне надоело пытаться получить нули, NULLS и "точно округлить петлю значений PHP, MySql и POST, поэтому я просто использую" Да "и" Нет ".

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

 

Ссылаясь на эту ссылку   [Boolean datatype в Mysql](https://dba.stackexchange.com/questions/28422/what-is-the-benefit-of-using-boolean-over-tinyint1), в зависимости от использования приложения, если нужно сохранить только 0 или 1, лучше выбрать бит (1).

 

 Прочитав ответы здесь, я решил использовать `bit(1)` и да, это как-то лучше в пространстве/времени, **НО** через некоторое время я передумал и никогда больше не буду его использовать. Это сильно усложнило мою разработку при использовании готовых операторов, библиотек и т.д. (Php).

  С тех пор я всегда использую `tinyint(1)`, кажется достаточно хорошим.

 

 Поскольку MySQL (8.0.16) и MariaDB (10.2.1) реализовали ограничение CHECK, я бы сейчас использовал

 
```
bool_val TINYINT CHECK(bool_val IN(0,1))

```
  Вы сможете хранить только `0`, `1` или `NULL`, а также значения, которые можно преобразовать в `0` или `1` без ошибок, таких как `'1'`, `0x00`, `b'1'` или `TRUE`/`FALSE`.

  Если вы не хотите разрешать значения NULL, добавьте параметр `NOT NULL`

 
```
bool_val TINYINT NOT NULL CHECK(bool_val IN(0,1))

```
  Обратите внимание, что практически нет разницы, если вы используете `TINYINT`, `TINYINT(1)` или `TINYINT(123)`.

  Если вы хотите, чтобы ваша схема была совместимой вверх, вы также можете использовать `BOOL` или `BOOLEAN`

 
```
bool_val BOOL CHECK(bool_val IN(TRUE,FALSE))

```
  [ДБ <> Fiddle Demo](https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=a029601f37296a7e712c096d03d94b1d)