1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PostgreSQLだと基本的にvarcharかtextで良いということ 🐘

Last updated at Posted at 2025-12-03

まとめ 🐘

  • PostgreSQLだと基本的にvarcharかtextで良い
  • varcharかtextをどちらにするかは個人次第
  • 文字数制限をしたいならvarchar(n)でも良いがCHECK制約の方がより制限をかけられる

一人アドベントカレンダー3営業日目、ゆる〜くやっていきます(夜中滑り込みました💤)

背景

url varchar(255) NOT NULL,

基本的にTEXT型で良いです。
https://wiki.postgresql.org/wiki/Don't_Do_This#Text_storage

上司から上のレビュー指摘を受けたので、なぜそうなのか調べたいと思いました。

PostgresSQLのマニュアル 〜Don't Do This〜 📕

以下がマニュアルです。

まず以下が書かれていました。

デフォルトでvarchar(n)型を使用しないでください。
代わりにvarchar(長さ制限なし)またはtextの使用を検討してください。

その理由を見ていきます。

varchar(n),varchar,textのストレージ上のサイズは完全に同一

varchar(n)

  • 可変長テキストフィールド
  • n文字(バイト数ではない)を超える文字列を挿入しようとするとエラーになる

varchar((n)なし)やtextは同様ですが、長さの制限がありません。

同じ文字列をこれら3つのフィールドタイプ(varchar(n),varchar,text)に挿入した場合、
ストレージ上のサイズは完全に同一なので、パフォーマンスの差はありません。

フィールドの値を制限する必要がある場合、最大長よりも具体的な制約が必要になる可能性が高い

ここでいう具体的な制約というのは最小長や限定された文字の集合などです。
CHECK制約は最大文字数制限だけでなく、そのような制約もすべて実現できます。

例えば「ユーザーID」を以下のルールにします。

  • 3〜20文字
  • 半角英数字と _ のみ

varchar(20) だけだと:
最大20文字ということしか保証できない

3文字未満も入るし、日本語も入ってしまう
しかし、text型 + CHECK制約なら:

CREATE TABLE users (
  id TEXT PRIMARY KEY,
  user_name TEXT NOT NULL,
  CHECK (
    char_length(user_name) BETWEEN 3 AND 20
    AND user_name ~ '^[A-Za-z0-9_]+$'
  )
);

これで

  • 最大長(20文字)
  • 最小長(3文字)
  • 許可する文字種(英数字 + _)
    までDB側で保証できます。

まとめ 🐘

  • PostgreSQLだと基本的にvarcharかtextで良い
  • varcharかtextをどちらにするかは個人次第
  • 文字数制限をしたいならvarchar(n)でも良いがCHECK制約の方がより制限をかけられる

最後に ⭐️

  • varchar、textについて理解が深まりました
  • CHECK制約は業務で使ったことがないので今度勉強してみたいと思います
  • textを推している理由については今度伺ってみたいです(varcharとvarchar(n)が紛らわしいから?)

参考 📚

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?