Reputation: 1849
I'm having a multilingual website which it's users are able to have profile in different languages, for example each user could have his profile published in "English" and "French" and "Spanish", something like LinkedIn.
Now, I'm a user who is seeing the website in "English" language, so while I go to other members profile page, I should see that member profile in "English", if that profile is not available in that language, I should see that profile in that member "main_lang".
So I have a "members" table which has a column as "published_profile_langs", in this col the languages which each member has published his profile in is gonna be stored comma separated: "english,spanish", and "main_lang" col which is the user main language (his profile is definitely published in main_lang since we're asking for details on sign up step).
In another hand, members details are stored in different tables, such as "members_details_english", "members_details_spanish", "members_details_french".
I want to join my query, but it seems it's not possible in the way which I managed, currently I need to use 2 queries for loading the members details in the mentioned above scenario, my code in "members_profile.php" is:
// FIRST QUERY
$check_member = mysql_query("SELECT main_lang, profile_published_langs FROM members WHERE id = '$this_user_id'");
while($row = mysql_fetch_array($check_member)){
$this_main_lang = $row['main_lang'];
$this_profile_published_langs = $row['profile_published_langs'];
}
$this_profile_published_langs_arr = explode(',', $this_profile_published_langs);
if(!in_array($lang, $this_profile_published_langs_arr)) $lang = $this_main_lang;
$details_table = 'members_details_' . $lang;
// SECOND QUERY
$get_details = mysql_query("SELECT * FROM $details_table WHERE member_id = '$this_user_id'");
while($row_details = mysql_fetch_array($get_details)){
//blah blah
}
Is there any better way to achieve this? maybe someway to query once and not twice? any better database structure for this scenario?
I would appreciate any kind of help
Upvotes: 0
Views: 977
Reputation: 879
Try considering language as just another entity in the database. Use the table members
to store all data not dependant on the language, and have a second table with data that is; members_i18n
- short for memebers_internationalization
.
In the first table you can have a column called main_language_id
and use the second table to store columns for data in different languages for each member by relating to it with member_id
and language_id
. This way you can fetch data for each member in all languages, just their main language, or any specific set of languages you need.
Plus, you won't need to use serialized data in your tables like profile_published_langs
.
So a few example queries would be:
-- Main language
SELECT *
FROM member AS m
JOIN member_i18n AS mi
ON m.member_id = mi.member_id
AND m.main_language_id = mi.language_id
-- Specific language
SELECT *
FROM member AS m
JOIN member_i18n AS mi
ON m.member_id = mi.member_id
WHERE mi.language_id = 'eng'
-- All languages
SELECT *
FROM member AS m
JOIN member_i18n AS mi
ON m.member_id = mi.member_id
EDIT:
Personally, I usually use a third table with languages that looks like this:
CREATE TABLE `language` (
`language_id` char(3) NOT NULL,
`name` varchar(30) NOT NULL,
`code2` char(2) NOT NULL,
PRIMARY KEY (`language_id`)
);
-- Sample data
INSERT INTO `language` (`language_id`, `name`, `code2`) VALUES
('deu', 'Deutsch', 'de'),
('eng', 'English', 'en');
I found it to be very useful when printing out multilingual data.
EDIT 2:
So to fetch data for a user in the "current" language and their main language, just write a single query like this:
-- Current language (i.e. 'eng') + member's main language
SELECT *
FROM member AS m
JOIN member_i18n AS mi
ON m.member_id = mi.member_id
WHERE mi.language_id = m.main_language_id
OR mi.language_id = 'eng'
You'll end up with one or two rows, depending on the member's profile.
Upvotes: 1
Reputation: 2238
I would probably build a user table, a language table and a mapping table
Now, i would agree, that you might still need two queries, but I think its much more manageable since the table name is available from the lang table, and you might keep it in session (e.g. where you let the user choose from a drop down which language to switch to, the table name can be available there itself, so that you dont have to fetch it)...
Let me know if this direction of thought helps.. perhaps I can help further...
Upvotes: 0
Reputation: 1
You can have a table members (id_user, mainlang, firstname, ...) and a table profile (id_user, language, and all data in that language). and for a user you have a row for each language. Your select is like this
select * from profile where id_user = $userId and language = $lang
Upvotes: 0