在MySQL中,zerofill有什么好处?


168

我只是想知道什么是确定的利益/用途ZEROFILL用于INT在数据类型MySQL

`id` INT UNSIGNED ZEROFILL NOT NULL 


好问题。也可能会问相关的问题:是否有充分的理由不使用ZEROFILL?使用ZEROFILL有哪些弊端和潜在陷阱?收益大于弊端吗?
spencer7593 '17

Answers:


254

选择带有类型的列时,ZEROFILL它将用零填充字段的显示值,直到字段定义中指定的显示宽度。大于显示宽度的值不会被截断。请注意,的使用ZEROFILL还意味着UNSIGNED

使用ZEROFILL和显示宽度不会影响数据的存储方式。它仅影响其显示方式。

以下是一些示例SQL演示了如何使用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;

结果:

        x          y
 00000001          1
 00000012         12
 00000123        123
123456789  123456789

52
@diEcho:例如,如果您希望所有发票号以10位数字显示,则可以将该列的类型声明为INT(10)ZEROFILL。
马克·拜尔斯

76
我强烈建议您远离此功能-数字值的显示/格式设置是表示问题,而绝对不是数据库级别的内容。至少在使用数据库备份软件时不会这样。请注意,这可能会引起问题-如果您解析一个以前导零作为整数的值,许多解析器会将其视为八进制,这可能不是您想要的。当您实际存储的是有效的(固定长度)数字字符串时,唯一应该使用此功能的是(存储)优化。
mindplay.dk 2014年

3
@ mindplay.dk:取决于。如果您存储的是GTIN之类的内容,则它们必须为14位数字,但也可以仅为8位数字,并用零左填充。在这种情况下,依靠输出端是不正确的,因为它不仅是小数,而且是键。
DanMan

1
@MarkByers,虽然实际上是说,大多数客户端库(例如PHP)难道不会在将零移交给应用程序代码之前简单地去除零吗?如果是这样,那么看起来确实没有意义。MySQL早期的设计很糟糕。
和平者

131

为了了解一个示例,其中的用法ZEROFILL可能很有趣:

在德国,我们有5位邮政编码。但是,这些代码可能以零开头,因此80337对于munic 01067是有效的邮政编码,是Berlin的邮政编码。

如您所见,任何德国公民都希望邮政编码显示为5位数字的代码,因此1067看起来很奇怪。

为了存储这些数据,您可以使用VARCHAR(5)或,INT(5) ZEROFILL而零填充整数有两个很大的优点:

  1. 减少硬盘上的存储空间
  2. 如果您插入1067,您仍然会01067回来

也许这个例子有助于理解的使用ZEROFILL


10
值得补充的是,显示数据的SQL客户端负责格式化带前导零的数字。这并不是每个应用程序都在自动获取数据的过程。
a_horse_with_no_name 2014年

固定宽度的列也更好,因为它们减少了磁盘碎片。
DanMan 2014年

@Phil,实际上,尽管如此,大多数客户端库(例如PHP)难道不会在将零移交给应用程序代码之前简单地将零去除吗?如果是这样,那么看起来确实没有意义。MySQL早期的设计很糟糕。
和平者

3
@Pacerier这取决于您希望如何表示客户端库中的数据:数字或字符串。德语邮政编码不是数字,而是仅包含数字的字符串。因此,我不同意您在MySQL早期关于不良设计的说法。它仍然是一种有效的方法,但是在极少数情况下。
2015年


15

如果您需要将此“整数”与其他内容(另一个数字或文本)连接在一起,那么这将有助于正确排序,然后需要将其分类为“文本”。

例如,

如果您需要使用连接为A-005或10/0005 的整数字段编号(比方说5)


4

我知道我参加聚会很晚,但是我发现Zerofill对于TINYINT(1)的布尔表示很有帮助。Null并不总是意味着False,有时您不希望如此。通过对tinyint进行零填充,可以有效地将这些值转换为INT并消除应用程序在交互时可能造成的任何混乱。然后,您的应用程序可以类似于原始数据类型True = Not(0)的方式处理这些值。


1
谢谢,但是不幸的是,我只是针对mysql数据库运行了一些测试,并且它不会将null值填零:-/。通过限制字段不允许为空,仍然可以实现该目标。我应该比尝试回答有关我通常不使用的dbs的问题更好地了解。在人们太不高兴之前要删除我的答案。大声笑
马林

1
有用?不对 ZEROFILL不执行任何操作(除附加无符号)时的显示长度为1
Brilliand

@Marlin,您应该始终将默认值设置为true或false ...如果您不使用默认值,那么您提到的问题将不是唯一的... NOT NULL也是必须的:)
bakriawad 2014年

我会投票反对,但您的代表在,666所以我宁愿保留这个答案;-)
马丁

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

如果为数字列指定ZEROFILL,MySQL会自动将UNSIGNED属性添加到该列。

允许UNSIGNED属性的数值数据类型也允许SIGNED。但是,这些数据类型默认情况下是带符号的,因此SIGNED属性无效。

以上描述摘自MYSQL官方网站。


0

零填充

这本质上意味着,如果将整数值23插入宽度为8的INT列中,则其余可用位置将自动填充零。

因此

23

变成:

00000023
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.