0

次のSQLテーブル(たとえばMySQL)があるとします。

CREATE TABLE `table` (
  `id` int(11) unsigned NOT NULL,
  `lang` tinyint(3) unsigned NOT NULL,
  `data` text NOT NULL,
  PRIMARY KEY (`id`,`lang`)
) ENGINE=InnoDB

idこのテーブルには、IDを持つオブジェクトに関するいくつかのデータが格納dataされており、複数の言語で記述できます= lang。このテーブルの一般的な使用例は次のとおりです。あるIDを持つオブジェクトのデータを取得する必要があり、言語がlang =1または少なくともlang =5であるか、 id =1に対してlang =1または5の行がない場合は他の言語見つかった。

言い換えれば、英語または少なくともドイツ語でid = 1のオブジェクトに関する情報を取得したいのですが、そうでない場合は、他の言語で十分です。

これはかなり単純なクエリです。

SELECT * FROM `table` WHERE `id` = 1
ORDER BY
  CASE WHEN `lang` = 1 THEN 1
       WHEN `lang` = 2 THEN 2
       ELSE 3
  END ASC
LIMIT 1

このクエリは非常に高速で、メモリ内の並べ替えでPRIMARYキーのみを使用します。

1つのクエリで複数のオブジェクトのそのようなデータを取得したい場合に質問が表示されます。私が考えることができる唯一のものは次のようなものです:

SELECT id, (SUBQUERY TO GET DATA AS ABOVE WHERE id = tmp.id LIMIT 1) AS data
FROM (SUBQUERY TO SELECT ids) as tmp

そのクエリはその仕事をしますが、見た目も感じも醜いです:/

そして、これは最初の質問です: そのようなことをするための良いそして正しい方法はありますか?誰かがそのような問題を解決するためのより良い方法を知っていますか?

次に、高負荷で非常に大きなデータテーブルについて考えてみましょう。たとえば、それぞれに5〜15の言語を持つ1,000,000のオブジェクトを与えたと仮定します。これはMySQLにとって非常に大きなテーブルなので、1つのテーブルをさらにいくつかに分割します(たとえば、複数のサーバーに20のテーブルを分割します)。これで、特定のオブジェクトのデータが格納されている場所を知るための簡単なハッシュ関数(id%N == 0など)ができました。

したがって、質問#2:*データがどこにあるかがすでにわかっている場合、複数のテーブル(1つのデータベースでもtable_1からtable_5まで)でこのような要求を行う方法は?*この質問には最初の質問の後でのみ答えることができると思います:(

このトピックに関する他のいくつかの質問:おそらく全体の状況は間違っていますか?そのようなデータを別の方法で保存する必要がありますか?それとも、それを行うための他のより効率的な方法がいくつかありますか?

4

1 に答える 1

1

あなたが提案する

SELECT id, (SUBQUERY TO GET DATA AS ABOVE WHERE id = tmp.id LIMIT 1) AS data
FROM (SUBQUERY TO SELECT ids) as tmp

小さな変更ですが、希望する各行に最適な言語を示す結果セットに参加する方が確かに少し良いでしょう。

SELECT
    `table`.`id`,
    `table`.`lang`,
    `table`.`data`
FROM
    `table`
    JOIN (
        SELECT
            `id`,
            MAX(`evaluatelanguage`(`lang`)) AS `bestscore`
        FROM
            `table` AS `sqtable`
        GROUP BY
            `id`
    ) AS `subquery` ON
        `table`.`id` = `subquery`.`id` AND
        `evaluatelanguage`(`table`.`lang`) = `subquery`.`bestscore`

NB。このバージョンでは、すべての言語に個別のランクを付ける必要があります。そうしないと、IDがのELSE句に該当する複数の行が表示されるためCASEです。このクエリは改善できると思いますが(確かにevaluatelanguage何度も使用する必要はありませんか?)、どうすればよいかわかりません。

于 2011-07-06T14:24:26.040 に答える