Database design 数据库本地化

Database design 数据库本地化,database-design,internationalization,schema,Database Design,Internationalization,Schema,我有许多数据库表,其中包含需要本地化的name和description列。我最初尝试设计一个支持这一点的DB模式,如下所示: product ------- id name description local_product ------- id product_id local_name local_description locale_id locale ------ id locale 但是,此解决方案需要为每个包含名称和需要本地化的描述列的表创建一个新的本地表。为了避免这种开销

我有许多数据库表,其中包含需要本地化的
name
description
列。我最初尝试设计一个支持这一点的DB模式,如下所示:

product
-------
id
name
description


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


locale
------
id
locale
但是,此解决方案需要为每个包含
名称
和需要
本地化
的描述列的表创建一个新的
本地
表。为了避免这种开销,我重新设计了模式,这样只需要一个
本地化

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
区域设置

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
请注意,
本地化
表的复合主键是
(id,locale\u id)
,但
产品
表中的外键仅指该复合主键的第一个元素。从正常化的角度来看,这似乎是一件“坏事”

是否有任何方法可以解决此问题,或者,是否有完全不同的模式支持本地化,而无需为每个可本地化的表创建单独的表

更新:
许多受访者提出了一种解决方案,要求为每个可本地化的表创建一个单独的表。然而,这正是我试图避免的。我上面提出的模式几乎解决了这个问题,让我满意,但我不满意的是,
localization\u id
外键只引用
localization
表中相应主键的一部分

谢谢,
Don

我认为正确的方法是创建额外的表,然后执行额外的步骤,从第一个表中删除所有特定于语言的资源

所以你会:

产品

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

我觉得很好。您描述的是产品与其本地化文本之间的一对多关系


我想知道您是否也应该本地化英文,而不是在产品表中对其进行非规范化。

如果我理解正确,您的问题只是因为您希望在多个表中对名称和描述使用相同的语言本地化。在这种情况下,您不能在本地化表中添加prod_id。设计中的另一个问题是,它无法优雅地处理同一产品的多个语言本地化。您可以调整它以使其工作:

如果名称和描述是唯一需要本地化的字段,则可以执行以下操作

产品(标识、名称、描述、交易行标识)

产品翻译(ID、名称、描述、语言ID、翻译ID)

translation_row_id将是指向Product_translations.id的外键 但是,翻译id将指向同一表中的父记录,该父记录将用作所有特定语言记录的公共记录

示例记录

产品

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

(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';
重要提示:我假设product表有更多不需要此转换的属性。
“&langID”是SQL查询的一个参数,它会向用户询问他选择的语言代码

我喜欢这个想法,但会朝另一个方向前进一步,并为翻译的每一列提供本地化条目:

国家

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
本地化的主键是(id,locale\u id)。在其他几个表中,id也是一个FK引用是没有问题的。如果需要,您可以添加一个代理PK,只要在(id,locale\u id)上仍然有一个唯一的索引

这是一个单一的本地化表,它适用于模式中的任何表,而不管它有哪些字段(不限于具有本地化的任何内容的名称和描述)。缺点是使用本地化表时可能会对性能造成影响——尽管可能只需为给定的locale_id缓存整个内容,因此在查找条目时只需查找给定的id(因为缓存已经基于语言设置了键)


您还可以考虑在Product表中保留默认名称和描述字段,在当前语言缺少条目的情况下使用,或者在输入时,用户没有指定语言。如果您正在移植一个现有的应用程序,您已经在那里有了值(没有区域设置信息)。

当有多个表包含可本地化内容时,此模式将不起作用。每个可本地化内容都需要一个额外的表。我认为你绕不过去。您可以看到,某些可本地化的表可能没有名称或描述,或者可能有更多需要翻译的字段。这当然打破了规范化的最佳实践。使用额外的表。在这种情况下,可以安全地假设每个可本地化的表只需要一个名称和描述就可以本地化。我已经修改了模式以纳入您的建议本地化的全部要点是“东西”和名称之间存在一对多的关系。因此,很自然地,“thing”表中的引用不能是本地化表的完整主键,因为这会将关系约束为一对一。执行多对一关系的更常见的方法是将“一”端的标识符发布到“多”端,但在这里这样做会有问题,因为本地化表将必须引用许多不同的表,这会导致混乱、定义松散的外键引用。很好的建议,我可以尝试一下。不过,我很高兴