数据库设计:如何支持多语言网站?

时间:2011-04-05 22:29:28

标签: mysql database database-design data-modeling

假设我有桌子:

TABLE: product
=================================================================
| product_id | name           | description                     |
=================================================================
| 1          | Widget 1       | Really nice widget. Buy it now! |
-----------------------------------------------------------------

如果我想提供多语言支持,那么最好的方法是什么?

可能的解决方案:

  1. 在上表中添加“语言”列;这将表明特定记录的语言。 (我不认为这是我的选择,因为其他表将使用product.product_id作为其FK。)
  2. 删除产品表中的任何可翻译列(在上面的示例中,product.name和product.description),并将其放在带有“language”列的单独表中。该新表将使用product.product_id作为FK。 (我不会在我的应用程序的第一个版本中支持多语言。这个解决方案意味着我必须做一个额外的JOIN才能获得最初支持的语言的值。)
  3. 我没有考虑的其他事情?

5 个答案:

答案 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)的一点修改版本。我认为不要从产品表中删除namedescription列 - 在这种情况下,如果本地化版本不存在,您将始终拥有产品的默认值。

答案 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 JOINCOALESCE获取特定语言版本,但可以使用英语版本:

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