基本问题是
char
将用空格填充值,这可能会导致一些令人惊讶和不一致的结果。
这里我们看到postgres保留了尾随空间。
test=> create table foo ( c char(10), v varchar(10) );
CREATE TABLE
test=> insert into foo values ('foo', 'foo');
INSERT 0 1
test=> select * from foo;
c | v
------------+-----
foo | foo
test=> select concat(c, '>'), concat(v, '>') from foo where c = 'foo ';
concat | concat
-------------+--------
foo > | foo>
但MySQL不会,除非
PAD_CHAR_TO_FULL_LENGTH
被设置。
mysql> create table foo ( c char(10), v varchar(10) );
mysql> insert into foo values ('foo', 'foo');
mysql> select * from foo;
+------+------+
| c | v |
+------+------+
| foo | foo |
+------+------+
mysql> select concat(c, '>'), concat(v, '>') from foo where c = 'foo ';
+----------------+----------------+
| concat(c, '>') | concat(v, '>') |
+----------------+----------------+
| foo> | foo> |
+----------------+----------------+
mysql> set sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
mysql> select concat(c, '>'), concat(v, '>') from foo where c = 'foo ';
+----------------+----------------+
| concat(c, '>') | concat(v, '>') |
+----------------+----------------+
| foo > | foo> |
+----------------+----------------+
The PostgreSQL documentation
概述了几个问题。
类型字符的值在物理上用空格填充到指定的宽度n,
并以这种方式存储和显示
.
…在比较类型character的两个值时,尾随空格被视为语义无关紧要的空格,并且被忽略。在空白显著的排序规则中,此行为可能会产生意外的结果;例如
SELECT 'a '::CHAR(2) collate "C" < E'a\n'::CHAR(2)
返回true,即使C语言环境将空格视为大于换行符
将字符值转换为其他字符串类型时,将删除尾随空格。
存储引擎已经改进到几乎没有理由使用
烧焦
不再。
这三种类型之间没有性能差异,除了使用空白填充类型时增加存储空间,以及在存储到长度受限列中时,检查CPU长度的一些额外CPU周期。虽然character(n)在其他一些数据库系统中具有性能优势,但是postgresql中没有这样的优势;
事实上,字符(n)通常是这三个字符中最慢的一个,因为它有额外的存储成本。
在大多数情况下,应使用不同的文本或字符。
其中一例
烧焦
可以
被证明是存储非常小,固定大小的字符串。例如,
ISO 2 character country codes
可能存储为
char(2)
. 但在如此小的字符串上,不太可能注意到性能差异。
烧焦
头痛是最好避免的。