Suggestion for database structure for multilanguage
Using PHP 5.x and 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 span开发者_StackOverflow中文版ish 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. 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; 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_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 :
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
- 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. All in one query, and all you need are 3 arguments: the story id, the desired language, and a default fallback language.
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. 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.
So in my musical "genres" table, there is a text field named "lang". On in I have the following json structure:
{"es_gl":"MARCHA ESPAÑOLA", "es_EN" : "SPANISH MARCH"}
Then using PHP is really easy to get our data from a json structure. Let's say I have a genre on my $genre variable.
$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.
精彩评论