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 - テキストと同じ
- テキスト - 私にとっては勝者 - over(n)データ型には問題がないため、varcharよりも - 重複した名前があるため
この記事では詳細なテストを行い、4つのデータ型すべてに対する挿入と選択のパフォーマンスが似ていることを示します。また、必要に応じて長さを制限するための代替方法について詳しく見ていきます。関数ベースの制約またはドメインは、長さの制約を即座に増やすという利点を提供します。また、ストリングの長さの制約を減らすことはまれであることに基づいて、dependentszはそれらのうちの1つが通常長さの制限に最適です。
ドキュメントの " 文字型 "が指摘するように、varchar(n)
、char(n)
、およびtext
はすべて同じ方法で格納されます。唯一の違いは、長さが指定されている場合は長さをチェックするために余分なサイクルが必要であり、char(n)
にパディングが必要な場合は余分なスペースと時間が必要なことです。
ただし、1文字だけを格納する必要がある場合は、特殊な型"char"
を使用することでパフォーマンスがわずかに向上します(二重引用符を使用します - それらは型名の一部です)。フィールドへのアクセスが速くなり、長さを格納するためのオーバーヘッドがなくなります。
私はちょうど小文字のアルファベットから選ばれた1,000,000個のランダムな"char"
のテーブルを作りました。頻度分布(select count(*), field ... group by field
)を取得するためのクエリは、text
フィールドを使用した同じデータに対する約760に対して、約650ミリ秒かかります。
そして「純粋なSQL」ベンチマークを使用する(外部スクリプトなしで)
uTF8で任意のstring_generatorを使用する
主なベンチマーク:
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)
にあります。
CREATE TABLE
のvarchar
節を使用して、(同じCHECK
パフォーマンスで)制限を明示する
例えば。 CHECK(char_length(x)<=10)
。
INSERT/UPDATEのパフォーマンスがごくわずかに低下するだけで、範囲とストリング構造を制御することもできます。
例えば。 CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')
PostgreSQLマニュアル上
これら3つのタイプの間には、ブランク埋め込みタイプを使用するときの記憶スペースの増加、および長さ制限のある列に保管するときの長さをチェックするための余分なCPUサイクルがいくつかあるだけです。 character(n)は他のデータベースシステムではパフォーマンス上の利点がありますが、PostgreSQLではそのような利点はありません。実際、文字(n)は追加のストレージコストのため、通常3つのうちで最も遅いです。ほとんどの場合、代わりにテキストや文字を使用するべきです。
私は通常テキストを使います
参照先: http://www.postgresql.org/docs/current/static/datatype-character.html
私の意見では、varchar(n)
にはそれ自身の利点があります。はい、それらはすべて同じ基本型とすべてを使用しています。ただし、PostgreSQLのインデックスのサイズ制限は、1行あたり 2712バイト です。
TL; DR: text
type 制約なしを使用していて、これらのカラムにインデックスがある場合、いくつかのカラムでこの制限に達するとエラーが発生する可能性があります。データを挿入しますが、varchar(n)
を使用すると、それを防ぐことができます。
もう少し詳しく: /ここでの問題は、PostgreSQLがtext
型またはvarchar(n)
のインデックスを作成するときに例外を出さないことです。ただし、n
が2712より大きい場合、エラーが発生します。 2712を挿入しようとしています。それはあなたがそれが2712よりはるかに下で圧縮されるので繰り返し文字で容易に構成される100.000文字の文字列を挿入することができることを意味しますが、圧縮サイズが2712バイトより大きいので4000文字で文字列を挿入できないかもしれません。 n
が2712よりも大きくない{too too}であるvarchar(n)
を使用すると、これらのエラーから安全です。
textとvarcharは、暗黙的に型変換が異なります。私が気付いた最大の影響は、末尾のスペースの処理です。例えば ...
select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text
ご想像のとおり、true, false, true
ではなくtrue, true, true
を返します。
ややOT:もしあなたがRailsを使っているなら、Webページの標準フォーマットは異なるかもしれません。データ入力フォームの場合、text
ボックスはスクロール可能ですが、character varying
(Rails string
)ボックスは1行です。表示ビューは必要なだけ長くなります。
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