web-dev-qa-db-ja.com

多言語データベース設計のベストプラクティスは何ですか?

多言語データベースを作成する最良の方法は何ですか?すべてのテーブルにローカライズされたテーブルを作成するには、デザインとクエリを複雑にします。他の場合、各言語に列を追加するのは簡単ですが、動的ではありません。

177
Arsen Mkrtchyan

私たちがしていることは、多言語オブジェクトごとに2つのテーブルを作成することです。

例えば。最初の表には言語に依存しないデータ(主キーなど)のみが含まれ、2番目の表には言語ごとに1つのレコードが含まれ、ローカライズされたデータと言語のISOコードが含まれます。

場合によっては、DefaultLanguageフィールドを追加して、指定された言語のローカライズされたデータが利用できない場合にその言語にフォールバックできるようにします。

例:

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>

このアプローチを使用すると、必要な数の言語を処理できます(新しい言語ごとにフィールドを追加する必要はありません)。


更新(2014-12-14): この回答 をご覧ください。多言語データをアプリケーションにロードするために使用される実装に関する追加情報があります。

197
M4N

Martinが投稿した回答をお勧めします。

しかし、クエリが複雑になりすぎることを心配しているようです:

すべてのテーブルにローカライズされたテーブルを作成するには、設計とクエリを複雑にします...

そのため、次のような単純なクエリを書く代わりに、考えているかもしれません。

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

...次のようなクエリの作成を開始する必要があります。

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

あまりきれいな視点ではありません。

ただし、手動で行う代わりに、独自のデータベースアクセスクラスを開発する必要があります。これは、特別なローカリゼーションマークアップを含むSQLを事前解析し、データベースに送信する必要がある実際のSQLに変換します。

そのシステムを使用すると、次のようになります。

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

そして、あなたはそれをもっとうまくできると確信しています。

重要なのは、テーブルとフィールドに同じ名前を付けることです。

14
Rene Saarsoo

私はこのタイプのアプローチが私にとってうまくいくと思います:

製品ProductDetail国
 =================================== 
 ProductId ProductDetailId CountryId 
-etc-ProductId CountryName 
 CountryId Language 
 ProductName-etc-
 ProductDescription 
-etc-

ProductDetailテーブルには、サポートする言語でのすべての翻訳(製品名、説明など)が保持されます。アプリの要件に応じて、地域の言語も使用するように国テーブルを分類することをお勧めします。

13
Nick

私は次のアプローチを使用しています:

製品

ProductID OrderID、...

製品情報

ProductIDタイトル名LanguageID

言語

LanguageID名前文化、....

9
omoto

マーティンのソリューションは私のものと非常に似ていますが、目的の翻訳が見つからない場合にデフォルトの説明をどのように処理しますか?

各フィールドにIFNULL()と別のSELECTステートメントが必要ですか?

デフォルトの翻訳は同じテーブルに保存されます。「isDefault」などのフラグは、現在の言語で何も見つからなかった場合の説明がデフォルトの説明であることを示します。

2
doM