假设我有桌子:
TABLE: product
=================================================================
| product_id | name | description |
=================================================================
| 1 | Widget 1 | Really nice widget. Buy it now! |
-----------------------------------------------------------------
如果我想提供多语言支持,那么最好的方法是什么?
可能的解决方案:
答案 0 :(得分:4)
我会选择解决方案2.
此选项可以最大限度地减少您的第一个版本的工作,并减少不更改的列之间的重复。
它需要一个额外的JOIN
,但这是一个简单的键连接,所以它不会对你的表现产生太大影响。
答案 1 :(得分:4)
我会使用第三种替代方案,它是您现有设计和解决方案#2的混合体。表格中存在的列现在代表您的“中性”或默认语言。然后,您将为每个需要翻译的值添加一个表,其中包含主表的PK,语言代码的键以及父表中需要翻译的每个值的列。所以我们可能
Create Table product_translations
(
product_id int not null References product( id )
, language_code varchar(5) not null
, name ...
, description ...
, Primary Key ( product_id, language_code )
...
)
您的查询将如下所示:
Select P.product_id
, Coalesce( PT.name, P.name ) As Name
From product As P
Left Join product_translations As PT
On PT.product_id = P.product_id
And PT.language_code = 'en-UK'
它确实意味着您提取产品信息的每个查询都需要左键连接到翻译表,然后决定在没有翻译值时该怎么做:返回默认语言术语(如我在上面的示例中所示)或return null。
答案 2 :(得分:1)
我会使用(2)的一点修改版本。我认为不要从产品表中删除name
和description
列 - 在这种情况下,如果本地化版本不存在,您将始终拥有产品的默认值。
答案 3 :(得分:0)
我认为选项#2会在错误的方向上创建1:M关系。现在,您需要一个需要翻译的基表的转换表。
我使用的最新解决方案,适用于您的样本:
language
--------------
language_id
language_name
language_key
-------------
language_key_id
lang_key_name (or description)
translation
-------------------
translation_id
language_id
language_key_id
translation_text
product
--------------
product_id
product_name_key_id
product_description_key_id
您还可能希望在密钥表中添加“默认翻译”之类的内容,以便添加翻译是可选的,并且具有后备值。
最后,请考虑在您的应用中缓存此数据,因为它不太可能经常更改。
答案 4 :(得分:0)
您确定始终至少用英语提供所有内容吗?翻译的数量是否相当小?如果是这样,我会按原样保留product
,并为每个翻译添加一个类似的表格:
TABLE: product_fi
=================================================================
| product_id | name | description |
=================================================================
| 1 | Vimpain 1 | Tosi kiva vimpain. Osta heti! |
-----------------------------------------------------------------
然后您可以OUTER JOIN
和COALESCE
获取特定语言版本,但可以使用英语版本:
SELECT
coalesce(fi.name, en.name) AS name,
coalesce(fi.description, en.description) AS description
FROM product en
LEFT OUTER JOIN product_fi fi ON en.product_id = fi.product_id
WHERE en.product_id = 1