文本数据类型和字符变化(varchar)数据类型之间的区别是什么?
根据文档
如果使用不带长度说明符的字符变化,则该类型接受任何大小的字符串。后者是PostgreSQL的扩展。
and
此外,PostgreSQL还提供了文本类型,用于存储任意长度的字符串。尽管类型text不在SQL标准中,但其他几个SQL数据库管理系统也具有它。
那么有什么不同呢?
文本数据类型和字符变化(varchar)数据类型之间的区别是什么?
根据文档
如果使用不带长度说明符的字符变化,则该类型接受任何大小的字符串。后者是PostgreSQL的扩展。
and
此外,PostgreSQL还提供了文本类型,用于存储任意长度的字符串。尽管类型text不在SQL标准中,但其他几个SQL数据库管理系统也具有它。
那么有什么不同呢?
当前回答
character varying(n), varchar(n) -(两者相同)。值将被截断为n个字符而不引发错误。 character(n), char(n) -(都是一样的)。固定长度,并将空白垫至长度结束。 文本-无限长度。
例子:
Table test:
a character(7)
b varchar(7)
insert "ok " to a
insert "ok " to b
我们得到了结果:
a | (a)char_length | b | (b)char_length
----------+----------------+-------+----------------
"ok "| 7 | "ok" | 2
其他回答
在我看来,varchar(n)有它自己的优点。是的,它们都使用相同的底层类型等等。但是,应该指出的是,PostgreSQL中的索引有其每行2712字节的大小限制。
TL;博士: 如果您使用无约束的文本类型,并且在这些列上有索引,则很可能在某些列上达到此限制,并在尝试插入数据时出错,但使用varchar(n)可以防止这种情况。
Some more details: The problem here is that PostgreSQL doesn't give any exceptions when creating indexes for text type or varchar(n) where n is greater than 2712. However, it will give error when a record with compressed size of greater than 2712 is tried to be inserted. It means that you can insert 100.000 character of string which is composed by repetitive characters easily because it will be compressed far below 2712 but you may not be able to insert some string with 4000 characters because the compressed size is greater than 2712 bytes. Using varchar(n) where n is not too much greater than 2712, you're safe from these errors.
(这个答案是Wiki,你可以编辑-请改正和改进!)
更新2016年基准(pg9.5+)
使用“纯SQL”基准测试(不需要任何外部脚本)
使用UTF8的任何string_generator 主要指标:
2.1. 插入
2.2. 选择比较和计数
CREATE FUNCTION string_generator(int DEFAULT 20,int DEFAULT 10) RETURNS text AS $f$
SELECT array_to_string( array_agg(
substring(md5(random()::text),1,$1)||chr( 9824 + (random()*10)::int )
), ' ' ) as s
FROM generate_series(1, $2) i(x);
$f$ LANGUAGE SQL IMMUTABLE;
准备具体的测试(示例)
DROP TABLE IF EXISTS test;
-- CREATE TABLE test ( f varchar(500));
-- CREATE TABLE test ( f text);
CREATE TABLE test ( f text CHECK(char_length(f)<=500) );
执行基本测试:
INSERT INTO test
SELECT string_generator(20+(random()*(i%11))::int)
FROM generate_series(1, 99000) t(i);
还有其他测试,
CREATE INDEX q on test (f);
SELECT count(*) FROM (
SELECT substring(f,1,1) || f FROM test WHERE f<'a0' ORDER BY 1 LIMIT 80000
) t;
... 并使用EXPLAIN ANALYZE。
2018年再次更新(pg10)
小小的编辑增加了2018年的结果,并加强了建议。
2016年和2018年的结果
我的结果,在许多机器和许多测试中,经过平均后:都是一样的(统计上小于标准偏差)。
建议
使用文本数据类型,避免旧的varchar(x),因为有时它不是一个标准,例如在CREATE FUNCTION子句中varchar(x)≠varchar(y)。 用CREATE表中的CHECK子句表达限制(具有相同的varchar性能!),例如CHECK(char_length(x)<=10)。在INSERT/UPDATE中可以忽略不计的性能损失,您还可以控制范围和字符串结构,例如CHECK(char_length(x)>5 and char_length(x)<=20 and x LIKE 'Hello%')
没有区别,在引子里都是可变长度数组。
查看本文来自Depesz: http://www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/
以下是几个亮点:
总结一下: Char (n)——在处理小于n的值时占用太多空间(将它们填充到n),并且由于添加尾随会导致微妙的错误 空格,加上改变极限是有问题的 Varchar (n) -在活动环境中更改限制是有问题的(在更改表时需要排他锁) Varchar -就像文本一样 Text -对我来说是胜过(n)数据类型的赢家,因为它没有数据类型的问题,胜过varchar -因为它有独特的名称
本文进行了详细的测试,以证明所有4种数据类型的插入和选择的性能是相似的。它还详细介绍了在需要时限制长度的其他方法。基于函数的约束或域提供了立即增加长度约束的优势,并且基于减少字符串长度约束的情况很少,depesz得出结论,它们中的一个通常是长度限制的最佳选择。
character varying(n), varchar(n) -(两者相同)。值将被截断为n个字符而不引发错误。 character(n), char(n) -(都是一样的)。固定长度,并将空白垫至长度结束。 文本-无限长度。
例子:
Table test:
a character(7)
b varchar(7)
insert "ok " to a
insert "ok " to b
我们得到了结果:
a | (a)char_length | b | (b)char_length
----------+----------------+-------+----------------
"ok "| 7 | "ok" | 2
有些OT:如果你使用Rails,网页的标准格式可能会有所不同。对于数据输入表单,文本框是可滚动的,但是字符变化(Rails字符串)框是一行的。显示视图根据需要而定。