PostgreSQL: Difference between text and varchar (character varying)
根据文件
If character varying is used without length specifier, the type accepts strings of any size. The latter is a PostgreSQL extension.
和
In addition, PostgreSQL provides the text type, which stores strings of any length. Although the type text is not in the SQL standard, several other SQL database management systems have it as well.
那有什么区别呢?
没有区别,在引擎盖下面是所有的
从depesz查看本文:http://www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/
几个亮点:
To sum it all up:
- char(n) – takes too much space when dealing with values shorter than
n (pads them ton ), and can lead to subtle errors because of adding trailing
spaces, plus it is problematic to change the limit- varchar(n) – it's problematic to change the limit in live environment (requires exclusive lock while altering table)
- varchar – just like text
- text – for me a winner – over (n) data types because it lacks their problems, and over varchar – because it has distinct name
本文做了详细的测试,以表明所有4种数据类型的插入和选择的性能是相似的。它还详细介绍了在需要时限制长度的其他方法。基于函数的约束或域提供了长度约束即时增加的优势,并且在减少字符串长度约束很少的基础上,Depesz得出结论,其中一个约束通常是长度限制的最佳选择。
正如文档中的"字符类型"所指出的,
但是,当您只需要存储一个字符时,使用特殊类型
我刚做了一张表格,从小写字母表中选择了1000000个随机的
更新2016年基准(pg9.5+)
并使用"纯SQL"基准(无任何外部脚本)
使用任何带utf8的字符串生成器
主要基准:
2.1。插入
2.2。选择比较和计数
1 2 3 4 5 6 | 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; |
准备特定测试(示例)
1 2 3 4 | 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) ); |
执行基本测试:
1 2 3 | INSERT INTO test SELECT string_generator(20+(random()*(i%11))::INT) FROM generate_series(1, 99000) t(i); |
以及其他测试,
1 2 3 4 5 | 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; |
…使用
2018年再次更新(第10页)
很少编辑以增加2018年的成果并加强建议。
2016年和2018年的成果我的结果,经过平均,在许多机器和许多测试中:都一样
(统计上比标准差小)。
使用
text 数据类型,
避免使用旧的varchar(x) ,因为有时它不是标准,例如在CREATE FUNCTION 条款varchar(x) 中≠varchar(y) 中。明示限制(具有相同的
varchar 性能!)根据CREATE TABLE 中的withCHECK 条款,如CHECK(char_length(x)<=10) 等。插入/更新时性能损失可以忽略不计,您还可以控制范围和字符串结构
例如CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%') 。
关于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
在我看来,
DR:如果在没有约束的情况下使用
更多细节:这里的问题是,PostgreSQL在为
文本和varchar具有不同的隐式类型转换。我注意到的最大影响是处理尾随空格。例如。。。
1 | SELECT ' '::CHAR = ' '::VARCHAR, ' '::CHAR = ' '::text, ' '::VARCHAR = ' '::text |
返回
有点OT:如果您使用的是Rails,那么网页的标准格式可能会有所不同。对于数据输入表单,
例子:
1 2 3 4 5 6 | TABLE test: a CHARACTER(7) b VARCHAR(7) INSERT"ok " TO a INSERT"ok " TO b |
我们得到结果:
1 2 3 | a | (a)CHAR_LENGTH | b | (b)CHAR_LENGTH ----------+----------------+-------+---------------- "ok "| 7 |"ok" | 2 |