多言語データベース設計のベストプラクティスは何ですか?[閉まっている]


193

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



3
私は私には、この非常に役に立ったと評価していました:MySQLで多言語データベースの設計
Siamak A.Motlagh

回答:


223

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

たとえば、最初のテーブルには言語中立データ(主キーなど)のみが含まれ、2番目のテーブルにはローカライズされたデータと言語のISOコードを含む、言語ごとに1つのレコードが含まれます。

場合によっては、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):多言語データをアプリケーションにロードするために使用される実装に関する追加情報については、この回答をご覧ください。


15
言語に中立なフィールドがidのみの場合はどうなりますか?そして、行を挿入するときに外部キー参照を正確にどのように挿入しますか?
Timo Huovinen、2010

4
面白いことに、私は多言語CMSのデータベーススキームを設計していて、この質問も頭の中にありました。私はこの答えを見る前に、このアプローチを選びました!この回答をありがとう!
Patrick Manser 2013年

5
ここで注意すべき点の1つは、このテーブルにPKがないか、IDと言語が複合PKである必要があることです。それか、おそらくIDとしてProductTranslationIdフィールドを追加する必要があります。
Daniel Lorenz

1
@Luca:私はあなたの質問に答え、データのロードに使用する実装を示しました。
M4N 2014

1
@AarónGutiérrezさて、おかしなことに、id:D という単一の列を持つテーブルを作成します。説明すると、それぞれidがリレーショナルテーブルの任意の言語からの単語を付加できる意味を表すため、meaning(id)とword(id、senseing_id)の2つのテーブルを取得idwordます。テーブルのは単語idを表し、idはをmeaning表します普遍的な意味。
Timo Huovinen、

18

マーティンが投稿した答えをお勧めします。

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

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

したがって、次のような単純なクエリを作成する代わりに、

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");

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

重要なのは、テーブルとフィールドに統一された方法で名前を付けることです。


もう1つの質問は、製品の1つのビジネスオブジェクトを作成することです。または2つを作成する...最初のケースでは、そのアイテムを操作するのは簡単です。2つ目は、CMSを簡単に作成できます
Arsen Mkrtchyan

14

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

製品ProductDetail国
========= ================== =========
ProductId ProductDetailId CountryId
-etc-ProductId CountryName
            CountryId言語
            ProductName-など-
            製品説明
            -など-

ProductDetailテーブルは、サポートしたい言語でのすべての翻訳(製品名、説明など)を保持します。アプリの要件によっては、国の表を細かく分類して地域の言語を使用することもできます。


私が現在取り組んでいるプロジェクトでも、同じ方法を選択しました。これは、さまざまなロケールに、単位系とユーザーに表示されるメジャーに関する非常に具体的な情報が含まれているためです。
califrench 2014

8
国と言語(ロケール)は異なります。また、ISO言語コードは自然なキーなので、langから国への不要な結合を排除できます。
ギベンコア2014年

10

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

製品

ProductID OrderID、...

製品情報

製品IDタイトル名言語ID

言語

言語ID名前カルチャ、....


2

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

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

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


1
@GorrillaApe:目的の言語が見つからなかった場合にデフォルトの言語にフォールバックする方法の例については、この回答を参照してください:stackoverflow.com/a/27474681/19635
M 4 N
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.