Qual é o significado de tinyint (N)?

17

Quando usamos um comprimento de argumento com tipos de dados numéricos, até onde eu sei, isso especifica a largura da exibição.
Eu tentei o seguinte:

mysql> create table boolean_test (var1 boolean, var2 tinyint);    
Query OK, 0 rows affected (0.10 sec)   

mysql> show create table boolean_test;   
+--------------+-------------------------   
| Table        | Create Table
+--------------+-------------------------  
| boolean_test | CREATE TABLE `boolean_test` (  
  `var1` tinyint(1) DEFAULT NULL,  
  `var2` tinyint(4) DEFAULT NULL  
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |   
+--------------+---------------------------  
1 row in set (0.00 sec)  

Primeiro de tudo, tinyint é um valor de 1 byte. Então, qual é o significado de tinyint(4)? Não pode haver 4 dígitos.

mysql> insert into boolean_test values(101,112);  
Query OK, 1 row affected (0.03 sec)   

mysql> select * from boolean_test;  
+------+------+  
| var1 | var2 |  
+------+------+  
|   10 |  112 |  
|  101 |  112 |  
+------+------+  
2 rows in set (0.00 sec)  

Vejo que em tinyint eu armazenei um 10 e 101 e poderia recuperar esses valores, apesar de ser definido como tinyint (1).
Eu não deveria ver um 1 para var1? Ou seja, apenas 1 dígito de exibição?

Cratylus
fonte
Por que você tem duas linhas após uma inserção? Não consigo entender completamente esse código.
WoodrowShigeru 02/07/19

Respostas:

24

Data-sábio, tinyint(1), tinyint(2), tinyint(3)etc, são todos exatamente o mesmo. Eles estão todos no intervalo -128 a 127 para SIGNEDou 0-255 para UNSIGNED. Como outras respostas observaram, o número entre parênteses é apenas uma dica de largura de exibição.

Você pode notar, porém, que application = wise things podem parecer diferentes. Aqui, tinyint(1)pode ter um significado especial. Por exemplo, o Connector / J (conector Java) trata tinyint(1)como um valor booleano e, em vez de retornar um resultado numérico ao aplicativo, converte valores em truee false. isso pode ser alterado através do tinyInt1isBit=falseparâmetro de conexão.

Shlomi Noach
fonte
13

Um tinyint (1) pode conter números no intervalo de -128 a 127, devido ao tipo de dados ter 8 bits (1 byte) - obviamente, um tinyint não assinado pode conter valores de 0 a 255.

Ele silenciosamente truncará valores fora do intervalo:

mysql> create table a
    -> (
    ->    ttt tinyint(1)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into a values ( 127 );
Query OK, 1 row affected (0.00 sec)

mysql> insert into a values ( -128 );
Query OK, 1 row affected (0.00 sec)

mysql> insert into a values ( 128 );
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> insert into a values ( -129 );
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from a;
+------+
| ttt  |
+------+
|  127 |
| -128 |
|  127 |
| -128 |
+------+
4 rows in set (0.00 sec)

mysql>

... a menos que você altere sql_modeou altere a configuração do servidor:

mysql> set sql_mode=STRICT_ALL_TABLES;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into a values ( -129 );
ERROR 1264 (22003): Out of range value for column 'ttt' at row 1
mysql>

O valor usado no DDL para o tipo de dados (por exemplo: tinyint (1)) é, como você suspeitou, a largura de exibição. No entanto, é opcional e os clientes não precisam usá-lo. O cliente MySQL padrão não o usa, por exemplo.

Philᵀᴹ
fonte