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 đó?
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:
Để thay đổi mã hóa cơ sở 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
sudo -u postgres pg_dump your_db > /backups/postgresql.sql
...
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.
-bash: syntax error near unexpected token
( ' `
psql
dấu nhắc.
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.
Và đ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).
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à:
Trong trường hợp khẩn cấp, chỉ cần đổi tên lại các DB
# 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"