我必须国际化一个项目,它不仅是应用程序的标签,我还必须将目录国际化,例如
国家:
我不想创建像下一个模型:
CREATE TABLE country (
id_country INT NOT NULL AUTO_INCREMENT,
name_es VARCHAR(100) NOT NULL,
name_en VARCHAR(100) NOT NULL,
....................,
PRIMARY KEY (`id_country`));
有没有最佳实践,模式设计或框架来解决这个问题?因为我认为这是一个常见问题。我正在考虑下一个型号:
CREATE TABLE country (
id_country INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
languaje VARCHAR(100) NOT NULL,
PRIMARY KEY (`id_country`));
问题是我将只为一个国家/地区拥有许多外键,因此查询会更复杂。
我正在使用Java,Spring启动,Spring数据,JavaServer Faces,Primefaces。
我希望你能帮助我。
由于
答案 0 :(得分:2)
老实说,我发现XML中的翻译最灵活,并且更好地融入版本控制。人类的做法也更容易。
但是,数据库允许灵活使用,过滤,排序等。
可以使用某些评估的东西:报告,完整性检查,统计。
table Texts
id int auto_incr -- internally
key varchar 30 -- public key in software
comment varchar 80 -- translator info, like noun, in menu
categ varchar 20 -- glossar entry / menu / help / tooltip
sortkey varchar 20 -- to order the translation
...
table Locales
locale varchar 10
table Translations
textid int
locale varchar 160
我们的想法是为翻译人员准备和协调工作。 翻译记忆库格式也可用于导出/导入以翻译服务。 词汇表对于拥有一致的术语非常重要。 在开发方面进行翻译的努力提高了质量,并且节省了工作。
production 数据库可以是摘录,甚至是生成的java ListResourceBundle:字符串数组。
答案 1 :(得分:1)
如果按目录标题排序对您来说不是问题,最好的方法是将翻译保留在属性文件中,而不是表格中的标题列,在表格中添加一个键列并使用该键根据区域设置引用标题。这种方法的缺点是您无法根据标题对数据进行排序。好处是你不受限制你想支持的语言数量。
但是,如果排序,分组......数据库查询的功能很重要,那么除了使用字典表之外别无选择,如其他答案中所述。这种方法的缺点是查询性能较低,因为与字典表的连接很多,当然缺少密钥的风险,会使你使用外连接的性能更差!
字典表结构如下:
CREATE TABLE dictionary(
id INT NOT NULL,
locale VARCHAR(2) NOT NULL,
value VARCHAR(100) NOT NULL,
PRIMARY KEY (id, locale);
和例如国家/地区表将是这样的:
CREATE TABLE country (
id_country INT NOT NULL AUTO_INCREMENT,
name_dictionary_id INT NOT NULL,
....................,
PRIMARY KEY (`id_country`));
以及按本地检索国家/地区列表的查询将如下所示:
select
c.id_country, d.value
from
country c
left outer join dictionary d
on (c.name_dictionary_id = d.id and d.locale = :locale)
order by d.value asc
:locale是必须根据用户/浏览器请求的语言环境发送给查询的参数。
当您创建新国家/地区时,您需要获取受支持的语言环境的所有名称,并为每个语言环境插入一个字典,所有字典都具有相同的ID,但区域设置不同。
答案 2 :(得分:0)
是的,这是一个常见问题,并且有最佳做法。
对于不太可能改变的静态文本 - 例如国家/地区名称,最佳做法是使用客户端(而不是DB端)本地化。在这种情况下,您将DB条目视为键并从资源文件(或消息源,根据您希望如何实现它)读取翻译。 JSF在这里不会帮助你,你必须创建自己的bean来阅读翻译的名称。
对于动态文本(即经常更改或可由用户输入的内容),最佳做法是使用带有复合键的查找表:
CREATE TABLE translation (
key VARCHAR(100) NOT NULL,
languageid VARCHAR(20) NOT NULL,
translation VARCHAR(100) NOT NULL,
PRIMARY KEY (`key`, `languageid`));
再一次,您可以将原始条目视为密钥,但不建议这样做。实际上,即使是静态场景也不建议使用它 - 它会强制您重复使用相同文本的翻译。问题是,翻译可能因上下文而有所不同......所以最好使用独特的翻译键,即使这意味着没有语言中立的翻译。
答案 3 :(得分:0)
首先,对不起我的英语水平。
在我的职业生涯中,我曾两次面对你的问题。
在这两种情况下,在开发之前我们都知道我们将使用哪种语言。第二个模型就是这样的:
CREATE TABLE Translations (
id_translation INT NOT NULL AUTO_INCREMENT,
es_ES VARCHAR(200),
en_UK VARCHAR(200),
...(more languages)
PRIMARY KEY ('id_translation')
);
CREATE TABLE Countries (
id_country INT NOT NULL AUTO_INCREMENT,
id_translation INT NOT NULL,
...
PRIMARY KEY ('id_country'),
FOREIGN KEY ('id_translation')
);
使用此模型,此密钥只有一个密钥(id_country
)和N
转换,其中N是Translations
数据表中的语言列数。将来,如果您需要添加新语言,则必须在Translations
数据表中添加新列。在您的查询中,您必须join Countries with Translations
(id_translation
)和SELECT
所选语言列。
如果您使用实体(JPA),您将实体Translation
包含在实体Country
中。使用此对象图,您可以创建一个辅助JSF组件,以根据所选语言显示正确的文本。
P.S。如果您的应用程序将多次访问您的数据库以显示翻译,我建议您使用Ehcache,Memcached或类似的等缓存系统来提高性能。
答案 4 :(得分:0)
正如之前提到的那样(如果我正确地看到其他两个答案),最好的是翻译部分不在数据库中,但由于你想要一切都在数据库中,这里是我的5美分。 我仍然没有想出如何在这里发布时正确格式化代码,所以很抱歉。另外我会写一些伪SQL,但我希望它会很清楚。
共有3个表格:
CREATE TABLE country (
id_country INT NOT NULL AUTO_INCREMENT,
//--optionally you could have name VARCHAR in default language
PRIMARY KEY (`id_country`));
CREATE TABLE language(
id_lang INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50),
PRIMARY KEY (`id_lang`));
CREATE TABLE countryInLanguage(
id_country REFERENCES country.id_country, //-- FK to country table
id_lang REFERENCES language.id_lang, //-- FK to language table
nameInLang VARCHAR(100),
PRIMARY KEY (`id_country, id_lang`));
表countryInLanguage称为关联表,表示N对N的关系。当然,您的查询必须访问两个表而不是一个但仅才能获得给定语言的国家/地区名称。我会说这并不复杂得多。至少它很容易扩展 - 如果你要添加新的国家或新语言。对于其他一切你将使用id_country。
这里有一些冗余存储空间被占用,例如,有许多语言n元组,其中一些国家名称以相同的方式编写,但不会过多地写入...
此外,您可以在国家/地区表中使用国家/地区名称列,该国家/地区名称列将使用默认语言保留国家/地区名称(默认最常用于特定应用,用户,公司等)。地狱,您甚至可以根据用户选择的默认语言更新这些默认值。
但是,我必须重复(我和其他人)翻译最好保存在人类可读的文件中。为什么?翻译你的应用程序的人通常不知道如何处理数据库和编写SQL语句和查询,但如果他们有一个文本文件(可以是XML,键值文件......)那么对他们来说很容易。