2012-01-25 5 views
0

私はこのような構造で、いくつかのテキストデータを保存するためのテーブルを使用しています:のMySQL:右の表から読むか、デフォルト

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; 

このテーブルはすべて英語「の文字列を」続けるには(本当にこれはテキストは時には4kbより長くなります)。私は、文字列を必要とするとき、私はこのようにMySQLを呼び出す:

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

を今、私は「strings_es」やスペイン語、オランダ語の言語が使用されている「strings_de」と呼ばれる私のアプリケーションので、私が追加した他のテーブルを「国際化」しています。それぞれのidは、同じ言語の文字列に常に一致します。 PHPで

私は、現在選択されている言語が含まれ$言語変数がありますなど、「en」と英語、スペイン語のための「ESを」私はこのクエリを使用して文字列を取得:

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

問題は、特定のID(このIDはテーブルに存在しない)の翻訳がないことがあります。たとえば、スペイン語では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'"); 
} 

私はただ1つのMySQLクエリでこれを行う方法を知りたいと思います。

答えて

1

あなたは、文字列テーブル内の言語を使用して、それ固有のキー(ID +言語)の一部にする必要があります。このようにして、より多くの言語を使用するときに新しいテーブルを追加する必要がなくなります。例えば

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 

で指定した言語でIDやデフォルト言語の文字列を取得します。

編集:ユニークIDとして機能するようにstring_id列を追加しました。

+0

がわかります。ここで問題となるのは、 'id'はプライマリなので、IDを持つ新しい行を追加することはできません。プライマリキーを削除することはできません。なぜなら、IDが重複しているとエラーを受け取ることを期待する他の(外部の)モジュールがあるからです。継承されたコードに関するよくある問題:( – Ivan

+0

@Ivan 'string_id'カラムを追加してstringsテーブルのユニークキーとして機能させ、' id'カラムを必要に応じて使用できるようになりました。 – dgw

1
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 
+0

戻り値:#1064 - SQL構文に誤りがあります。あなたのMySQLサーバのバージョンに対応するマニュアルをチェックし、右側の構文が5行目の 'a'の近くにあることを確認してください。 – Ivan

+0

@Ivan私の更新バージョン – RedFilter

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