文本数据类型和字符变化(varchar)数据类型之间的区别是什么?

根据文档

如果使用不带长度说明符的字符变化,则该类型接受任何大小的字符串。后者是PostgreSQL的扩展。

and

此外,PostgreSQL还提供了文本类型,用于存储任意长度的字符串。尽管类型text不在SQL标准中,但其他几个SQL数据库管理系统也具有它。

那么有什么不同呢?


当前回答

来自http://www.sqlines.com/postgresql/datatypes/text:的一个很好的解释

TEXT和VARCHAR(n)之间的唯一区别是您可以限制 VARCHAR列的最大长度,例如VARCHAR(255) 不允许插入长度超过255个字符的字符串。 TEXT和VARCHAR的上限都是1gb,但是没有 它们之间的性能差异(根据PostgreSQL 文档)。

其他回答

有些OT:如果你使用Rails,网页的标准格式可能会有所不同。对于数据输入表单,文本框是可滚动的,但是字符变化(Rails字符串)框是一行的。显示视图根据需要而定。

(这个答案是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%')

如果你只使用文本类型,在使用AWS数据库迁移服务时可能会遇到问题:

使用大对象(LOB),但目标LOB列不能为空

由于大型对象(lob)的大小未知且有时较大,因此需要更多的处理 和资源比标准对象。以帮助调整包含 lob, AWS DMS提供以下选项

如果你在所有事情上都坚持使用PostgreSQL,那么你可能没问题。但如果你打算通过ODBC或DMS等外部工具与你的db交互,你应该考虑不要事事使用TEXT。

在PostgreSQL手册上

There is no performance difference among these three types, apart from increased storage space when using the blank-padded type, and a few extra CPU cycles to check the length when storing into a length-constrained column. While character(n) has performance advantages in some other database systems, there is no such advantage in PostgreSQL; in fact character(n) is usually the slowest of the three because of its additional storage costs. In most situations text or character varying should be used instead.

我通常使用文本

引用:http://www.postgresql.org/docs/current/static/datatype-character.html

在我看来,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.