【问题标题】:Database modeling for international and multilingual purposes用于国际和多语言目的的数据库建模
【发布时间】:2025-12-23 00:40:15
【问题描述】:

我需要为多语言的 Web 应用程序创建一个大规模的 DB 模型。

我每次思考如何做到这一点时都有一个疑问,那就是如何解决一个字段的多个翻译问题。一个案例。

管理员可以从后端编辑的语言级别表可以有多个项目,例如:基本、高级、流利、重要......在不久的将来可能会增加一种类型。管理员去后端添加一个新级别,它会在正确的位置对其进行排序.. 但是我如何处理最终用户的所有翻译?

数据库国际化的另一个问题是,对于用户研究而言,可能会因美国、英国和德国而异……在每个国家/地区,他们都会有自己的水平(可能与另一个国家等价,但最终不同)。那么计费呢?

您如何进行大规模建模?

【问题讨论】:

  • 附带说明,请确保使用 UTF-8 编码创建表。
  • 您使用的是什么技术?大多数现有框架都很好地管理 i18n。
  • @sp00m:我正在使用 PHP。网站的语言没有问题,“静态”的。我要求管理员可以从网站后端添加的东西......添加时他们不能只为 1 项添加 15 种语言。可能在这个话题上谈论语言/语言级别也不对。或者你是说在数据库上管理 i18n 也很好?谢谢!

标签: mysql database database-design internationalization multilingual


【解决方案1】:

以前关于此主题的一些 * 问题:

一些有用的外部资源:

最好的方法通常是,为每个现有表格创建一个新表格,将文本项移入其中;新表的PK是旧表的PK加上语言。

在你的情况下:

  1. 管理员可以从后端编辑的语言级别表可以有多个项目,例如:基本、高级、流利、重要......在不久的将来可能会增加一种类型。管理员去后端添加一个新级别,它会在正确的位置对其进行排序.. 但是我如何处理最终用户的所有翻译?

您现有的表格可能如下所示:

+----+--------+---------+ |编号 |价格 |类型 | +----+--------+---------+ | 1 | 299 |基本 | | 2 | 299 |提前| | 3 | 399 |流利 | | 4 | 0 |物质 | +----+--------+---------+

然后变成两张表:

+----+-------+ +----+------+-------------+ |编号 |价格 | |编号 |朗 |类型 | +----+-------+ +----+------+-------------+ | 1 | 299 | | 1 | zh |基本 | | 2 | 299 | | 2 | zh |提前| | 3 | 399 | | 3 | zh |流利 | | 4 | 0 | | 4 | zh |物质 | +----+-------+ | 1 |法语 |元素 | | 2 |法语 |前卫 | | 3 |法语 |钱| : : : : +----+------+-------------+
  1. 数据库国际化的另一个问题是,对于用户研究而言,可能会因美国、英国和德国而异……在每个国家/地区,他们都会有自己的水平(可能与另一个国家等价,但最终不同)。那么计费呢?

所有本地化都可以通过类似的方法进行。除了将文本字段移动到新表之外,您还可以移动任何可本地化的字段 - 只有所有语言环境共有的字段才会保留在原始表中。

【讨论】:

  • 嗨@eggyal。这种方法仍然有效且最好吗?如果是这样,当我有一个目前无法更改表的数据库时,我应该如何关注?
【解决方案2】:

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

DB Designer Fork的可视化

i18n 表仅包含一个 PK,因此任何表只需引用此 PK 即可将字段国际化。然后表translation 负责将这个通用ID 与正确的翻译列表联系起来。

locale.id_locale 是一个VARCHAR(5) 来管理enen_US ISO syntaxes

currency.id_currency 是一个CHAR(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 来优化你的查询。您还可以使用索引来提高查询性能(在某些数据库中,外键会自动建立索引,例如MySQL/InnoDB)。

【讨论】:

  • 好的,这是非常容易理解和有用的解释。我唯一的问题 - 在内存和服务器资源方面为每个本地化字符串使用 TEXT 类型会不会很昂贵?
  • @f_martinez 我想这取决于您需要存储的数据。但是请随意使用您需要的类型,例如,如果它可以适合 varchar。
  • 不要混用货币翻译
  • 冬青废话!我现在非常爱你! @f_martinez 如果你的数据库主要是读取操作,有几层缓存,它可能不会有什么可担心的。
  • @inkalimeva 我更新了我的答案以提供一个示例,希望对您有所帮助:)