我不得不在问卷数据库中处理这个问题。多个问卷需要翻译成多种语言(英语、日语、中文)。
我们首先确定了将打印在问卷上的所有文本列。对于所有这些,我们需要能够存储翻译。对于每个包含需要翻译的文本列的表,然后我们创建了一个 _translations 表,其中有一个指向原始表主键的外键、一个指向我们的语言表的外键,然后每个文本字段都有一个 unicode 列那需要翻译。在这些文本列中,我们将存储我们需要的每种语言的翻译。
所以一个典型的查询看起来像:
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
因此,总是只有一个额外的连接(对于每个表)来获取翻译。
我应该指出,我们只需要处理有限数量的表,因此维护一些额外的 %_translations 表并不是什么大问题。
我们确实考虑为新语言添加列,但出于几个原因决定不这样做。首先,不知道要支持的语言数量,但可能很多(10 种、20 种或更多)。结合大多数表格至少有 3 个不同的人类可读列的事实,我们将不得不添加许多文本列,这将导致非常宽的行。所以我们决定不这样做。
我们考虑的另一种方法是制作一个大的“标签”表,其中包含以下列:
(table_name、id_of_table、column_name、language_id、translated_text)
有效地拥有一张表来存储数据库中任何位置的所有翻译。我们也决定不这样做,因为它会使编写查询复杂化(因为每个“正常”列都会在转换表中产生一行,这将导致有效地将已经很大的转换表多次连接到正常表(每个翻译的列)。对于您的示例表,您将获得如下查询:
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
如您所见,本质上类似于实体-属性-值设计,这使得查询起来很麻烦。
最后一种方法的另一个问题是,即使不是不可能,也很难对翻译文本实施约束(在我们的例子中主要是单一性约束)。使用单独的翻译表,您可以轻松干净地克服这些问题。