text
数据类型和character varying
( varchar
)数据类型之间有什么区别?
根据 文档
如果在不使用长度说明符的情况下使用字符变化,则该类型可接受任何大小的字符串。后者是 PostgreSQL 扩展。
和
另外,PostgreSQL 提供了文本类型,可以存储任意长度的字符串。尽管类型文本不在 SQL 标准中,但其他几种 SQL 数据库管理系统也具有它。
那有什么区别呢?
没什么区别,引擎盖下全是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"
用于获取频率分布的查询( select count(*), field ... group by field
)大约需要 650 毫秒,而使用text
字段在相同数据上大约需要 760 毫秒。
并使用 “纯 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 年的结果并加强建议。
经过平均,我在许多机器和许多测试中得到的结果:都是一样的
(统计上小于 tham 标准偏差)。
使用text
数据类型,
避免使用旧的varchar(x)
因为有时它不是标准的,例如在CREATE FUNCTION
子句中varchar(x)
≠ varchar(y)
。
CREATE TABLE
中的CHECK
子句表示限制(具有相同的varchar
性能!)
例如CHECK(char_length(x)<=10)
。
INSERT / UPDATE 的性能损失可以忽略不计,您还可以控制范围和字符串结构
例如CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')