数据库设计 - 多语言网站

时间:2012-11-18 14:15:24

标签: mysql database-design

我有一个多语种网站,用户可以使用不同语言的个人资料,例如每个用户可以将他的个人资料发布为“英语”,“法语”和“西班牙语”,类似于LinkedIn。

现在,我是以“英语”语言浏览网站的用户,所以当我转到其他会员资料页面时,我会看到该会员资料为“英文”,如果该资料不可用语言,我应该在该成员“main_lang”中看到该配置文件。

所以我有一个“成员”表,其中有一列为“published_profile_langs”,在这个列中,每个成员发布其个人资料的语言将以逗号分隔:“english,spanish”和“main_lang” col是用户的主要语言(他的个人资料肯定是在main_lang中发布的,因为我们要求提供有关注册步骤的详细信息)。

另一方面,成员详细信息存储在不同的表中,例如“members_details_english”,“members_details_spanish”,“members_details_french”。

我想加入我的查询,但似乎不可能以我管理的方式,目前我需要使用2个查询来加载上述场景中的成员详细信息,我在“members_profile.php”中的代码是:

// 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
        }

有没有更好的方法来实现这一目标?或许可以一次查询一次而不是两次?这个场景有更好的数据库结构吗?

我很感激任何帮助

3 个答案:

答案 0 :(得分:1)

尝试将语言视为数据库中的另一个实体。使用表members来存储所有不依赖于语言的数据,并使用第二个表来显示数据; members_i18n - memebers_internationalization的缩写。

在第一个表格中,您可以拥有一个名为main_language_id的列,并使用第二个表格为每个成员存储不同语言的数据列,并将其与member_idlanguage_id相关联。这样,您就可以获取所有语言中每个成员的数据,只需要获取主要语言或您需要的任何特定语言集。

另外,您不需要在表格中使用序列化数据,例如profile_published_langs

所以一些示例查询将是:

-- 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

编辑:

就个人而言,我通常使用第三个表格,其语言如下:

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');

我发现在打印多语言数据时非常有用。

编辑2:

因此,要以“当前”语言及其主要语言获取用户的数据,只需编写单个查询,如下所示:

-- 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'

最终会有一到两行,具体取决于会员的个人资料。

答案 1 :(得分:0)

您可以拥有表成员(id_user,mainlang,firstname,...)和表配置文件(id_user,语言以及该语言中的所有数据)。对于用户,每种语言都有一行。您的选择就像这样

select * from profile where id_user = $userId and language = $lang

答案 2 :(得分:0)

我可能会构建一个用户表,一个语言表和一个映射表

  1. user_main - 所有常用列,此处有邮件语言列
  2. 语言表 - 无论你想保留什么,代码等,还有一列 - lang表名(相当于你的user_details_spanish等表)
  3. 映射表 - 用户ID,lanague id(这里的一行意味着那个 特定用户拥有该语言的个人资料)
  4. 现在,我同意,您可能仍然需要两个查询,但我认为它更易于管理,因为表名可以从lang表中获得,并且您可以将其保留在会话中(例如,您让用户选择的位置)从下拉哪种语言切换到,表名可以在那里自己使用,这样你就不用去取它了... ...

    让我知道这个思想方向是否有帮助......也许我可以帮助进一步......