Confusão BOOLEAN ou TINYINT

90

Eu estava projetando um banco de dados para um site onde preciso usar um tipo de dados booleano para armazenar apenas 2 estados, verdadeiro ou falso. Estou usando o MySQL.
Ao projetar o banco de dados usando phpMyAdmin, descobri que tenho os tipos de dados BOOLEAN e TINYINT.
Eu li artigos diferentes, alguns disseram que TINYINT é igual ao BOOLEAN, sem diferença. Alguns dizem que o BOOLEAN é convertido em TINYINT no MySQL.

MINHA pergunta é, se ambos são iguais, por que existem dois? Deve haver apenas um deles.

Aqui está a referência aos artigos que li:
http://www.careerride.com/MySQL-BOOL-TINYINT-BIT.aspx
http://dev.mysql.com/doc/refman/5.5/en/numeric-type -overview.html

Bipin Chandra Tripathi
fonte

Respostas:

135

O MySQL não possui tipo de dados booleano interno. Ele usa o menor tipo de dados inteiro - TINYINT.

O BOOLEAN e o BOOL são equivalentes a TINYINT (1), porque são sinônimos.

Tente criar esta tabela -

CREATE TABLE table1 (
  column1 BOOLEAN DEFAULT NULL
);

Em seguida, execute SHOW CREATE TABLE, você obterá esta saída -

CREATE TABLE `table1` (
  `column1` tinyint(1) DEFAULT NULL
)
Devart
fonte
1
Mas sua resposta está correta em todos os outros aspectos. O que parece confundir o OP é a existência de sinônimos.
ypercubeᵀᴹ
2
Parece que isso é feito para compatibilidade com versões anteriores. O tipo de dados BOOLEAN era anterior ao MySQL 5 e o tipo de BIT não era otimizado, também era TINYINT. Da documentação - Novos recursos planejados para 5.1: Otimize o tipo de BIT para levar um bit. (BIT agora leva um byte; ele é tratado como um sinônimo de TINYINT.).
Devart
5
Sim, você pode saber têm BIT(1)ou BIT(17)ou mesmoBIT(64)
ypercubeᵀᴹ
3
@Devart - Onde sua resposta tem mais votos e aparece primeiro (na minha lista de qualquer maneira) e algum tempo já passou, há alguma chance de você estar disposto a adicionar à sua resposta para incluir alguma discussão sobre o tipo BIT no MySQL 5.1 e mais tarde?
Jonathan
3
@Jonathan Talvez mencioná-lo seja valioso, no entanto BIT (1) não usa menos espaço do que TINYINT (1) e não é exibido como a maioria das pessoas esperaria ao usar o console mysql padrão. Por causa dessa desvantagem, e nenhum benefício de armazenamento, apenas usar TINYINT (1) ou BOOLEAN parece ser o mais comum em minha experiência.
Tyler Smith
31

Apenas uma nota para os desenvolvedores de php (não tenho os pontos stackoverflow necessários para postar isso como um comentário) ... a conversão de automagic (e silent) para TINYINT significa que php recupera um valor de uma coluna "BOOLEAN" como um "0" ou "1", não é o esperado (por mim) verdadeiro / falso.

Um desenvolvedor que está olhando para o SQL usado para criar uma tabela e vê algo como: "some_boolean BOOLEAN NOT NULL DEFAULT FALSE," pode razoavelmente esperar ver resultados verdadeiro / falso quando uma linha contendo aquela coluna é recuperada. Em vez disso (pelo menos na minha versão do PHP), o resultado será "0" ou "1" (sim, uma string "0" ou uma string "1", não um int 0/1, obrigado php).

É uma nit, mas o suficiente para fazer com que os testes de unidade falhem.

Tom Stambaugh
fonte
2
Como uma observação adicional, os drivers mysql do PHP puxam todos os tipos inteiros como strings.
kojow7
24

As versões mais recentes do MySQL possuem o novo BITtipo de dados em que você pode especificar o número de bits no campo, por exemplo BIT(1)para usar como Booleantipo, porque pode ser apenas 0ou 1.

Please_Dont_Bully_Me_SO_Lords
fonte
7

A partir da referência da versão MySql 5.1

BIT(M) =  approximately (M+7)/8 bytes, 
BIT(1) =  (1+7)/8 = 1 bytes (8 bits)

========================================================== =========================

TINYINT(1) take 8 bits.

https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html#data-types-storage-reqs-numeric

fortuna
fonte
1
Sua referência diz que o armazenamento necessário é na verdade "aproximadamente (M + 7) / 8 bytes". ou seja, ele arredonda para o próximo byte completo. Portanto, não leva 1 bit.
MPEN