2

我什至在发布之前就已经回答了我的问题,但我不确定这是否是最好的解决方案。这是业务问题:

支持i18l的固定数据表。该应用程序完全支持区域设置,但页面上显示的一些文本来自数据库。这是一个例子:

表是“期间”:

INSERT INTO PERIOD (lang, ref, desc) VALUES
('en', 'HOUR', 'Hourly'),
('en', 'WEEK', 'Weekly'),
('en', 'MONTH', 'Monthly'),
('de', 'HOUR', 'Stündlich'),
('de', 'WEEK', 'Wöchentlich'),
('de', 'MONTH', 'Monatlich');

我不使用自动生成的 ID 的原因是因为当有人使用德语网站并选择“Wochentlich”每周出现一次时,我们希望,如果区域设置更改为英语,我们希望“每周”为显示。如果我们使用 ID,那么它将被固定为实际选择的项目,我们最终会得到像“这个客户有一个 wochtenlich 常设订单”这样的句子——你可以看到这有点愚蠢。所以我们通过将“ref”存储为“外键”来解决它。获取此类数据的每个查询都使用“ref”和“lang”参数来获取当前设置语言的正确项目。

我知道缺点,因为我们无法将 VARCHAR 指定为外键,因此我们无法在数据库中获得正确的关系。(我们使用的是 MySQL 5.x)

谁能提出一个更正确的方法来解决这个问题?

非常感谢。

4

1 回答 1

1

我将应用程序设计为为每个期间类型存储一行,并为每个翻译的术语使用附加列。

INSERT INTO PERIOD (ref, desc_en, desc_de) VALUES
('HOUR', 'Hourly', 'Stündlich'),
('WEEK', 'Weekly', 'Wöchentlich'),
('MONTH', 'Monthly', 'Monatlich');

您可以获得给定语言环境的所有时期描述的列表:

SELECT desc_de FROM PERIOD;

您可以在给定的语言环境中获取给定时间段的描述:

SELECT desc_de FROM PERIOD WHERE ref = 'WEEK';

您甚至可以考虑没有完成翻译的情况:

SELECT COALESCE(desc_de, desc_en) AS desc FROM PERIOD WHERE ref = 'WEEK';

您可以从用户指定的语言环境中获取描述(注意将语言环境选择列入白名单,以避免 SQL 注入)。例如在 PHP 中:

$locales = array('en'=>1, 'de'=>1);
$locale = array_key_exists($_GET['locale'], $locales) ? $_GET['locale'] : 'en';
$sql = "SELECT desc_{$locale} FROM PERIOD WHERE ref = 'WEEK'";

PS:对于它的价值,您可以在任何版本的 MYSQL 中使用 varchar 作为主键或外键(只要您使用 InnoDB)。

CREATE TABLE FOO (id VARCHAR(10) PRIMARY KEY);
CREATE TABLE BAR (foo_id VARCHAR(10), FOREIGN KEY (foo_id) REFERENCES FOO(id));
于 2013-08-18T19:14:39.810 回答