Qual é o benefício de zerofill no MySQL?


168

Eu só quero saber qual é o benefício / uso da definição ZEROFILLpara INTDataType no MySQL?

`id` INT UNSIGNED ZEROFILL NOT NULL 


Boa pergunta. Perguntas relacionadas que também podem ser feitas: Existem boas razões para não usar o ZEROFILL? Quais são as desvantagens e possíveis armadilhas do uso do ZEROFILL? Os benefícios superam as desvantagens?
Spencer7593

Respostas:


254

Quando você seleciona uma coluna com o tipo, ZEROFILLela preenche o valor exibido do campo com zeros até a largura de exibição especificada na definição da coluna. Valores maiores que a largura da exibição não são truncados. Observe que o uso de ZEROFILLtambém implica UNSIGNED.

O uso ZEROFILLe a largura de exibição não afetam como os dados são armazenados. Afeta apenas como é exibida.

Aqui está um exemplo de SQL que demonstra o uso de ZEROFILL:

CREATE TABLE yourtable (x INT(8) ZEROFILL NOT NULL, y INT(8) NOT NULL);
INSERT INTO yourtable (x,y) VALUES
(1, 1),
(12, 12),
(123, 123),
(123456789, 123456789);
SELECT x, y FROM yourtable;

Resultado:

        x          y
 00000001          1
 00000012         12
 00000123        123
123456789  123456789

52
@diEcho: se, por exemplo, você deseja que todos os seus números de fatura sejam exibidos com 10 dígitos, você pode declarar o tipo dessa coluna como INT (10) ZEROFILL.
Mark Byers

76
Eu recomendo que você fique longe desse recurso - como um valor numérico é exibido / formatado é uma preocupação de apresentação e absolutamente não é algo que pertence ao nível do banco de dados; pelo menos não se você estiver usando o banco de dados para fazer backup de um software. Esteja ciente de que isso pode causar problemas - se você analisar um valor com um zero à esquerda como um número inteiro, muitos analisadores considerarão o valor como octal, o que provavelmente não é o que você deseja. O único momento em que você deve usar esse recurso é como uma otimização (armazenamento), quando o que você está realmente armazenando é efetivamente uma sequência de dígitos (de comprimento fixo).
mindplay.dk

3
@ mindplay.dk: depende. Se você estiver armazenando algo como um GTIN, eles devem ter 14 dígitos, mas também podem ter apenas 8 dígitos e preenchidos à esquerda com zeros. Contar com o lado da saída não seria correto neste caso, porque não é simplesmente um decimal, mas uma chave.
DanMan

1
@ MarkByers, na prática, porém, a maioria das bibliotecas clientes (por exemplo, PHP) simplesmente não retira os zeros antes de entregá-los ao código do aplicativo? Se assim for, então realmente parece um pouco inútil. Um design ruim nos primeiros dias do MySQL.
Pacerier 21/05

131

Um exemplo para entender, onde o uso de ZEROFILLpode ser interessante:

Na Alemanha, temos códigos postais de 5 dígitos. No entanto, esses códigos podem começar com um zero, assim 80337como um CEP válido para munic, 01067é um CEP de Berlim.

Como você vê, qualquer cidadão alemão espera que os códigos postais sejam exibidos como um código de 5 dígitos, então isso 1067parece estranho.

Para armazenar esses dados, você pode usar um VARCHAR(5)ou INT(5) ZEROFILLenquanto o inteiro preenchido com zerar tem duas grandes vantagens:

  1. Muito menos espaço de armazenamento no disco rígido
  2. Se você inserir 1067, você ainda 01067volta

Talvez este exemplo ajude a entender o uso de ZEROFILL.


10
Vale acrescentar que o cliente SQL que exibe os dados é responsável por formatar os números com zeros à esquerda. Isso não é algo que "automagicamente" acontece com cada aplicativo que recupera os dados.
a_horse_with_no_name

