可能性のある複製:
多言語データベースのスキーマ
以下に例を示します。
[ products ]
id (INT)
name-en_us (VARCHAR)
name-es_es (VARCHAR)
name-pt_br (VARCHAR)
description-en_us (VARCHAR)
description-es_es (VARCHAR)
description-pt_br (VARCHAR)
price (DECIMAL)
問題:すべての新しい言語はテーブル構造を変更する必要があります。
別の例を次に示します。
[ products-en_us ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
[ products-es_es ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
問題:すべての新しい言語では新しいテーブルを作成する必要があり、「価格」フィールドはすべてのテーブルで複製されます。
別の例を次に示します。
[ languages ]
id (INT)
name (VARCHAR)
[ products ]
id (INT)
price (DECIMAL)
[ translation ]
id (INT, PK)
model (VARCHAR) // product
field (VARCHAR) // name
language_id (INT, FK)
text (VARCHAR)
問題:ハード?
3番目の例は、実際に問題が通常解決される方法です。ハード、しかし実行可能。
変換テーブルから製品への参照を削除し、必要な場所に翻訳への参照を配置します(逆の場合)。
[ products ]
id (INT)
price (DECIMAL)
title_translation_id (INT, FK)
[ translation ]
id (INT, PK)
neutral_text (VARCHAR)
-- other properties that may be useful (date, creator etc.)
[ translation_text ]
translation_id (INT, FK)
language_id (INT, FK)
text (VARCHAR)
別の方法(特に良い方法ではありません)として、1つのフィールドを持ち、そこにあるすべての翻訳を(たとえばXMLとして)マージしたままにすることができます。
<translation>
<en>Supplier</en>
<de>Lieferant</de>
<fr>Fournisseur</fr>
</translation>
方法3と同様:
[languages]
id (int PK)
code (varchar)
[products]
id (int PK)
neutral_fields (mixed)
[products_t]
id (int FK)
language (int FK)
translated_fields (mixed)
PRIMARY KEY: id,language
そのため、各テーブルに対して、翻訳済みフィールドを保持する別のテーブル(私の場合は接尾辞「_t」)を作成します。 SELECT * FROM products
、単に... LEFT JOIN products_t ON products_t.id = products.id AND products_t.language = CURRENT_LANGUAGE
。
それほど難しくはなく、頭痛から解放されます。
JOINの数を減らすために、翻訳済みと未翻訳を別々の2つのテーブルに分けておくことができます。
[ products ]
id (INT)
price (DECIMAL)
[ products_i18n ]
id (INT)
name (VARCHAR)
description (VARCHAR)
lang_code (CHAR(5))
私の$ DAYJOBでは、I18Nにgettextを使用しています。 xgettext.pl にプラグインを作成しました。このプラグインは、すべての英語のテキストをデータベーステーブルから抽出し、それらをマスターmessages.potに追加します。
それは非常にうまく機能します-翻訳者は翻訳を行うときに1つのファイル、poファイルのみを扱います。翻訳を行う際にデータベースエントリをいじることはありません。
[言語] id(int PK)コード(varchar)
[products]
id (int PK)
name
price
all other fields of product
id_language ( int FK )
私は実際にこの方法を使用しますが、私の場合は、製品の観点ではありません。CMSのさまざまなページで、この作業は非常にうまくいきます。
多数の製品がある場合、5つまたは6つの言語で1つの製品を更新するのは頭痛の種かもしれませんが、レイアウトの問題です。
4番目のソリューションはどうですか?
[ products ]
id (INT)
language (VARCHAR 2)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
*translation_of (INT FK)*
* Translation_of *は[〜#〜] fk [〜#〜]それ自身です。デフォルト言語を追加すると、* translation_of *はNullに設定されます。ただし、2番目の言語を追加すると、* translation_of *はプライマリ製品の言語IDを取ります。
SELECT * FROM products WHERE id = 1 AND translation_of = 1
その場合、IDが1の製品のすべての翻訳を取得します。
SELECT * FROM products WHERE id = 1 AND translation_of = 1 AND language = 'pl'
ポーランド語の翻訳でのみ製品を取得します。 2番目のテーブルとJOINSなし。