私はアンケートデータベースでこれに対処しなければなりませんでした。複数のアンケートを複数の言語 (英語、日本語、中国語) に翻訳する必要がありました。
最初に、アンケートに印刷されるすべてのテキスト列を特定しました。これらすべてについて、翻訳を保存できる必要があります。翻訳が必要なテキスト列を持つテーブルごとに、元のテーブルの主キーを指す外部キー、言語テーブルへの外部キー、および各テキスト フィールドの Unicode 列を持つ _translations テーブルを作成しました。それには翻訳が必要です。これらのテキスト列には、必要な各言語の翻訳を保存します。
したがって、典型的なクエリは次のようになります。
select p.id
, pt.product_name
, pt.product_description
from product p
inner join product_translations pt
on p.id = pt.product_id
and 'fr' = pt.language_code
そのため、翻訳を取得するために、(テーブルごとに) 常に 1 つの追加の結合のみを行います。
限られた数のテーブルを処理するだけでよかったので、いくつかの追加の %_translations テーブルを維持することは大きな問題ではありませんでした。
新しい言語用に列を追加することも検討しましたが、いくつかの理由から断念しました。まず第一に、サポートされる言語の数は不明でしたが、かなりの数になる可能性があります (10、20、またはそれ以上の言語)。ほとんどのテーブルには少なくとも 3 つの個別の人間が読める列があるという事実と組み合わせると、非常に多くのテキスト列を追加する必要があり、結果として非常に幅の広い行になります。だから私たちはそれをしないことにしました。
列を持つ 1 つの大きな「ラベル」テーブルを作成するために検討した別のアプローチ:
( table_name 、 id_of_table 、 column_name 、 language_id 、translated_text)
データベース内の任意の場所にすべての翻訳を格納する 1 つのテーブルを効果的に持つ。クエリの作成が複雑になるため、これにも反対することにしました (「通常の」列ごとに変換テーブルに 1 つの行が作成され、すでに大きな変換テーブルが通常のテーブルに複数回 (それぞれに 1 回) 効果的に結合されるため)。例のテーブルでは、次のようなクエリが得られます。
select product.id
, product_name.translated_text product_name
, product_description.translated_text product_description
from product p
inner join translations product_name
on p.id = product_name.id
and 'product' = product_name.table_name
and 'product_name' = product_name.column_name
and 'fr' = product_name.language
inner join translations product_description
on p.id = product_name.id
and 'product' = product_description.table_name
and 'product_description' = product_description.column_name
and 'fr' = product_description.language
ご覧のとおり、本質的にこの種のエンティティ属性値の設計に似ているため、クエリが煩雑になります。
最後のアプローチのもう 1 つの問題は、翻訳されたテキストに制約 (この場合は主に単一性制約) を適用することが不可能ではないにしても困難になることです。翻訳用の別のテーブルを使用すると、これらの問題を簡単かつきれいに克服できます。