As colunas de largura fixa também são melhores, porque reduzem a fragmentação no disco.
DanMan

@ Phil, na prática, porém, a maioria das bibliotecas clientes (por exemplo, PHP) simplesmente não retira os zeros antes de entregá-los ao código do aplicativo? Se assim for, então realmente parece um pouco inútil. Um projeto ruim nos primeiros dias do MySQL.
Pacerier 21/05

3
@Pacerier Depende de como você deseja que os dados da sua biblioteca cliente sejam representados: como número ou como sequência. Um CEP alemão não é um número, é apenas uma sequência de dígitos. Portanto, eu discordo de sua declaração de mau design nos primeiros dias do MySQL. Ainda é uma abordagem válida, mas para casos raros.
Phil

61

É um recurso para personalidades perturbadas que gostam de caixas quadradas.

Você insere

1
23
123 

mas quando você seleciona, ele preenche os valores

000001
000023
000123

15

Ajuda na classificação correta no caso em que você precisará concatenar esse "número inteiro" com outra coisa (outro número ou texto) que precisará ser classificada como "texto".

por exemplo,

se você precisar usar os números dos campos inteiros (digamos 5) concatenados como A-005 ou 10/0005


4

Sei que estou atrasado para a festa, mas acho que o zerofill é útil para representações booleanas de TINYINT (1). Nulo nem sempre significa Falso, às vezes você não quer. Ao preencher um minúsculo, você efetivamente converte esses valores em INT e remove qualquer confusão que seu aplicativo possa ter durante a interação. Seu aplicativo pode tratar esses valores de maneira semelhante ao tipo de dados primitivo True = Not (0)


1
Obrigado, mas infelizmente acabei de executar alguns testes em um banco de dados mysql e ele não zerofill valores nulos: - /. Esse objetivo ainda é alcançado restringindo o campo a não permitir nulo. Eu deveria saber melhor do que tentar responder a perguntas sobre dbs que eu não costumo usar. Vou excluir minha resposta antes que as pessoas fiquem com muito voto negativo. lol
Marlin

1
Útil? Está incorreto. Zerofill não faz nada (exceto adiciona Não assinado) quando o tamanho da tela é 1. #
20illanndnd

@ Marlin e você deve sempre definir um valor padrão para true ou false ... se você não usar valores padrão, o problema que você mencionou NÃO será o único ... NOT NULL é obrigatório também :)
bakriawad

Eu downvote, mas o seu representante é a 666que eu prefiro manter esta resposta como for;-)
Martin

3
mysql> CREATE TABLE tin3(id int PRIMARY KEY,val TINYINT(10) ZEROFILL);
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO tin3 VALUES(1,12),(2,7),(4,101);
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM tin3;
+----+------------+
| id | val        |
+----+------------+
|  1 | 0000000012 |
|  2 | 0000000007 |
|  4 | 0000000101 |
+----+------------+
3 rows in set (0.00 sec)

mysql>

mysql> SELECT LENGTH(val) FROM tin3 WHERE id=2;
+-------------+
| LENGTH(val) |
+-------------+
|          10 |
+-------------+
1 row in set (0.01 sec)


mysql> SELECT val+1 FROM tin3 WHERE id=2;
+-------+
| val+1 |
+-------+
|     8 |
+-------+
1 row in set (0.00 sec)


1

Se você especificar ZEROFILL para uma coluna numérica, o MySQL adicionará automaticamente o atributo UNSIGNED à coluna.

Os tipos de dados numéricos que permitem o atributo UNSIGNED também permitem SIGNED. No entanto, esses tipos de dados são assinados por padrão, portanto, o atributo SIGNED não tem efeito.

A descrição acima é retirada do site oficial do MYSQL.


0

PREENCHIMENTO ZERO

Isto significa essencialmente que, se o valor inteiro 23 for inserido em uma coluna INT com a largura de 8, o restante da posição disponível será preenchido automaticamente com zeros.

Conseqüentemente

23

torna-se:

00000023
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.