web-dev-qa-db-ja.com

postgresデータベースの文字エンコードをどのように変更しますか?

デフォルトの文字セットSQL_ASCIIでセットアップされたデータベースがあります。 UNICODEに切り替えたいです。それを行う簡単な方法はありますか?

72
Nick Retallack

データベースのエンコードを変更するには:

  1. データベースをダンプする
  2. データベースをドロップし、
  3. 異なるエンコーディングで新しいデータベースを作成します
  4. データをリロードします。

この間、クライアントのエンコードが正しく設定されていることを確認してください。

ソース: http://archives.postgresql.org/pgsql-novice/2006-03/msg00210.php

54
Daniel Kutik

最初に、ダニエルの答えは正しい、安全なオプションです。

SQL_ASCIIから他の何かに変更する特定のケースでは、pg_databaseカタログをチートして単純に突いてデータベースエンコーディングを再割り当てできます。これは、想定されたエンコードで非ASCII文字を既に格納していることを前提としています(または単に非ASCII文字を使用していないことを前提としています)。

その後、次のことができます。

update pg_database set encoding = pg_char_to_encoding('UTF8') where datname = 'thedb'

これにより、データベースの照合順序は変更されず、エンコードされたバイトが文字に変換される方法が変更されます(したがって、length('£123')は5ではなく4を返します)。データベースが 'C'照合を使用する場合、ASCII文字列の順序に変更はありません。ただし、非ASCII文字を含むインデックスを再構築する必要があります。

買い手責任負担。ダンプとリロードは、データベースの内容が実際に期待するエンコーディングになっているかどうかを確認する方法を提供しますが、そうではありません。そして、データベースに誤ってエンコードされたデータがあることが判明した場合、救助は困難になります。可能であれば、ダンプして再初期化します。

95
araqnid

特定のエンコーディングでデータベースをダンプし、異なるエンコーディングで別のデータベースに復元しようとすると、データが破損する可能性があります。データをデータベースに挿入する前に、データエンコーディングを設定する必要があります。

this を確認します。他のデータベースをコピーする場合、エンコードとロケールの設定はソースデータベースのものから変更できません。データが破損する可能性があるためです。

そして this一部のロケールカテゴリは、データベースの作成時に値を修正する必要があります。データベースごとに異なる設定を使用できますが、データベースが作成されると、そのデータベースの設定は変更できなくなります。 LC_COLLATEおよびLC_CTYPEはこれらのカテゴリです。 これらはインデックスのソート順に影響するため、固定しておく必要があります。そうしないと、テキスト列のインデックスが破損します。ただし、セクション22.2 。CREATE DATABASEコマンドで特に指定しない限り、これらのカテゴリのデフォルト値はinitdbの実行時に決定され、新しいデータベースの作成時にこれらの値が使用されます。


here のように、debian OSで正しいローカルエンコーディングを使用して、最初からすべてを適切に再構築します。

su root

ローカル設定を再構成します。

dpkg-reconfigure locales

ロケールを選択します(たとえば、スイスのフランス語の場合:fr_CH.UTF8)

Postgresqlを適切にアンインストールしてクリーンアップします。

apt-get --purge remove postgresql\*
rm -r /etc/postgresql/
rm -r /etc/postgresql-common/
rm -r /var/lib/postgresql/
userdel -r postgres
groupdel postgres

Postgresqlを再インストールします。

aptitude install postgresql-9.1 postgresql-contrib-9.1 postgresql-doc-9.1

これで、新しいデータベースは、正しいエンコード、LC_TYPE(文字分類)、およびLC_COLLATE(文字列ソート順)で自動的に作成されます。

11
Douglas

Daniel Kutikの答えは正しいですが、database renamingを使用すると、さらに安全になります。

したがって、本当に安全な方法は次のとおりです。

  1. 異なるエンコーディングと名前で新しいデータベースを作成します
  2. データベースをダンプする
  3. ダンプを新しいDBに復元する
  4. 新しいDBでアプリケーションが正しく実行されることをテストします
  5. 古いDBの名前を意味のあるものに変更します
  6. 新しいDBの名前を変更する
  7. アプリケーションを再度テストする
  8. 古いデータベースを削除する

緊急の場合は、DBの名前を変更してください

8
Sergey Zarubin
# dump into file
pg_dump myDB > /tmp/myDB.sql

# create an empty db with the right encoding (on older versions the escaped single quotes are needed!)
psql -c 'CREATE DATABASE "tempDB" WITH OWNER = "myself" LC_COLLATE = '\''de_DE.utf8'\'' TEMPLATE template0;'

# import in the new DB
psql -d tempDB -1 -f /tmp/myDB.sql

# rename databases
psql -c 'ALTER DATABASE "myDB" RENAME TO "myDB-wrong-encoding";' 
psql -c 'ALTER DATABASE "tempDB" RENAME TO "myDB";'

# see the result
psql myDB -c "SHOW LC_COLLATE"   
3
rubo77