Làm cách nào để bạn thay đổi mã hóa ký tự của cơ sở dữ liệu postgres?


82

Tôi có một cơ sở dữ liệu đã được thiết lập với bộ ký tự mặc định SQL_ASCII. Tôi muốn chuyển nó sang UNICODE. Có một cách dễ dàng để làm điều đó?



Câu trả lời:


64

Để thay đổi mã hóa cơ sở dữ liệu của bạn:

  1. Kết xuất cơ sở dữ liệu của bạn
  2. Bỏ cơ sở dữ liệu của bạn,
  3. Tạo cơ sở dữ liệu mới với mã hóa khác
  4. Tải lại dữ liệu của bạn.

Đảm bảo rằng mã hóa máy khách được đặt chính xác trong suốt quá trình này.

Nguồn: http://archives.postgresql.org/pgsql-novice/2006-03/msg00210.php


Trên điều tôi không nhận được từ liên kết được "Kiểm tra xem các tập tin dump được tạo ra trong bước đầu tiên có bất kỳ ký tự đặc biệt và thực hiện những thay đổi cần thiết" => Tôi có phải tự thay đổi tất cả các ký tự đặc biệt
spankmaster79

1
Bạn có thể vui lòng thêm các lệnh để kết xuất và nhập lại vào câu trả lời của bạn không? như sudo -u postgres pg_dump your_db > /backups/postgresql.sql...
rubo77

104

Trước hết, câu trả lời của Daniel là phương án chính xác, an toàn.

Đối với trường hợp cụ thể của việc thay đổi từ SQL_ASCII sang một thứ gì đó khác, bạn có thể gian lận và chỉ cần chọc vào danh mục pg_database để gán lại mã hóa cơ sở dữ liệu. Điều này giả sử rằng bạn đã lưu trữ bất kỳ ký tự không phải ASCII nào trong bảng mã dự kiến ​​(hoặc đơn giản là bạn chưa sử dụng bất kỳ ký tự không phải ASCII nào).

Sau đó, bạn có thể làm:

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

Điều này sẽ không thay đổi đối chiếu của cơ sở dữ liệu, chỉ là cách các byte mã hóa được chuyển đổi thành các ký tự (vì vậy bây giờ length('£123') sẽ trả về 4 thay vì 5). Nếu cơ sở dữ liệu sử dụng đối chiếu 'C', sẽ không có thay đổi nào đối với thứ tự cho các chuỗi ASCII. Mặc dù vậy, bạn có thể cần phải xây dựng lại bất kỳ chỉ mục nào chứa các ký tự không phải ASCII.

Emptor caveat. Kết xuất và tải lại cung cấp một cách để kiểm tra nội dung cơ sở dữ liệu của bạn có thực sự nằm trong bảng mã mà bạn mong đợi hay không. Và nếu hóa ra bạn có một số dữ liệu được mã hóa sai trong cơ sở dữ liệu, việc giải cứu sẽ rất khó khăn. Vì vậy, nếu bạn có thể, hãy kết xuất và khởi động lại.


1
+1 Cảm ơn bạn. Máy dev của tôi sử dụng UTF8 enconding nhưng sản xuất của tôi sử dụng LATIN1. Tôi đã gặp rất nhiều lỗi vì điều này.
Luiz Damim

1
Người ta cho tôi lỗi này: -bash: syntax error near unexpected token ( ' `
Abhipso Ghosh

@AbhipsoGhosh điều này không phải được dán vào bash shell mà là ở psqldấu nhắc.
Pierre

14

Kết xuất một cơ sở dữ liệu với một mã hóa cụ thể và cố gắng khôi phục nó trên một cơ sở dữ liệu khác với một mã hóa khác có thể dẫn đến hỏng dữ liệu. Mã hóa dữ liệu phải được đặt TRƯỚC KHI bất kỳ dữ liệu nào được đưa vào cơ sở dữ liệu.

Kiểm tra điều này : Khi sao chép bất kỳ cơ sở dữ liệu nào khác, không thể thay đổi cài đặt mã hóa và ngôn ngữ từ cài đặt của cơ sở dữ liệu nguồn, vì điều đó có thể dẫn đến dữ liệu bị hỏng.

điều này : Một số danh mục ngôn ngữ phải có giá trị cố định khi cơ sở dữ liệu được tạo. Bạn có thể sử dụng các cài đặt khác nhau cho các cơ sở dữ liệu khác nhau, nhưng khi một cơ sở dữ liệu được tạo, bạn không thể thay đổi chúng cho cơ sở dữ liệu đó nữa. LC_COLLATE và LC_CTYPE là những danh mục này. Chúng ảnh hưởng đến thứ tự sắp xếp của các chỉ mục, vì vậy chúng phải được giữ cố định, nếu không các chỉ mục trên cột văn bản sẽ bị hỏng. ( Nhưng bạn có thể giảm bớt hạn chế này bằng cách sử dụng đối chiếu, như đã thảo luận trong Phần 22.2. ) Giá trị mặc định cho các danh mục này được xác định khi chạy initdb và các giá trị đó được sử dụng khi tạo cơ sở dữ liệu mới, trừ khi được chỉ định khác trong lệnh CREATE DATABASE.


Tôi thà xây dựng lại mọi thứ từ đầu đúng cách với một mã hóa cục bộ chính xác trên hệ điều hành debian của bạn như được giải thích ở đây :

su root

Định cấu hình lại cài đặt cục bộ của bạn:

dpkg-reconfigure locales

Chọn ngôn ngữ của bạn (chẳng hạn như tiếng Pháp ở Thụy Sĩ: fr_CH.UTF8)

Gỡ cài đặt và dọn dẹp postgresql đúng cách:

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

Cài đặt lại postgresql:

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

Giờ đây, mọi cơ sở dữ liệu mới sẽ tự động được tạo với mã hóa chính xác, LC_TYPE (phân loại ký tự) và LC_COLLATE (thứ tự sắp xếp chuỗi).


2
Tôi nghĩ nó là "dpkg-recfigure locales", số nhiều. Hình thức số ít dường như không hoạt động (chỉ được đánh dấu).
foo

9

Câu trả lời của Daniel Kutik là đúng, nhưng nó có thể an toàn hơn nữa, với việc đổi tên cơ sở dữ liệu .

Vì vậy, cách thực sự an toàn là:

  1. Tạo cơ sở dữ liệu mới với mã hóa và tên khác
  2. Kết xuất cơ sở dữ liệu của bạn
  3. Khôi phục kết xuất cho DB mới
  4. Kiểm tra xem ứng dụng của bạn có chạy đúng với DB mới không
  5. Đổi tên DB cũ thành một cái gì đó có ý nghĩa
  6. Đổi tên DB mới
  7. Thử nghiệm lại ứng dụng
  8. Bỏ cơ sở dữ liệu cũ

Trong trường hợp khẩn cấp, chỉ cần đổi tên lại các DB


7
# 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"   
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.