Thực hành tốt nhất cho thiết kế cơ sở dữ liệu đa ngôn ngữ là gì? [đóng cửa]


193

Cách tốt nhất để tạo cơ sở dữ liệu đa ngôn ngữ là gì? Để tạo bảng được bản địa hóa cho mỗi bảng làm cho thiết kế và truy vấn trở nên phức tạp, trong trường hợp khác, việc thêm cột cho mỗi ngôn ngữ là đơn giản nhưng không động, vui lòng giúp tôi hiểu đâu là lựa chọn tốt nhất cho các ứng dụng doanh nghiệp



3
Tôi thấy điều này rất hữu ích với tôi: Thiết kế cơ sở dữ liệu đa ngôn ngữ trong MySQL
Siamak A.Motlagh

Câu trả lời:


222

Những gì chúng ta làm, là tạo hai bảng cho mỗi đối tượng đa ngôn ngữ.

Ví dụ: bảng đầu tiên chỉ chứa dữ liệu trung lập ngôn ngữ (khóa chính, v.v.) và bảng thứ hai chứa một bản ghi cho mỗi ngôn ngữ, chứa dữ liệu được bản địa hóa cộng với mã ISO của ngôn ngữ.

Trong một số trường hợp, chúng tôi thêm trường Ngôn ngữ mặc định, để chúng tôi có thể quay lại ngôn ngữ đó nếu không có dữ liệu địa phương hóa cho một ngôn ngữ được chỉ định.

Thí dụ:

Table "Product":
----------------
ID                 : int
<any other language-neutral fields>


Table "ProductTranslations"
---------------------------
ID                 : int      (foreign key referencing the Product)
Language           : varchar  (e.g. "en-US", "de-CH")
IsDefault          : bit
ProductDescription : nvarchar
<any other localized data>

Với phương pháp này, bạn có thể xử lý bao nhiêu ngôn ngữ khi cần (mà không phải thêm các trường bổ sung cho mỗi ngôn ngữ mới).


Cập nhật (2014-12-14): vui lòng xem câu trả lời này , để biết thêm thông tin về việc triển khai được sử dụng để tải dữ liệu đa ngôn ngữ vào một ứng dụng.


14
Nếu trường trung tính ngôn ngữ duy nhất là id thì sao? và chính xác làm thế nào để bạn chèn tham chiếu khóa ngoại khi chèn một hàng?
Timo Huovinen

4
Thật buồn cười, tôi đã thiết kế một sơ đồ cơ sở dữ liệu cho một CMS đa ngôn ngữ và có câu hỏi này trong đầu. Tôi đã chọn cách tiếp cận này, trước khi tôi nhìn thấy câu trả lời này! Cảm ơn câu trả lời này!
Patrick Manser

5
Một điều cần lưu ý ở đây là sẽ không có PK trên bảng này hoặc ID và Ngôn ngữ cần phải là PK tổng hợp. Hoặc, hoặc bạn cần thêm trường ProductTranslationId, có thể là một danh tính.
Daniel Lorenz

1
@Luca: Tôi đã trả lời câu hỏi của bạn, cho biết những gì tôi sử dụng để tải dữ liệu.
M4N

1
@ AarónGutiérrez Vâng, thật vui là bạn tạo một bảng với một cột duy nhất gọi là id: D. Để giải thích, mỗi idđại diện cho một ý nghĩa mà bạn có thể đính kèm các từ từ bất kỳ ngôn ngữ nào trong một bảng quan hệ, do đó bạn nhận được hai bảng, meaning(id) và word(id, mean_id), idtrong wordbảng đại diện cho id từ, idtrong meaningđại diện ý nghĩa đó là phổ quát.
Timo Huovinen

18

Tôi đề nghị câu trả lời được đăng bởi Martin.

Nhưng bạn dường như lo ngại về các truy vấn của mình trở nên quá phức tạp:

