文本数据类型和字符变化(varchar)数据类型之间的区别是什么?
根据文档
如果使用不带长度说明符的字符变化,则该类型接受任何大小的字符串。后者是PostgreSQL的扩展。
and
此外,PostgreSQL还提供了文本类型,用于存储任意长度的字符串。尽管类型text不在SQL标准中,但其他几个SQL数据库管理系统也具有它。
那么有什么不同呢?
文本数据类型和字符变化(varchar)数据类型之间的区别是什么?
根据文档
如果使用不带长度说明符的字符变化,则该类型接受任何大小的字符串。后者是PostgreSQL的扩展。
and
此外,PostgreSQL还提供了文本类型,用于存储任意长度的字符串。尽管类型text不在SQL标准中,但其他几个SQL数据库管理系统也具有它。
那么有什么不同呢?
当前回答
(这个答案是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%')
其他回答
在我看来,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.
来自http://www.sqlines.com/postgresql/datatypes/text:的一个很好的解释
TEXT和VARCHAR(n)之间的唯一区别是您可以限制 VARCHAR列的最大长度,例如VARCHAR(255) 不允许插入长度超过255个字符的字符串。 TEXT和VARCHAR的上限都是1gb,但是没有 它们之间的性能差异(根据PostgreSQL 文档)。
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
Text和varchar有不同的隐式类型转换。我注意到的最大影响是对尾随空格的处理。例如……
select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text
返回真,假,真和不真,真,真,如你所料。
有些OT:如果你使用Rails,网页的标准格式可能会有所不同。对于数据输入表单,文本框是可滚动的,但是字符变化(Rails字符串)框是一行的。显示视图根据需要而定。