数据库创建。附加列或附加表

时间:2015-08-10 08:08:52

标签: sql postgresql database-design

我正在为多语言应用程序(俄语和英语)开发服务器。所有文本将存储在一个表中,文本将具有俄语和英语版本。一开始,几乎所有文本都没有英文版。我看到两个解决方案: 1)存储在不同列中的俄语和英语版本的文本(将是许多空值)。 2)在第一列中存储第二列中的文本和语言ID。然后我将需要一个表,它将存储文本组(例如,文本“Vodka”和“Водка”是一个文本组,但具有不同的语言ID)。

一个用户只能使用一种语言。从性能的角度来看,哪些解决方案更好?

1 个答案:

答案 0 :(得分:1)

我不认为它在性能上有很大的不同,但只有一个文本列的文本表具有动态的优势。即如果您一次添加第三种语言,则不必更改您的查询。

每种语言的文字列:

select
  (select case when :lang = 'RU' then text_ru else text_en end from i18n where id = p.id_i18n_name and lang = :lang) as name,
  (select case when :lang = 'RU' then text_ru else text_en end from i18n where id = p.id_i18n_color and lang = :lang) as color,
  (select case when :lang = 'RU' then text_ru else text_en end from i18n where id = p.id_i18n_description and lang = :lang) as description
from products p;

(如果您添加了第三种语言,则必须重新编写此查询以及所有其他语言。)

每种语言一条记录:

select
  (select text from i18n where id = p.id_i18n_name and lang = :lang) as name,
  (select text from i18n where id = p.id_i18n_color and lang = :lang) as color,
  (select text from i18n where id = p.id_i18n_description and lang = :lang) as description
from products p;

在这种情况下,您也可以编写存储过程:

select
  i18n_text(id_i18n_name, :lang) as name,
  i18n_text(id_i18n_color, :lang) as color,
  i18n_text(id_i18n_description, :lang) as description
from products;

这具有良好的可读性的魅力,您可以将默认语言定义为过程中的回退,以便无法找到所需语言的条目。

因此,为了便于使用,我建议使用一个文本列,其中包含一个文本列,语言ID作为主键的一部分。如上所述,我并不期望在性能方面产生重大影响,因为您总是通过主键访问i18n记录。

所以答案是:每个文本一个记录,而不是两个列。每种语言的列都会丢失所有动态。它仍然是一个表,只有两个记录。 ("组"只是一个I18N ID有两个记录。)你可能想要一个额外的语言表(EN =英语,RU =俄语等)。

Table I18N

ID  LANG  TEXT
1   EN    Vodka
1   RU    ?????
2   EN    Rum
2   RU    ...

Primary Key = ID + LANG