协慌网

登录 贡献 社区

文字和 varchar 之间的区别(字符不同)

text数据类型和character varyingvarchar )数据类型之间有什么区别?

根据 文档

如果在不使用长度说明符的情况下使用字符变化,则该类型可接受任何大小的字符串。后者是 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 毫秒。

更新 2016 年基准(pg9.5 +)

并使用 “纯 SQL” 基准(没有任何外部脚本)

  1. 将任何 string_generator 与 UTF8 一起使用

  2. 主要基准:

    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 年的结果并加强建议。


2016 年和 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%')