多语言目录(带自定义字段)数据库结构设计
很快我将致力于支持多语言内容的目录(php+mysql)。现在我正在考虑设计数据库结构的最佳方法。目前,我看到了 3 种多语言处理方法:
1)为每种语言特定数据建立单独的表,即示意性地看起来像这样:
- 将有一个表 Main_Content_Items,存储不能的基本数据可以像 ID、创建日期、点击量、投票等一样进行翻译 - 它只是一种,并且涉及所有语言。
以下是将为每种语言复制的表格:
- Common_Data_LANG 表(例如:common_data_en_us)(存储可以翻译的通用/“静态”字段,但存在于所有目录项中:标题、描述等等...)
- Extra_Fields_Data_LANG 表(存储可以翻译的额外字段数据,但对于自定义项目组可能有所不同,即:| id | item_id | field_type | value | ... ) 然后,根据项目请求,我们将根据用户/默认语言在表中查找,并将可翻译数据与 main_content 表连接起来。
优点:
- 我们可以更新“主要”数据(即点击量、投票数...),这些数据最常通过一个查询更新,
- 我们不需要 o 如果我们有 4 种或更多语言(与结构相比),则重复数据 4 倍或更多次仅使用一张带有“lang”字段的表。因此,MySql 查询将花费更少的时间来浏览 100000 条(例如)记录目录,而不是 400000 条或更多
。 缺点:
- 每种语言 +2 表
2) 在内容表中使用“lang”字段:
- Main_Content_Items 表(存储无法翻译的基本数据,如 ID、创建日期、点击量、投票等...)
- Common_Data 表(存储可被转换的公共/“静态”字段)已翻译,但存在于 eny 目录项: | item_id | desc | 等...)
- Extra_Fields_Data 表(存储可翻译的额外字段数据 |自定义项目组不同,例如: | id | lang | value 因此,我们将根据“lang”字段将 common_data 和 extra_fields 连接到 main_content_items。
优点:
- 我们可以更新最常更新的“主要”数据(即点击量、投票...),只需一个查询,
- 我们只有 3 个内容数据表
缺点:
- 我们有 custom_data 和 extra_fields 表,其中填充了所有语言的数据,因此它的 X 倍更大,查询运行速度更慢
3) 与第二种方式相同,但 Main_Content_Items 表与 Common_Data 合并,具有“lang”字段:
优点:
- ...?
缺点:
- 我们需要更新“主要”数据(即点击量、投票数...),对于每种语言,这些数据最常更新,
- 我们有 custom_data 和 extra_fields 表,其中填充了所有语言的数据,因此它的大小增加了 X 倍,并且查询运行较慢
会很高兴听到有关“什么更好”和“为什么”的建议?或者还有更好的方法吗?
提前致谢...
Soon I'll be working on catalog(php+mysql) that will have multilang content support. And now I'm considering the best approach to design the database structure. At the moment I see 3 ways for multilang handling:
1) Having separate tables for each language specific data, i.e. schematicly it'll look like this:
- There will be one table Main_Content_Items, storing basic data that cannot be translated like ID, creation_date, hits, votes on so on - it will be only one and will refer to all languages.
And here are tables that will be dublicated for each language:
- Common_Data_LANG table(example: common_data_en_us) (storing common/"static" fields that can be translated, but are present for eny catalog item: title, desc and so on...)
- Extra_Fields_Data_LANG table (storing extra fields data that can be translated, but can be different for custom item groups, i.e. like: | id | item_id | field_type | value | ...)
Then on items request we will look in table according to user/default language and join translatable data with main_content table.
Pros:
- we can update "main" data(i.e. hits, votes...) that are updated most often with only one query
- we don't need o dublicate data 4x or more times if we have 4 or more languages in comparison with structure using only one table with 'lang' field. So MySql queries would take less time to go through 100000(for example) records catalog rather then 400000 or more
Cons:
- +2 tables for each language
2) Using 'lang' field in content tables:
- Main_Content_Items table (storing basic data that cannot be translated like ID, creation_date, hits, votes on so on...)
- Common_Data table (storing common/"static" fields that can be translated, but are present for eny catalog item: | id | item_id | lang | title | desc | and so on...)
- Extra_Fields_Data table (storing extra fields data that can be translated, but can be different for custom item groups, i.e. like: | id | item_id | lang | field_type | value | ...)
So we'll join common_data and extra_fields to main_content_items according to 'lang' field.
Pros:
- we can update "main" data(i.e. hits, votes...) that are updated most often with only one query
- we only 3 tables for content data
Cons:
- we have custom_data and extra_fields table filled with data for all languages, so its X time bigger and queries run slower
3) Same as 2nd way, but with Main_Content_Items table merged with Common_Data, that has 'lang' field:
Pros:
- ...?
Cons:
- we need to update update "main" data(i.e. hits, votes...) that are updated most often with for every language
- we have custom_data and extra_fields table filled with data for all languages, so its X time bigger and queries run slower
Will be glad to hear suggestions about "what is better" and "why"? Or are there better ways?
Thanks in advance...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在这个问题中给出了类似的答案 并强调了这种技术的优点(例如,对于我来说,让应用程序决定语言并通过仅更改
lang
参数来相应地构建查询是很重要的SQL 查询的 >WHERE 子句与您的第二个解决方案非常接近,我不太明白“extra_fields”,但如果它有意义,您可以(!)合并。我建议您不要使用第一个想法,因为表太多,并且很容易丢失其中的项目。
对于您的编辑:我仍然认为第二种方法更好(它是更好的方法)。我的选择所以它是相对的;))我不是优化专家,但我认为使用适当的索引和适当的表结构速度应该不是问题。与往常一样,找到最有效方法的最佳方法是同时使用这两种方法,看看哪种方法最好,因为速度会因数据、结构等而异。
I've given a similar anwer in this question and highlighted the advantages of this technique (it would be, for example, important for me to let the application decide on the language and build the query accordingly by only changing the
lang
parameter in theWHERE
clause of the SQL query.This get's pretty close to your second solution. I didn't quite got the "extra_fields" but if it makes sense, you could(!) merge it into the common_data table. I would advise you against the first idea since there will be too many tables and it can be easy to lose track about the items in there.
To your edit: I still consider the second approach the better one (it's my optinion so it's relative ;)) I'm no expert on optimization but I think that with proper indexes and proper table structure speed should be not be a problem. As always, the best way to find the most effective way is doing both methods and see which is best since speed will vary from data, structure, ....