2009-08-24 109 views
8

我有一個數字,包含namedescription列這就需要進行本地化數據庫表。我在設計一個能夠支持這樣的數據庫架構初步嘗試是這樣的:數據庫本地化

product 
------- 
id 
name 
description 


local_product 
------- 
id 
product_id 
local_name 
local_description 
locale_id 


locale 
------ 
id 
locale 

然而,這種解決方案需要一個新的local_表包含name和描述列要求localization每個表。在試圖避免這種開銷我重新設計,使得僅需要一個單一的localization

product 
------- 
id 
localization_id 


localization  
------- 
id  
local_name 
local_description 
locale_id 


locale 
------ 
id 
locale 

下面是其將被存儲在這個模式中的數據的一例的模式時,有2個表(產品和國家)需要本地化:

國家

id,  localization_id 
----------------------- 
1,  5 

產品

id,  localization_id 
----------------------- 
1,  2 

本地化

id,  local_name, local_description,  locale_id 
------------------------------------------------------ 
2,  apple,  a delicious fruit,  2 
2,  pomme,  un fruit délicieux, 3 
2,  apfel,  ein köstliches Obst, 4 
5,  ireland,  a small country,  2 
5,  irlande,  un petite pay,   3 

區域

id,  locale 
-------------- 
2,  en 
3,  fr 
4,  de 

注意,localization表的化合物主鍵是(id, locale_id),但在product表的外鍵僅指這種化合物PK的第一個元素。這似乎是正常化POV的「壞事」。

有沒有什麼辦法可以解決這個問題,或者是有沒有支持本地化而不考慮每個本地化表創建一個單獨的表完全不同的架構?

更新: 一些答覆提出,需要對每個本地化表創建一個單獨的表中的溶液。但是,這正是我想要避免的。我上面幾乎提出的方案解決了這個問題讓我滿意,但我不滿的事實localization_id外鍵僅指在localization表中相應的主鍵的一部分。

謝謝, 唐

+1

「但我對LOCAL_ID外鍵僅引用本地化表中相應主鍵的一部分這一事實感到不滿。 我沒有看到問題,從產品到本地化有一對多的關係,數據庫結構遵循要求,你已經找到了一個很好的解決方案。 – 2010-10-01 13:45:51

+0

這應發佈在http://dba.stackexchange.com/ – 2014-09-27 05:42:12

回答

1

正確的方法,我覺得,是創建額外的表,但後來去了額外的步驟,並從第一個表中刪除所有的語言特定資源。

所以你必須:

產品

id 
-name removed 
-description removed 

產品本地化

productid, locale_id, name, description 
------------------------------------------------------ 
1,   3,   pomme, un fruit délicieux 
1,   4,   apfel, ein köstliches Obst 
1,   1,   apple, a delicious fruit 

區域

id,  locale 
-------------- 
1,  en 
3,  fr 
4,  de 
+0

當有多個表包含可本地化的內容時,此架構將不起作用 – 2009-08-24 15:18:24

+0

您將需要每個可本地化內容的額外表。我不認爲你可以解決這個問題。一些localisable表可能沒有名稱或描述,你看,或可能有更多的領域需要翻譯。這當然會打破正常化的最佳實踐。使用額外的表格。 – DanDan 2009-08-24 15:21:33

+0

在這種情況下,它是安全的假設,*每*本地化表將只需要一個名稱和說明進行本地化 – 2009-08-24 15:25:38

3

我認爲沒關係。您正在描述產品與其本地化文本之間的一對多關係。

我想知道你是否應該本地化英文,而不是在產品表中對它進行非規範化處理。

+0

我已經修改了方案,以將您的建議 – 2009-08-24 15:36:54

+2

本地化的整點是,有一到「事物」和名字之間的多種關係。因此,「thing」表中的引用自然不能成爲本地化表的完整主鍵,因爲這會將關係限制爲一對一。執行多對一關係的更常見方式是將「one」端的標識符發佈到「many」端,但這樣做會遇到問題,因爲本地化表必須引用許多不同的表,從而導致混亂,鬆散定義的外鍵引用。 – Jay 2009-08-24 16:10:56

1

如果我理解正確,你的問題只是因爲你想在多個表中使用相同的languale本地化名稱和描述。在這種情況下,您不能在本地化表格中添加prod_id。您的設計中的另一個問題是,它無法爲同一產品優雅地處理多種語言本地化。你可以調整它的工作:

如果名稱和描述是唯一需要本地化的字段,您可以執行以下操作。

產品(ID,名稱,描述,tanslation_row_id)

Product_translations(ID,名稱,描述,LANG_ID,translation_id)

的translation_row_id將外鍵指向Product_translations.ID 的translation_id會,然而在同一個表中指出一個父記錄,作爲所有語言特定記錄的通用記錄。

示例記錄

產品

(ID, name, description, translation_row_id) 
(p1, apples,a red fruit, tr1) 
(p2, mango, a yellow fruit, tr2) 

Product_translations

(ID, name, description, lang_id, translation_id) 
(tr1, apples, a red fruit, ENU, null) 
(tr2, mango, a yellow fruit, null) 
(tr3, pomme,un fruit rouge, FRA,tr1) 
(tr4, mangue,a yellow fruit, SPA,tr2) 

給定一個語言代碼,你可以使用FOLL SQL查詢

select T.name, T.description 
from product_translations T 
where T.translation_id = 
    (select T2.ID 
     from Product P,Product_translations T2 
     where P.translation_row_id = t2.ID 
    ) 
    and T.lang_id = '&langID'; 
提取名稱和描述值

重要說明:我假定產品表具有許多不需要此翻譯的屬性。 「& LANGID」是SQL查詢,將要求用戶自己選擇

+0

很好的建議,我可以試試這個。但是,我可能會從產品(和其他可本地化的)表中刪除名稱和說明,因爲它似乎是多餘的。此外,product_translations表應該叫更多的東西一般像「翻譯」,因爲在現實中,它會包含本地化國家,產品,等等。 – 2009-08-24 15:47:34

2

我喜歡這個主意的語言代碼,但會走在其他方向邁出的一步,並有每列本地化條目的參數被翻譯:

國家

id,  localization_id 
----------------------- 
1,  5 

產品

id,  name_locale_id, description_locale_id 
---------------------------------------------- 
1,  2,    8 

本地化

id,  locale_id, value 
------------------------------------------------------ 
2,  2    apple 
2,  3    pomme 
2,  4    apfel 
5,  2    ireland 
5,  3    irlande 
8,  2    a delicious fruit 
8,  3    un fruit délicieux 
8,  4    ein köstliches Obst 
9,  2    a small country 
9,  3    un petite pay 

區域

id,  locale 
-------------- 
2,  en 
3,  fr 
4,  de 

本地化的PK是(ID,LOCALE_ID)。在其他幾個表中,id也是FK參考是沒有問題的。如果你願意,你可以添加一個代理PK,只要你在(id,locale_id)上還有一個唯一索引。

關於這一點的好處是它是一個單一的本地化表,它適用於您的架構中的任何表,無論它具有哪些字段(您不限於具有本地化的任何名稱和描述) 。缺點是在使用本地化表時潛在的性能受到影響 - 儘管潛在地,您可以緩存給定locale_id的整個內容,所以當您查找條目時,您只需查找給定的ID(因爲您的緩存是基於該語言鍵控)。

您也可以考慮在產品表中保留默認的名稱和說明字段,以便在當前語言缺少條目或進入時用戶未指定語言時使用。如果你正在移植一個現有的應用程序,那麼你也會有這種情況(沒有語言環境信息)。