到目前为止,已经有几个问题,他们都得到了相同的答案:一个用于语言中性数据的表,1- *用于带有翻译的表和一个索引语言ID字段
这有几个问题:
许多数据库人员已经解决了各种理论和实践问题,但令人惊讶的是很少有人在这方面工作。
我认为我们最终需要的是:
过度破坏?当然,也许,但整个问题都是真正的噩梦。这并不是一个不寻常的情况。
我们必须设法说服服务器供应商解决这个问题。
编辑:顺便说一句,这是我第一次使用社区维基;希望我做得对。
编辑2:我的措辞似乎让人们认为我正在攻击DBMS的概念。我不是;我只是说内置的本地化支持是一个非常需要的功能。
我可能不应该提到表现;在大多数情况下,它当然完全可以忽略不计。我担心的焦点是这个真的扼杀了生产力。
我将提供一个例子。假设我有一个非常简单的表来处理一个非常简单的商店:
Products (id, price, description, name, slug)
在EF / MVC中,我将它放在ORM设计器中,可能将其封装在存储库中,构建一个Products控制器,并为索引,详细信息,创建,更新,编辑和删除操作。要识别任何项目中的产品,我只需要做一个WHERE(slug = @slug)。我为创建/编辑操作创建了一个视图模型,设计了表单控件,并将其直接连接到存储库。做完了。要访问产品的详细信息,用户将转到/products/details/product-slug
。
但是,由于网站的其余部分是双语的,我决定相应地更改产品表。
Products (id, price)
ProductsText (productId, language, description, name, slug)
嘿,那不是那么糟糕。是的,还没有。然后你编写你的关系和你的约束,然后你写你在视图模型中写出你的所有属性,然后你为ProductsText数据创建一个完整的CRUD控制器或使用jQuery / Ajax添加创建/更新/编辑按钮在您的Products控制器上,然后添加验证逻辑以确保用户至少输入主要语言,然后当您想要读取最终用户页面的数据时,您编写另一个查询以连接ProductsText.slug和ProductsText。语言与产品...我可能错过了一些东西,但你明白了。
一旦涉及到本地化,程序的复杂性就会随着样板代码而爆炸。
当然,我不认为问题可以完全解决,而且显然也是一个UI问题,因为它是一个数据库问题。但是,可以做到这一点,以使这一切变得更容易。 “多字符串”字段类型可能是一个非常好的开始。
编辑3:有人听说过SQL Server建模服务吗?它有some localization tools,可能是朝着正确方向迈出的一步。仍然是CTP。
-- Simulate the French locale with the SET LANGUAGE statement.
SET LANGUAGE French
select Id, CountryName,
[System.Globalization].[SessionsString](CountryName, 1) as CountryNameString
from [Location].[CountriesTable]
答案 0 :(得分:5)
什么是本地化数据库字段?
通常在我们工作的应用程序中,UI已本地化。这是使用数据库完成的,我们将所有翻译(可能还有主要短语)放在表中,其中locale-code和phraseid是主键。这是相当简单的,需要一组可重复使用的存储过程并具有良好的性能,并且使用方法已被充分理解。我们经常允许动态翻译,以便应用程序界面包含一个翻译功能,可以进行更正,其他用户可以看到它们 - 丰富的表单应用程序或Web表单应用程序(取决于缓存 - 这是UI本地化的另一个关键功能) )
就查询需要连接而言 - 这只是规范化关系数据库中的生活现实,而且性能通常采用良好的规范化设计和正确的索引进行管理。
在其他“数据”中,除了在应用程序要求的指导下,本地化没有多大意义。例如,即使您可能在多个国家/地区提供产品,SKU和分销商也可能不同。这种级别的本地化是非常特定于应用程序的,我们经常把它作为一个单独的数据库来处理,并且确实没有任何东西将这些单独的国家数据库捆绑在一起 - 尽管在其他国家可能有相同的产品,但许多产品都没有。 / p>
如果您在世界各地销售相同的产品,那么您会陷入一种多语言CMS的原始场景。这需要除低级数据库之外的重要工作。例如,如果某人更正了默认的产品说明,那么翻译需要更正的翻译人员的标记是什么?这些问题非常重要。虽然我可以看到数据库供应商可以在哪些方面协助功能,但这些都是应用程序需求和设计的固有困难,而不一定是数据库可以添加将普遍解决的功能。
整理问题确实有点尴尬。通常,数据存储在nvarchar中,并且在编写存储过程时,您不会知道要检索的排序规则,因为区域设置将是一个参数。这只会影响检索到的需要按内容排序的集合,通常不是自然键,当然也不是按键检索 - 这不是一个大问题,而是一个没有动态SQL就无法轻松处理的集合(使用表格中的首选排序规则进行转换)根据传入的位置,如果混合来自不同语言环境的数据,则必须首先确定是否要按语言环境排序,然后可能难以选择可能在同一结果集中的所有语言环境中正常工作的排序规则)。您可能希望使用具有如此多种数据的Windows排序规则。
与ORM类似,我们通常将locale / phraseid的复合唯一键视为检索对象的密钥(我们通常还有代理身份主键) - 我知道传统的ORM不一定喜欢这种从检索的偏离通过无意义的代理键。
答案 1 :(得分:4)
我遇到了本地化CRM风格网站的所有这些问题。设计和优化并不好玩,但可以做到。我的2¢值得:
<强> 1。 CRUD的两倍。
这取决于您的CRUD的设计方式。我可以检索可能已本地化的字段的任何存储过程或函数都使用locale / culture代码参数。所有这些字段也NVARCHAR
,以避免编码问题。
<强> 2。如果你想要一个非常友好的网页用户界面,需要Ajax CRUD。
我想是的,但这取决于应用程序。应遵循“内部”CRUD(DRY原则)。
第3。验证的两倍以上 - 您需要确保关系为1- *而不是0 - *。
这也假设所有受支持的语言环境都需要所有内容,而不是使用回退机制。例如,Microsoft的MSDN内容在多个语言环境中可用,但有些只有一个(通常这是美国英语,Microsoft的“中立”语言环境)。
对于CRM风格的系统,任何区域设置都可用于初始内容,只要后备使用该内容即使中性内容不可用。
<强> 4。不符合语言之间的整理差异。
我发现将所有归类支持放在UI /报告层更容易。具有逐行指定的排序规则/区域设置的多语言感知表将是一个非常好的功能,但我不想等待它变得可用...
<强> 5。查询需要连接。
是的,肯定会使查询更复杂:-)但没有真正的解决方法。如果包含区域设置回退,则可能会变得更复杂(“区域设置特性”排名字段在此处有帮助)。
<强> 6。如果你想要多种语言的slu ,,哦,男孩。
这就是格式字符串中的.NET替换参数被设计为索引的原因,而不是位置(printf()
等是位置的)。英语格式可能需要以1,2,3顺序替换,而德语等效使用3,1,2。
为了让本地化程序更轻松,每当我创建.NET资源包时,我都会记录参数,包括索引,数据类型(包括最小和/或最大字符串长度)和上下文描述 - 上下文对于确定文本性别非常重要在某些地区。
多个也可能需要多个相关资源,因为某些语言环境需要的不仅仅是“单个”和“复数”(例如“0个文件”,“1个文件”,“2个文件”)。
相同的规则必须适用于数据库中的任何可本地化的列。
答案 2 :(得分:1)
到目前为止,答案并没有那么有用。我在过去做的各种项目中遇到了同样的问题。从来没有一个快捷方式或开箱即用的解决方案帮助我以简单的方式解决了这个问题。但是你的方法正朝着正确的方向发展,只需要对你的数据访问层做一些工作,就可以实际上抽象出这个要求造成的所有负担。
因此,对于类型,类别,国家等元数据,性能不是问题,因为可以缓存整个内容。对于自由文本条目,它是一个不同的故事。你很可能无法缓存它们,它们往往很长。
您可能已经知道这些页面:
http://www.codeproject.com/KB/aspnet/LocalizedSamplePart2.aspx http://www.sisulizer.com/online-help/DatabaseLocalization.shtml Best-practices for localizing a SQL Server (2005/2008) database
答案 3 :(得分:0)
根据我的经验,我并不常遇到存储在数据库中的数据具有许多相同文本的语言相关版本的问题。通常,开发的应用程序将为所有文本提供许多语言文件,这些文本或多或少地静态构建到应用程序中。然后我们看到文本用户输入的数据库数据。虽然具有许多不同语言的用户可以使用应用程序,但用户以多种语言键入相同文本的情况并不常见。通常,应用程序的使用将以其语言显示UI,然后以其语言输入和查看数据。
例如,我们在美国与荷兰或沙特阿拉伯的应用程序的用户会看到他们选择的语言的UI,但对于任何给定的安装,他们输入的数据将始终使用他们的母语。
显然这不适用于所有情况。 CRM就是一个例子,你可能会有多个翻译的相同文本,比如维基百科,但我认为上面描述的是更常见的情况。
答案 4 :(得分:0)
“很多数据库人员都在处理各种理论和实践问题,但令人惊讶的是很少有人在这方面工作。”
那是因为从你的例子中,从理论的角度来看,没有什么可以解决的。你提到的所谓“问题”,只不过是你管理更多数据的直接后果。
“两倍的CRUD。”
为什么这是一个问题?我知道至少有一些我构建的系统比你的例子更多。
“如果你想要一个非常友好的网络用户界面,需要Ajax CRUD。”
真的是这样吗?我不知道,但无论如何,在表示层中如何处理数据,DBMS并不关心,如果程序员认为它太难/繁琐,那么就不要责怪DBMS。
验证的两倍以上 - 您需要确保关系是1- *而不是0 - *。
为什么这是一个问题?如果声明了更多业务规则,则需要进行更多验证。
“不符合语言之间的整理差异。”
怎么样?将英文文本与法文整理的意义何在?乌克兰语或俄语或中文的英文文本?或者你的意思是其他什么?
“查询需要加入。”
为什么这是一个问题?
“如果你想要多种语言的slu ,,哦,小伙子。”
在什么情况下?出于什么目的?
SELECT语言,nllabel FROM ... NATURAL JOIN(选择'EN'作为语言UNION SELECT'FR'作为语言)
哦,等等,我忘了......加入也是一个问题。
答案 5 :(得分:-2)
“这显然是一个UI问题,因为它是一个数据库问题。”
我不同意这是。从数据库角度查看问题时,有两件事可能是解决方案的一个小问题:
可以进行全视图更新(通过JOIN和GROUP,根据您的情况)。 在数据库表中具有“table”类型属性的可能性。然后,您可以将整套适用的本地化名称 - 东西作为单个行中的sinle属性用于您的产品/...
至于全视图更新:不要屏住呼吸。你到达之前很久就会窒息。
至于嵌套表:它们可能已经存在,如果有人有甲骨文意志,我真的不知道,但我真的不相信这会在UI方面让生活更轻松。
哦,BTW:SQL远不是“理论上纯粹的”。