MySQL: чтение из правой таблицы или по умолчанию - PullRequest
0 голосов
/ 25 января 2012

Я использую таблицу для сохранения некоторых текстовых данных с такой структурой:

CREATE TABLE IF NOT EXISTS `strings_en` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(80) COLLATE utf8_unicode_ci NOT NULL,
  `content` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;

В этой таблице хранятся все английские "строки" (на самом деле это текст, который иногда длиннее 4 КБ). Когда мне нужна строка, я вызываю mySQL так:

SELECT `content` FROM `strings_en` WHERE `id`='42'

Теперь я "интернационализировал" свое приложение, поэтому я добавил другие таблицы, называемые "strings_es" или "strings_de", в которых используются испанский и голландский языки. Каждый идентификатор всегда соответствует одной и той же строке на разных языках.

В PHP у меня есть переменная $ language , которая содержит текущий выбранный язык: 'es' для испанского, 'en' для английского и т. Д. Я получаю строку с этим запросом:

SELECT `content` FROM `strings_$language` WHERE `id`='$string'

Проблема в том, что иногда нет перевода для данного идентификатора (этот идентификатор не существует в таблице). Например, в испанском языке не существует id = 10 (strings_es), но он существует на английском языке (strings_en). Я использую * strings_en * как по умолчанию , поэтому, когда строка не существует на текущем языке, я ищу на английском. Теперь я делаю это через условное выражение PHP:

$result = query("SELECT `content` FROM `strings_$language` WHERE `id`='$string'");
if (empty($result)) {
    $result = query("SELECT `content` FROM `strings_en` WHERE `id`='$string'");
}

Я хотел бы знать, как сделать это только в одном запросе MySQL.

Ответы [ 3 ]

1 голос
/ 25 января 2012
SELECT ISNULL(l.`content`, e.`content`) AS `content`
FROM `strings_en` AS e
LEFT OUTER JOIN `strings_$language` AS l ON l.`id` = e.`id`
WHERE e.`id` = `$string`
1 голос
/ 25 января 2012

Вы должны использовать язык внутри вашей таблицы строк и сделать его частью уникального ключа (id + language). Таким образом, вам не придется добавлять новые таблицы, когда вы используете все больше и больше языков.

Например:

CREATE TABLE IF NOT EXISTS `strings` (
  `string_id` int(11) NOT NULL AUTO_INCREMENT,
  `id` int(11) NOT NULL ,
  `language` char(2) NOT NULL DEFAULT 'en',
  `title` varchar(80) COLLATE utf8_unicode_ci NOT NULL,
  `content` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`string_id`) ,
  `i_id_lang`  UNIQUE INDEX (id,language)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;

А с

( SELECT * FROM strings WHERE id=? AND language=? UNION 
  SELECT * FROM strings WHERE id=? AND language='en' ) LIMIT 1

вы получите строку для идентификатора на данном языке или языке по умолчанию.

Редактировать: я добавил столбец string_id в качестве уникального идентификатора.

1 голос
/ 25 января 2012
SELECT COALESCE(other, en)
FROM (
    SELECT (SELECT `content` FROM `strings_$language` WHERE id = `$string`) as other,
    (SELECT `content` FROM `strings_en` WHERE id = `$string`) as en
) a
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...