VARCHAR列に任意の長さ制限を追加する必要がありますか?


35

PostgreSQLのドキュメントによるとVARCHARVARCHAR(n)との間にパフォーマンスの違いはありませんTEXT

名前または住所列に任意の長さ制限を追加する必要がありますか?

編集:だまされていない:

このCHARタイプは過去の遺物であり、パフォーマンスだけでなく、アーウィンのような他の長所と短所も彼の驚くべき答えで述べています。

回答:


45

答えはノーです。回避できる場合は
、長さ修飾子を追加しないでくださいvarchar。ほとんどの場合、とにかく実際には長さの制限は必要ありません。textすべての文字データに使用するだけです。をvarchar持たないRDBMSとの互換性を維持する必要がある場合は、(長さ修飾子なし)にしますtext

パフォーマンスはほぼ同じである- textであるまれな状況では少し速く、そしてあなたは、長さのチェックのためのサイクルを節約します。

実際に最大長を強制する必要がある場合は、そのためにチェック制約を使用textして追加します

ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);

このような制約は、テーブル定義と依存するすべてのオブジェクト(ビュー、関数、外部キーなど)を台無しにすることなく、いつでも変更または削除できます。

長さ修飾子を使用すると、このまたはこれまたはこのような問題に遭遇するだけです...

PostgreSQL 9.1では、この痛みを多少軽減するための新機能が導入されました。ここでリリースノートを引用します

ALTER TABLE ... SET DATA TYPE適切な場合にテーブルの書き換えを回避できるようにします(Noah Misch、Robert Haas)

たとえば、varchar列をテキストに変換するときに、テーブルを書き直す必要はなくなりました。ただし、varchar列の長さの制約を増やすに は、テーブルの書き換えが必要です。


この答えは、単に「実際のデータベースに任意の制限を追加しないでください」というだけであれば、はるかに良いと思います。この答えの多くは修正とさらなる情報を必要としているように感じますが、それは完全にトピックから外れており、私が完全に同意するあなたの結論をそらすでしょう。
エヴァンキャロル

はい、すべて9.1〜6年前のPostgresバージョンに基づいています。今は少し埃っぽいですが、基本的なアドバイスはまだ良いです。
アーウィンブランドステッター

健全性チェックの目的ですべてのテキスト列にチェック制約を追加し、非常に大きなテキストを挿入してクライアントのバグがすべてのデータベースのディスク容量を使い果たしないようにすることは良い考えですか、悪い考えですか?
コード

@コード:実行可能なオプションです。同じ制約を持つ列が多数ある場合は、ドメインを検討してください。またはvarchar(n)結局のところ、簡単にするために-マイナス面が通常あなたに影響しない場合。(実際の最大長を強制する場合、制限は任意ではありません。)
Erwin Brandstetter

12

データを検証するために、長さ制限を一種のチェック制約と見なす場合は、追加します。実際にあなたがしたい場合がありますないにするために、代わりに長さの定義が、実際のチェック制約を使用変える速く限界に。

長さの制限を変更(増加)するにALTER TABLEは、テーブルの排他的ロックが必要である間に(テーブルの再書き込みの可能性があるため)終了するのに長時間かかることがあるを実行する必要があります。

チェック制約の変更(つまり、ドロップと再作成)は非常に簡単な操作であり、テーブルのデータを読み取るだけで、行は変更されません。そのため、より高速になります(つまり、排他テーブルロックがはるかに短い時間保持されることを意味します)。

操作中、a text、a、varcharまたはvarchar(5000)columnに違いはありません。


単純な好奇心から、なぜデータをキャプチャしている間、この長さのチェックをクライアントアプリケーションで実行できないと思いますか?
PirateApp

4
@PirateApp:多くの場合、複数のアプリケーションまたは外部データソースが存在するためです(夜間のバッチインポートを考えてください)。そして、ほとんどの場合、データベース(およびデータ)は1つのアプリケーションよりも長く存続します。
a_horse_with_no_name

2

問題は、VARCHAR列に任意の長さ制限を追加するかどうかです。

それに対する答えは、単に「いいえ」です。のvarchar(max)ような規則をサポートまたは使用する下位データベースの場合のように、任意の制限を追加することを正当化できるものはありませんvarchar(255)。ただし、仕様が制限に対応している場合、特にPostgreSQLの最新バージョンでは、答えははるかに複雑になると思います。そして、そのために、私はYESに傾くでしょう。

私の意見では、仕様で要求されている場合、制限は賢明な選択です。特に、より合理的なワークロードの場合。他の理由がない場合は、メタデータを保存します。

ここでの私の答え、CHAR vs VARCHAR(Postgres)のインデックスパフォーマンスでは、メタデータの値を扱います。

意味のある可変長テキストキーがあり、一定の最大長を持つと信頼している仕様を見つけた場合、私も使用しvarcharます。ただし、その基準に適合するものは考えられません。


1

VARCHAR「長い文字列はシステムによって自動的に圧縮される」と「非常に長い値もバックグラウンドテーブルに格納される」ため、非常に大きな文字列の格納に定期的に使用すると、パフォーマンスに多少の違いがあるようです。理論的には、これは、非常に長い文字列フィールドに対する大量のリクエストが、短い文字列フィールドに対するリクエストよりも遅いことを意味します。名前とアドレスはそれほど長くないので、おそらくこの問題に遭遇することはないでしょう。

ただし、データベース外でこれらの文字列をどのように使用するかに応じて、システムの悪用を防ぐために実用的な制限を追加することができます。たとえば、フォームのどこかに名前と住所を表示している場合、「名前」フィールドにテキストの段落全体を表示できない可能性があるため、名前列を500などに制限するのが理にかなっています。文字。


1
私の知る限り、varcharとtextフィールドのTOASTに違いはありません。
-dezso

VARCHARTEXTPostgresでは純粋に構文上の砂糖であるため、ストレージの処理に違いはありません。言及する圧縮とバックグラウンドのテーブルストレージは、列のメタデータではなく、列のデータの実際の長さに基づいて行われます。TEXT列は内部的にvarlenaC構造体(最初の4バイトが作成/更新時に長さを格納する可変長配列)として格納され、その長さに基づいて最適化されるのはこの構造体です。
カウバート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.