1

現在使用しているアプリケーションにメッセージングシステムを実装しようとしています。メッセージはテーブルに保存されます。

CREATE TABLE `message` (
  `MessageID` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `Thread` BIGINT(20) NOT NULL,
  `From` BIGINT(20) NOT NULL,
  `To` BIGINT(20) NOT NULL,
  `DateTime` DATETIME NOT NULL DEFAULT '2012-01-01 00:00:00',
  `Content` TEXT NOT NULL,
  PRIMARY KEY (`MessageID`),
  CONSTRAINT `FK_messageTo` FOREIGN KEY (`To`) REFERENCES `team` (`TeamID`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `FK_messageFrom` FOREIGN KEY (`From`) REFERENCES `team` (`TeamID`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `FK_thread` FOREIGN KEY (`Thread`) REFERENCES `thread` (`ThreadID`) ON DELETE CASCADE ON UPDATE CASCADE
);

スレッドは、会話スレッド、基本的にはユーザーのペアを格納する別のテーブルです。

ユーザーが誰かとの会話を表示するときは、最新のメッセージ、たとえば10件のメッセージのみを表示する必要があります。より多くのメッセージがオンデマンドで表示されます(ボタンのクリックなど)。この場合、データベースをプールする最も効率的な方法がわかりません。

  • 毎回糸全体を取り出して切り落とすと、明らかにポイントが崩れます。

  • 次の行に沿ってクエリを実行します。

    SELECT *
      FROM message
     WHERE (to = {party1} AND `from` = {party2})
        OR (to = {party2} AND `from` = {party1})
     ORDER BY messageID DESC
     LIMIT {start}, {length}
    

ここで、{name}のような式は変数です。ここでLIMITがどのように機能するか、最初の方法よりも高速になるかどうかはわかりません。

  • 3番目のオプションは、スレッド内でインクリメントされる別のフィールド(インデックス)を追加することです(メッセージテーブルの主キーは、システムのどこかに新しいメッセージが追加されるたびにインクリメントされるため)。
4

2 に答える 2

4

ここで、あなたの要件を見た後に私の頭に浮かぶ 1 つの提案は次のとおりです。一度に 10 の会話を表示する必要があり、ユーザーがもっと見たい場合は、次の 10 の会話を見るためのボタンが提供されるとしましょう。

したがって、最初に最初の 10 件の会話を選択し、最後の会話の ID 番号をフロント エンド アプリケーションの変数に格納することができます。

SELECT *
  FROM message
 WHERE (to = {party1} AND from = {party2})
    OR (to = {party2} AND from = {party1})
   AND messageid BETWEEN 1 AND 10
 ORDER BY messageID 

ユーザーがボタンをクリックして次の 10 件の会話を表示すると、SQL エンジンに rang lastid+10 でクエリが再度送信されます。あれは:

SELECT *
  FROM message
 WHERE (to = {party1} AND from = {party2})
    OR (to = {party2} AND from = {party1})
   AND messageid BETWEEN 11 AND 20
 ORDER BY messageID 

また、テーブルに適切なインデックスがあることを確認してください。

于 2012-08-02T08:38:10.047 に答える
2

AnandPhadkeの答えに同意します。コメントするには複雑すぎるもの:

LIMIT結果の数を制限するために使用できる有用な ID を持っていないデータに使用されるハックです。たとえば、検索クエリを作成するとき、多くのテーブルを結合しますが、通常の場合、結果の数を制限するために使用できるものは何もありません。

多くのデータベースでサポートされています (すべてではありません。Oracle は最も注目すべき例外の 1 つです)。通常、パフォーマンスは「十分に良好」です。つまり、パフォーマンスが悪い場合はどうしますか? それを行う他の方法はありません。

しかし、データ モデルを変更して、リミッタとして使用できる適切な ID を与えることができれば、常に を使用するよりも優れていLIMITます。

欠点は、2 つのクエリを実行する必要があることです。まず、MAX(ID)(最新のメッセージを最初に表示する必要があるため) が必要です。そうして初めて、実際のクエリを実行できます。または、副選択を使用できます。この観点から、LIMIT「よりきれい」です。

于 2012-08-02T09:01:26.123 に答える