text
数据类型和character varying
(varchar
)数据类型有什么区别?
根据文档
如果在不使用长度说明符的情况下使用字符变化,则该类型接受任何大小的字符串。后者是PostgreSQL扩展。
和
另外,PostgreSQL提供了文本类型,该文本类型存储任意长度的字符串。尽管类型文本不在SQL标准中,但其他几种SQL数据库管理系统也具有它。
那有什么区别呢?
text
数据类型和character varying
(varchar
)数据类型有什么区别?
根据文档
如果在不使用长度说明符的情况下使用字符变化,则该类型接受任何大小的字符串。后者是PostgreSQL扩展。
和
另外,PostgreSQL提供了文本类型,该文本类型存储任意长度的字符串。尽管类型文本不在SQL标准中,但其他几种SQL数据库管理系统也具有它。
那有什么区别呢?
Answers:
没什么不同,实际上是全部varlena
(可变长度数组)。
在Depesz上查看以下文章:http : //www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/
一些要点:
总结一下:
- char(n)–处理小于
n
(将其填充到n
)的值时占用太多空间,并且由于添加尾随空格而可能导致细微的错误,此外,更改限制也存在问题- varchar(n)–在实时环境中更改限制是有问题的(更改表时需要排他锁)
- varchar –就像文本一样
- 文本–对我来说是赢家 –超过(n)个数据类型,因为它没有问题,而超过varchar –因为它具有独特的名称
本文进行了详细的测试,以显示所有4种数据类型的插入和选择性能相似。还详细介绍了在需要时限制长度的其他方法。基于函数的约束或域提供了立即增加长度约束的优势,并且在减少字符串长度约束的情况很少见的基础上,depesz得出结论,其中之一通常是长度限制的最佳选择。
作为“ 字符类型的文档,点”出来,varchar(n)
,char(n)
,和text
都存储相同的方式。唯一的区别是,如果指定了长度,则需要额外的循环来检查长度;如果需要填充,则需要额外的空间和时间char(n)
。
但是,当您只需要存储一个字符时,使用特殊类型在性能上有一点优势"char"
(保留双引号-它们是类型名称的一部分)。您可以更快地访问该字段,并且没有开销来存储长度。
我刚刚做了一个"char"
从小写字母中选择的1,000,000个随机表。获取频率分布(select count(*), field ... group by field
)的查询大约需要650毫秒,而使用text
字段对相同数据的查询大约需要760毫秒。
"char"
不是 char
?? 在当今的PostgreSQL 11+中有效吗?...是: “类型"char"
(请注意引号)与char(1)的不同之处在于,它仅使用一个字节的存储空间。它在系统目录中内部用作简单的枚举类型。” ,guide / datatype-character。
并使用“纯SQL”基准(无需任何外部脚本)
将任何string_generator与UTF8一起使用
主要基准:
2.1。插
2.2。SELECT比较和计数
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年的结果并加强建议。
经过平均后,我在许多机器和许多测试中得到的结果:都是相同的
(统计上小于标准偏差)。
使用text
数据类型,
避免使用过时,varchar(x)
因为有时它不是标准,例如在 CREATE FUNCTION
子句 varchar(x)
≠中varchar(y)
。
varchar
通过eg中的with CHECK
子句表示限制(具有相同的性能!)。INSERT / UPDATE的性能损失可以忽略不计,您还可以控制范围和字符串结构, 例如CREATE TABLE
CHECK(char_length(x)<=10)
CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')
"char"
,是不是 char
,即使在当今的PostgreSQL 11+的。正如guide / datatype-character所说:“该类型"char"
(请注意引号)与char(1)的不同之处在于,它仅使用一个字节的存储空间。它在系统目录中内部用作一种简单的枚举类型。” 。
在PostgreSQL手册上
这三种类型之间没有性能差异,除了使用空白填充类型时增加的存储空间,以及在存储到受长度限制的列中时需要一些额外的CPU周期来检查长度。尽管character(n)在某些其他数据库系统中具有性能优势,但在PostgreSQL中却没有这种优势。实际上,character(n)通常是这三个中最慢的,因为它需要额外的存储成本。在大多数情况下,应改用文字或字符变化。
我通常使用文字
参考:http : //www.postgresql.org/docs/current/static/datatype-character.html
我认为,这varchar(n)
有其自身的优势。是的,它们都使用相同的基础类型。但是,应该指出的是,PostgreSQL中的索引的大小限制为每行2712字节。
TL; DR:
如果您使用没有限制的text
类型并且在这些列上具有索引,则很有可能在尝试插入数据时达到某些限制并在使用时出错,但是使用可以防止这种情况。varchar(n)
更多详细信息:这里的问题是PostgreSQL在为text
type或varchar(n)
where n
大于2712 创建索引时没有给出任何异常。但是,当尝试插入压缩大小大于2712的记录时,它将给出错误。这意味着您可以轻松插入由重复字符组成的字符串的100.000个字符,因为它将被压缩到2712以下,但是由于压缩后的大小大于2712字节,您可能无法插入一些4000个字符的字符串。使用varchar(n)
其中n
不太多超过2712,你就是从这些错误中的安全。
来自http://www.sqlines.com/postgresql/datatypes/text的很好的解释:
TEXT和VARCHAR(n)之间的唯一区别是可以限制VARCHAR列的最大长度,例如,VARCHAR(255)不允许插入长度超过255个字符的字符串。
TEXT和VARCHAR的上限均为1 Gb,并且它们之间没有性能差异(根据PostgreSQL文档)。
character varying(n)
,varchar(n)
-(两者相同)。值将被截断为n个字符而不会引发错误。
character(n)
,char(n)
-(两者相同)。固定长度,并会用空白垫填满直到长度结束。
text
-无限长度。
例:
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