char在各种数据库中都被支持,用来存储较短的字符串,当然MySQL和Oracle也都有,但是却有一些不同之处,我们先来看个例子。
MySQL中,创建一个表,包含数据类型为char(4)的列c,并插入数据。
root@database-one 20:37: [(none)]> use gftest
Database changed
root@database-one 20:37: [gftest]> create table vc(v varchar(4),c char(4));
Query OK, 0 rows affected (0.19 sec)
root@database-one 20:37: [gftest]> insert into vc values('ab ','ab ');
Query OK, 1 row affected (0.01 sec)
root@database-one 20:38: [gftest]> commit;
Query OK, 0 rows affected (0.00 sec)
root@database-one 20:38: [gftest]> select length(v),length(c) from vc;
+-----------+-----------+
| length(v) | length(c) |
+-----------+-----------+
| 4 | 2 |
+-----------+-----------+
1 row in set (2.45 sec)
通过查询发现,char列插入的值是4个长度的字符串,但查询时,长度却是2。追加一个字符可以看得更清晰:
root@database-one 20:38: [gftest]> select concat(v,'+'),concat(c,'+') from vc;
+---------------+---------------+
| concat(v,'+') | concat(c,'+') |
+---------------+---------------+
| ab + | ab+ |
+---------------+---------------+
1 row in set (0.01 sec)
char列最后的空格已经被删除。我们再插入一条记录看看:
root@database-one 20:39: [gftest]> insert into vc values('cd','cd');
Query OK, 1 row affected (0.01 sec)
root@database-one 20:39: [gftest]> commit;
Query OK, 0 rows affected (0.00 sec)
root@database-one 20:39: [gftest]> select concat(v,'+'),concat(c,'+') from vc;
+---------------+---------------+
| concat(v,'+') | concat(c,'+') |
+---------------+---------------+
| ab + | ab+ |
| cd+ | cd+ |
+---------------+---------------+
2 rows in set (3.15 sec)
插入的’cd’,查询结果继续是’cd’。
同样的例子,我们在Oracle中看看效果:
SQL*Plus: Release 11.2.0.4.0 Production on Tue Feb 11 20:41:56 2020
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> create table vc(v varchar(4),c char(4));
Table created.
SQL> insert into vc values('ab ','ab ');
1 row created.
SQL> commit;
Commit complete.
SQL> select length(v),length(c) from vc;
LENGTH(V) LENGTH(C)
---------- ----------
4 4
SQL> select concat(v,'+'),concat(c,'+') from vc;
CONCAT(V,'+') CONCAT(C,'+')
--------------- ---------------
ab + ab +
看到没有,char列插入的值是4个长度的字符串,查询时,长度继续是4,空格继续在。我们再插入一条记录看看:
SQL> insert into vc values('cd','cd');
1 row created.
SQL> commit;
Commit complete.
SQL> select concat(v,'+'),concat(c,'+') from vc;
CONCAT(V,'+') CONCAT(C,'+')
--------------- ---------------
ab + ab +
cd+ cd +
插入的’cd’,查询结果多了2个空格。
为什么会这样呢?我们去官方文档中找找答案。
MySQL官方文档对其CHAR说明中有下面一段:
The length of a CHAR column is fixed to the length that you declare when you create the table. The length can be any value from 0 to 255. When CHAR values are stored, they are right-padded with spaces to the specified length. When CHAR values are retrieved, trailing spaces are removed unless the PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled.
CHAR列的长度固定为创建表时声明的长度。长度可以是0到255之间的任意值。在存储CHAR值时,会用空格将其右填充到指定的长度。检索CHAR值时,除非启用PAD_CHAR_TO_FULL_LENGTH SQL模式,否则将删除尾随空格。
Oracle官方文档对其CHAR说明中有下面一段:
The CHAR data type specifies a fixed-length character string. Oracle ensures that all values stored in a CHAR column have the length specified by size. If you insert a value that is shorter than the column length, then Oracle blank-pads the value to column length. If you try to insert a value that is too long for the column, then Oracle returns an error.
CHAR数据类型指定固定长度的字符串。Oracle确保存储在CHAR列中的所有值都具有由size指定的长度。如果插入的值小于列长度,则Oracle blank将该值填充到列长度。如果您尝试插入的值对于列太长,则Oracle将返回一个错误。
至此,真相大白啦,原来MySQL和Oracle在存储char时,如果值长度不够,都会填充,区别在于检索(读取)时,MySQL默认(因为默认情况下PAD_CHAR_TO_FULL_LENGTH SQL模式不开启)会删除右侧空格,而Oracle却不会。
你更喜欢哪家的处理方式,为什么呢?
© 2020, morinson. 版权所有. 欢迎转载,但请保留作者及出处。