Để tạo bảng được bản địa hóa cho mỗi bảng, hãy thiết kế và truy vấn phức tạp ...

Vì vậy, bạn có thể nghĩ rằng, thay vì viết các truy vấn đơn giản như thế này:

SELECT price, name, description FROM Products WHERE price < 100

... bạn sẽ cần bắt đầu viết các truy vấn như thế:

SELECT
  p.price, pt.name, pt.description
FROM
  Products p JOIN ProductTranslations pt
  ON (p.id = pt.id AND pt.lang = "en")
WHERE
  price < 100

Không phải là một quan điểm rất đẹp.

Nhưng thay vì thực hiện thủ công, bạn nên phát triển lớp truy cập cơ sở dữ liệu của riêng mình, đó là phân tích trước SQL có chứa đánh dấu nội địa hóa đặc biệt của bạn và chuyển đổi nó thành SQL thực tế mà bạn sẽ cần gửi đến cơ sở dữ liệu.

Sử dụng hệ thống đó có thể trông giống như thế này:

db.setLocale("en");
db.query("SELECT p.price, _(p.name), _(p.description)
          FROM _(Products p) WHERE price < 100");

Và tôi chắc chắn rằng bạn có thể làm tốt hơn thế.

Điều quan trọng là để các bảng và trường của bạn được đặt tên theo cách thống nhất.


Câu hỏi khác là, để tạo một đối tượng kinh doanh cho sản phẩm? hoặc để tạo hai ... trong trường hợp đầu tiên, thật dễ dàng để làm việc với mục đó, trong lần thứ hai dễ dàng viết CMS
Arsen Mkrtchyan

14

Tôi thấy cách tiếp cận này hiệu quả với tôi:

Sản phẩm Sản phẩm Đất nước
========= ================== =========
ProductId ProductDetailId CountryId
- vv - ProductId CountryName
            Ngôn ngữ quốc gia
            Tên sản phẩm - vv -
            Mô tả Sản phẩm
            - Vân vân -

Bảng ProductDetail chứa tất cả các bản dịch (cho tên sản phẩm, mô tả, v.v.) bằng các ngôn ngữ bạn muốn hỗ trợ. Tùy thuộc vào yêu cầu của ứng dụng của bạn, bạn có thể muốn chia bảng Quốc gia để sử dụng các ngôn ngữ trong khu vực.


Tôi đã chọn cách tiếp cận tương tự cho một dự án mà tôi hiện đang thực hiện vì các địa phương khác nhau của tôi chứa thông tin rất cụ thể về các hệ thống đơn vị và các biện pháp sẽ được hiển thị cho người dùng.
califbler

8
Quốc gia và ngôn ngữ (địa phương) là những thứ khác nhau. Và mã ngôn ngữ ISO là khóa tự nhiên, bạn loại bỏ sự tham gia không cần thiết từ lang sang quốc gia.
gavenkoa

10

Tôi đang sử dụng phương pháp tiếp theo:

Sản phẩm

ProductID OrderID, ...

Thông tin sản phẩm

Tên sản phẩm Tên ngôn ngữID

Ngôn ngữ

Tên ngôn ngữ Văn hóa, ....


2

Giải pháp của Martin rất giống với giải pháp của tôi, tuy nhiên bạn sẽ xử lý các mô tả mặc định như thế nào khi bản dịch mong muốn không được tìm thấy?

Điều đó có yêu cầu IFNULL () và một câu lệnh CHỌN khác cho mỗi trường không?

Bản dịch mặc định sẽ được lưu trữ trong cùng một bảng, trong đó một cờ như "isDefault" chỉ ra rằng mô tả đó là mô tả mặc định trong trường hợp không tìm thấy ngôn ngữ hiện tại.


1
@GorrillaApe: xem câu trả lời này để biết ví dụ về cách quay lại ngôn ngữ mặc định, nếu không tìm thấy ngôn ngữ mong muốn: stackoverflow.com/a/27474681/19635
M4N
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.