2011-04-05 41 views
3

假设我有表:数据库设计:如何支持多语种网站?

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)并把它放在一个带有“语言”栏的单独表格中。该新表将使用product.product_id作为FK。 (我的应用程序的第一个版本中我不会支持多种语言,这意味着我必须额外加入JOIN才能获得最初支持的语言的值)。
  3. 其他的东西我没有,考虑?
+0

解决方案2还意味着您必须确保每个产品都有每种语言的说明记录 - 否则,如果您使用内部联接,产品可能会消失。 – phoog 2011-04-05 22:35:46

+0

左连接将允许产品仍然出现。尽管如果您没有翻译,您可能不希望产品出现。这一切都取决于用例。 – 2011-04-05 22:38:06

+0

如果产品是您需要翻译的唯一表格,则选项2很好。否则,您需要为需要翻译的每个实体提供一个新的翻译表。 – 2011-04-05 22:43:37

回答

4

我会解决2.

此选项将最大限度地减少你的第一个版本,你的工作去,将减少不改变列之间的重复。

它确实需要额外的JOIN,但它是一个简单的键连接,因此它不会影响您的性能。

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 

您可能还需要类似“默认翻译”添加到密钥表,这样增加了翻译是可选的,且具有后备价值。

最后,考虑在应用中缓存这些数据,因为它不可能经常更改。

+0

你是对翻译每个基础表是正确的。我有点担心,因为我已经有很多桌子了。您的解决方案似乎与我在Amazon Web服务中看到的有点相似(我认为这种方法被称为“类别判别式”)。无论如何,我仍然试图完全理解你的解决方案中的关系。你有没有遇到过任何问题? – StackOverflowNewbie 2011-04-05 23:11:22

+0

基本上,您正在创建各自具有跨多种语言的翻译的文本键。如果您有具体问题,请随时回复。我没有遇到任何使用此模型的问题。类似的问题,我在这里给出了相同的答案:http://stackoverflow.com/questions/4289874/is-this-good-design-for-multi-language-of-system-text-to-support-x-number -of琅/ 4289909#4289909。 – 2011-04-05 23:49:19

+0

什么是product.product_name_key_id和product.product_description_key_id有关? – StackOverflowNewbie 2011-04-06 00:18:27

1

我会使用(2)的一点修改版本。我认为不要删除产品表中的namedescription列 - 在这种情况下,如果本地化版本不存在,您将始终拥有产品的默认值。

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' 

它确实在那里你拉的产品信息将需要一个左加入到翻译表,然后决定做什么的意思是每查询如果没有翻译值:返回默认语言术语(如我在上面的示例中所示)或返回null。

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