2009-08-24 59 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(因为您的缓存是基于该语言键控)。

您也可以考虑在产品表中保留默认的名称和说明字段,以便在当前语言缺少条目或进入时用户未指定语言时使用。如果你正在移植一个现有的应用程序,那么你也会有这种情况(没有语言环境信息)。