2011-04-05 75 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