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
);

Thread 是另一个存储对话线程的表,基本上是成对的用户。

当用户查看他们与 somone 的对话时,他们应该只显示最近的消息,例如 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 在这里是如何工作的,是否会比我的第一种方法更快。

  • 第三种选择是添加另一个在线程内递增的字段(索引)(因为每当在系统中的任何位置添加新消息时,消息表中的主键都会递增)。
4

2 回答 2

4

在看到您的要求后,我想到的一个建议是:假设您必须一次显示 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是一种 hack,用于处理您没有可用于限制结果数量的有用 ID 的数据。例如,当您构建搜索查询时,您连接了许多表,在通常情况下,您将无法使用任何东西来限制结果的数量。

许多数据库都支持它(不是全部,Oracle 是最显着的例外之一)。表现通常是“足够好”的意思:表现不好的时候你会怎么做?没有其他方法可以做到这一点。

但是,如果您可以更改数据模型并为其提供可以用作限制器的适当 ID,那总是比使用LIMIT.

缺点是您需要执行两个查询:首先,您需要MAX(ID)(因为您希望首先显示最新消息)。只有这样,您才能运行真正的查询。或者您可以使用子选择。从这个角度来说,LIMIT是“更干净”的。

于 2012-08-02T09:01:26.123 回答