简体   繁体   English

多语言数据库结构建议

[英]Suggestion for database structure for multilanguage

Using PHP 5.x and MySQL 5.x使用 PHP 5.x 和 MySQL 5.x

So I asked a question yesterday about the best way of handling dynamic data in multilanguage, this question is what would be a good solution for the database structure to handle this.所以我昨天问了一个关于用多语言处理动态数据的最佳方法的问题,这个问题是数据库结构处理这个问题的一个好的解决方案。 I have entries in the database for things like stories.我在数据库中有故事之类的条目。 My plan is to store a different version of the story for each language available in a db.我的计划是为数据库中可用的每种语言存储不同版本的故事。 So if the site supports english and spanish then in the admin tool they can add a english version of a story and a spanish version of a story.因此,如果网站支持英语和西班牙语,那么他们可以在管理工具中添加故事的英语版本和故事的西班牙语版本。

My thoughts on that was to have seperate tables in the db, one for each language.我对此的想法是在数据库中有单独的表,每种语言一个。 So one story table for english version, one for spanish and one for whatever other languages.因此,一张用于英文版的故事表,一张用于西班牙语,一张用于其他任何语言。 Then on the front end I simply allow the visitor to select what language to view the site in and via variables know what table to query to get that version of the story.然后在前端,我只是允许访问者 select 以什么语言查看站点,并通过变量知道要查询哪个表以获取该版本的故事。 But one issue is what if there isnt a spanish version but they selected spanish?但是一个问题是如果没有西班牙语版本但他们选择了西班牙语怎么办? Is that a good solution or is there a better way of doing this?这是一个好的解决方案还是有更好的方法来做到这一点? Looking for suggestions.寻找建议。

Having multiple tables is really not necessary, unless you plan on having millions of stories... I usually go along with two tables;真的没有必要拥有多张桌子,除非你打算拥有数百万个故事......我通常是 go 和两张桌子; one for the item and another for the localized item一个用于项目,另一个用于本地化项目

For example, a story would be like例如,一个故事就像

table "story"表“故事”

id INTEGER (Primary Key)
creation_date DATE_TIME
author VAR_CHAR(32)
..other general columns..

table "story_localized"表“story_localized”

story_id INTEGER (Foreign Key of story.id) \
lang CHAR(2)                               -- (Indexed, unique -- story_id+lang)
content TEXT
..other localized columns..

Performing the query is simply a matter of JOIN ing the two tables:执行查询只是JOIN两个表的问题:

SELECT s.*, sl.*
  FROM story s
  JOIN story_localized sl ON s.id = sl.story_id
 WHERE s.id = 1         -- the story you're looking for here
   AND sl.lang = 'en'   -- your language here
   -- other conditions here

This configuration gives a few advantages:这种配置有几个优点:

  • all your data is in the same table, no need to synchronizing CRUD operations您所有的数据都在同一个表中,无需同步 CRUD 操作
  • you can add new languages to any story without the need to create yet more tables您可以在任何故事中添加新语言,而无需创建更多表格
  • etc.等等

** EDIT ** **编辑**

Just as a bonus, here is a "trick" to retrieve a story easily, regardless of the language it's been written into作为奖励,这是一个轻松检索故事的“技巧”,无论它是用什么语言编写的

SELECT *
  FROM (SELECT * 
          FROM story s
          JOIN story_localized sl ON s.id = sl.story_id
         WHERE s.id = {storyId}
           AND sl.lang = {desiredLanguage}    -- example : 'es'
        UNION
        SELECT * 
          FROM story s
          JOIN story_localized sl ON s.id = sl.story_id
         WHERE s.id = {storyId}
           AND sl.lang = {defaultLanguage}    -- example : 'en'
        UNION
        SELECT * 
          FROM story s
          JOIN story_localized sl ON s.id = sl.story_id
         WHERE s.id = {storyId}
         LIMIT 1                              -- ..get the first language found
) story_l
LIMIT 1              -- only get the first SELECTed row found

Will try to fetch the story in the {desiredLanguage} , if the story is not available in that language, try to find it in {defaultLanguage} (ie. the site's default language), and if still nothing found, it doesn't matter which language to fetch the story, then, so fetch the first one found.将尝试获取{desiredLanguage}中的故事,如果该故事不支持该语言,请尝试在{defaultLanguage} (即站点的默认语言)中找到它,如果仍然没有找到,那没关系获取故事的语言,然后,获取找到的第一个。 All in one query, and all you need are 3 arguments: the story id, the desired language, and a default fallback language.一站式查询,您只需要 3 个 arguments:故事 ID、所需语言和默认后备语言。

Also, you can easily find out in what language the story is available into with a simple query:此外,您可以通过一个简单的查询轻松找出故事可用的语言:

SELECT sl.lang
  FROM story_localized sl
 WHERE sl.story_id = {storyId}

The best way to do this is to store the story as a multi-valued attribute.最好的方法是将故事存储为多值属性。 As @Yanick has shown you.正如@Yanick 向您展示的那样。 And it would be interfacially better if you populate your language choice element only with those languages in which that story is available.如果您仅使用该故事可用的那些语言填充您的语言选择元素,那么界面会更好。

Another nice approach when it is not a long text: weeks names, monts... in my app I am localizing musical genres, and musical instruments.当文本不是长文本时,另一种不错的方法是:星期名称、蒙特...在我的应用程序中,我正在本地化音乐流派和乐器。 Use a text field for store json data.使用文本字段存储 json 数据。

So in my musical "genres" table, there is a text field named "lang".所以在我的音乐“流派”表中,有一个名为“lang”的文本字段。 On in I have the following json structure:在我有以下 json 结构:

{"es_gl":"MARCHA ESPAÑOLA", "es_EN" : "SPANISH MARCH"}

Then using PHP is really easy to get our data from a json structure.然后使用 PHP 很容易从 json 结构中获取我们的数据。 Let's say I have a genre on my $genre variable.假设我的 $genre 变量上有一个流派。

$myJSON = json_decode($genre->lang);
echo $myJSON->es_gl // This echoes MARCHA ESPAÑOLA
echo $myJSON->es_es // This echoes SPANISH MARCH

This is good solution when your localization data is not big... like posts or blogs.当您的本地化数据不大时,这是一个很好的解决方案……比如帖子或博客。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM