2008-10-10 44 views
9

tôi đang tìm kiếm ý kiến ​​nếu vấn đề sau đây có thể có một/khác nhau/giải pháp chung tốt hơn:Cơ sở dữ liệu địa hóa


Tôi có một cơ sở dữ liệu cho các sản phẩm, trong đó có tên của các sản phẩm bằng tiếng Anh (ngôn ngữ mặc định của ứng dụng này) và tôi cần bản dịch của các tên nếu có.

Hiện nay tôi đã thiết lập này:

Một bảng sản phẩm

CREATE TABLE products 
(
    id serial NOT NULL, 
    "name" character varying(255) NOT NULL, 
    CONSTRAINT products_pkey PRIMARY KEY (id) 
) 

và một bảng nội địa hóa sản phẩm

CREATE TABLE products_l10n 
(
    product_id serial NOT NULL, 
    "language" character(2) NOT NULL, 
    "name" character varying(255) NOT NULL, 
    CONSTRAINT products_l10n_pkey PRIMARY KEY (product_id, language), 
    CONSTRAINT products_l10n_product_id_fkey FOREIGN KEY (product_id) 
     REFERENCES products (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE CASCADE 
) 

và tôi sử dụng các truy vấn sau đây để lấy một danh sách các sản phẩm địa phương (tiếng Đức trong trường hợp này) với dự phòng sang tên tiếng Anh mặc định:

SELECT p.id, COALESCE(pl.name, p.name) 
from products p LEFT 
JOIN products_l10n pl ON p.id = pl.product_id AND language = 'de'; 

Mã SQL nằm trong phương ngữ postgres. Dữ liệu được lưu dưới dạng UTF-8.

Trả lời

6

Có vẻ tốt với tôi. Điều tôi có thể thay đổi là cách bạn xử lý ngôn ngữ: có lẽ đó là một bảng riêng biệt. Do đó, bạn sẽ có:

CREATE TABLE products_l10n 
(
    product_id serial NOT NULL, 
    language_id int NOT NULL, 
    "name" character varying(255) NOT NULL, 
    CONSTRAINT products_l10n_pkey PRIMARY KEY (product_id, language), 
    CONSTRAINT products_l10n_product_id_fkey FOREIGN KEY (product_id) 
     REFERENCES products (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE CASCADE 
    CONSTRAINT products_l10n_language_id_fkey FOREIGN KEY (language_id) 
     REFERENCES languages (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE CASCADE 
) 

CREATE TABLE languages 
) 
    id serial not null 
    "language" character(2) NOT NULL 
) 

Bên cạnh đó, tôi nghĩ bạn đã có giải pháp tốt nhất có thể.

+2

Cơ sở dữ liệu không thể tối ưu hóa một trường ký tự (2) như là tích phân - vì mã ngôn ngữ ISO 639-1 dễ đọc hơn so với số nguyên nếu có vấn đề. – Fionn

+0

Tôi đã nghĩ chính xác điều tương tự. Trong nháy mắt thứ hai, sử dụng một lớp bổ sung có một số ưu điểm: có thể liệt kê tất cả các ngôn ngữ có sẵn/được cấu hình (hữu ích trong GUI), bạn có thể xóa toàn bộ ngôn ngữ (với ràng buộc DB) và ngăn chặn "lỗi chính tả". Mặc dù sau này không quan trọng khi sử dụng 2 mã char;) – kazu

0

Có vẻ hợp với tôi.

Rõ ràng bạn nên đặt tên được bản địa hóa thành cột Unicode, bạn có thể chọn đặt mặc định tiếng Anh thành trường ASCII (giả sử cơ sở dữ liệu hỗ trợ). Nó có thể là tốt nhất để chỉ làm Unicode trong suốt và "quên" về nó.

+0

Đã chỉnh sửa câu hỏi - dữ liệu luôn ở dạng Unicode (UTF-8). – Fionn

1

Có vẻ tốt - tương tự như kỹ thuật bản địa hóa ưa thích của tôi - về ký tự rộng (tiếng Nhật) thì sao? Chúng tôi luôn sử dụng nvarchar để xử lý điều đó.

Những gì chúng tôi thực sự tìm thấy, tuy nhiên trong hoạt động mua hàng quốc tế của chúng tôi, không có sự nhất quán trên các giới hạn quốc tế về sản phẩm, vì các nhà cung cấp ở mỗi quốc gia khác nhau nên chúng tôi đã quốc tế hoá/bản địa hóa giao diện của mình. khác biệt.

+0

Đã chỉnh sửa câu hỏi - dữ liệu luôn ở dạng Unicode (UTF-8). – Fionn

1

Biến thể duy nhất tôi có thể cung cấp là bạn cũng có thể muốn bao gồm khả năng quốc gia/phương ngữ; ví dụ, thay vì chỉ tiếng Anh (en), sử dụng tiếng Anh Mỹ (en-US). Bằng cách đó bạn có thể tính toán các biến thể theo cách (ví dụ, cách viết tiếng Anh, tiếng Pháp của Pháp có thể có sự khác biệt so với tiếng Pháp được nói ở Pháp, v.v.).

0

Yếu tố phức tạp duy nhất mà những người khác chưa đề cập là bộ mã - bạn có thể xử lý tiếng Do Thái, tiếng Ả Rập, tiếng Nga, tiếng Trung, tiếng Nhật không? Nếu tất cả mọi thứ là Unicode, bạn chỉ phải lo lắng về GB18030 (Trung Quốc), đó là (IIUC) một superset của Unicode.

0

Khi giao dịch với loại điều này, tôi sử dụng để xây dựng một bảng sản phẩm không chứa tên nào cả, và bảng product_translation chỉ giữ tên (và hơn thế nữa, rõ ràng).

Sau đó, tôi kết thúc với loại truy vấn:

 
SELECT 
    i.id, 
    i.price, 
    it.label 
FROM 
    items i 
    LEFT JOIN items_trans it 
     ON i.id=it.item_id AND it.lang_id=(
      SELECT lang_id 
      FROM items_trans 
      WHERE item_id=i.id 
      ORDER BY 
       (lang_id=1) DESC, 
       (lang_id=0) DESC 
      LIMIT 1 
     ) 

Bạn nghĩ gì?

+1

Tôi không thích tùy chọn này, vì trong trường hợp này bạn không được bảo đảm có ít nhất một giá trị mặc định cho các tên không được dịch. – Tengiz

Các vấn đề liên quan