29

我需要为多语言Web应用程序创建大型数据库模型。用于国际和多语言目的的数据库建模

有一个疑问,我每次想到如何做到这一点,就是我如何解决一个领域的多个翻译问题。一个案例。

管理员可以从后端编辑的语言级别表可以包含多个项目,如:basic,advance,fluent,mattern ...在不久的将来,它可能会是另外一种类型。管理员进入后端并添加一个新的级别,它会将其排序在正确的位置..但我如何处理最终用户的所有翻译?

数据库国际化的另一个问题是,用户研究可能会有所不同,从美国到英国到德国......在每个国家,他们都会有自己的水平(这可能会相当于另一个国家,但最后会有所不同) 。那么结算呢?

如何在大范围内建模?

+3

请注意,请确保使用UTF-8编码创建表格。 –

+0

你使用什么技术?现有的大多数框架都能很好地管理i18n。 – sp00m

+0

@ sp00m:我正在使用PHP。网站的语言,即“静态”语言没有问题。我要求管理员可以从网站的后端添加的内容...添加时,他们无法仅为1项添加15种语言。大概在这个话题上谈论语言/ language_levels是不对的。或者你是否也在说管理i18n对数据库有好处?谢谢! – udexter

回答

48

这里是我设计数据库的方式:

Data model

可视化的DB Designer Fork

i18n表只包含一个PK,让任何表只是要参考这个PK来实现一个领域的国际化。表translation然后负责将该通用ID与正确的翻译列表关联起来。

locale.id_localeVARCHAR(5)来管理的enen_USISO syntaxes

currency.id_currencyCHAR(3)来管理ISO 4217 syntax

您可以找到两个示例:pagenewsletter。这两个管理员管理的实体需要国际化其领域,分别为title/descriptionsubject/content

下面是一个例子查询:

select 
    t_subject.tx_translation as subject, 
    t_content.tx_translation as content 

from newsletter n 

-- join for subject 
inner join translation t_subject 
    on t_subject.id_i18n = n.i18n_subject 

-- join for content 
inner join translation t_content 
    on t_content.id_i18n = n.i18n_content 

inner join locale l 

    -- condition for subject 
    on l.id_locale = t_subject.id_locale 

    -- condition for content 
    and l.id_locale = t_content.id_locale 

-- locale condition 
where l.id_locale = 'en_GB' 

    -- other conditions 
    and n.id_newsletter = 1 

注意,这是一个标准化的数据模型。如果你有一个庞大的数据集,也许你可以考虑denormalizing it来优化你的查询。您还可以使用索引来提高查询性能(在某些DB中,外键会自动编入索引,例如MySQL/InnoDB)。

+1

好吧,这是非常容易理解和有用的解释。唯一的问题 - 从内存和服务器资源的角度来看,使用TEXT类型的每个本地化字符串都不会很昂贵吗? –

+0

@f_martinez我想这取决于你需要存储的数据。但是可以随意使用你需要的类型,例如它可以适合varchar。 – sp00m

+6

请勿混用**货币**和**翻译**。 – gavenkoa

27

有关这个主题的一些先前StackOverflow的问题:

个一些有用的外部资源:

最好的办法通常是,对于每一个现有的表,创建成文本项移动新表;新表的PK是旧表的PK和语言一起的。

你的情况:

  1. 对语言水平的表中,管理员可以从后台编辑,可以有多个项目,如:基本,高级,流利,Mattern的......在不久的未来可能它会成为一种类型。管理员进入后端并添加一个新的级别,它会将其排序在正确的位置..但我如何处理最终用户的所有翻译?

    你现有的表可能看起来是这样的:

     
    +----+-------+---------+ 
    | id | price | type | 
    +----+-------+---------+ 
    | 1 | 299 | basic | 
    | 2 | 299 | advance | 
    | 3 | 399 | fluent | 
    | 4 |  0 | mattern | 
    +----+-------+---------+ 
    

    然后它变成两个表:

     
    +----+-------+ +----+------+-------------+ 
    | id | price | | id | lang | type  | 
    +----+-------+ +----+------+-------------+ 
    | 1 | 299 | | 1 | en | basic  | 
    | 2 | 299 | | 2 | en | advance  | 
    | 3 | 399 | | 3 | en | fluent  | 
    | 4 |  0 | | 4 | en | mattern  | 
    +----+-------+ | 1 | fr | élémentaire | 
           | 2 | fr | avance  | 
           | 3 | fr | couramment | 
           : :  :    : 
           +----+------+-------------+ 
    
  2. 与数据库的internationalitzation另一个问题是,可能是用户研究可以有所不同,从美国到英国到DE ...在每个国家,他们将有他们的水平(这可能会相当于另一个,但fi最后,不同)。那么结算呢?

    所有本地化都可以通过类似的方法发生。不仅仅是将文本字段移动到新表中,您可以移动任何可本地化的字段 - 只有那些对所有语言环境通用的字段才会保留在原始表中。