在 MySql 表中存储聊天消息

Posted

技术标签:

【中文标题】在 MySql 表中存储聊天消息【英文标题】:Storing chat messages inside a MySql table 【发布时间】:2012-01-11 04:46:30 【问题描述】:

在过去的几周里,我一直在开发一个基于 Web 的聊天客户端应用程序,并且我有一个关于的问题。我创建了一个名为会话的表,现在它包含 5 个字段;

user1ID、user2ID、消息(mediumtext)、状态、时间戳

当我测试聊天应用程序时,一切正常,但问题是每次用户发送某些内容时,我都会将该值作为新行附加到我的“消息”字段中。在检索消息时,我的 sql 代码会读取整个内容并将其显示给相应的用户。因此,数据量随着添加到消息字段中的文本量而线性增加。 我的问题是,有没有办法只选择文本字段中的最后一行,或者可能是另一种可以减少传输数据量的解决方案。

【问题讨论】:

您是否将消息附加到表中唯一行中的现有字段? O_O 【参考方案1】:

您需要更好的数据库架构 - 更具关系性。这样做还会为您带来一些其他改进(密码保护聊天和多用户聊天)

这是您的数据库的 ERD。


2016 年 5 月 6 日编辑 添加具有(希望)改进的字段类型和名称的 DDL

CREATE TABLE user
(
    user_id CHAR(32),
    user_login VARCHAR(255),
    user_password CHAR(64),
    user_email VARCHAR(400),
    PRIMARY KEY (user_id)
);

CREATE TABLE message
(
    message_id CHAR(32),
    message_datetime DATETIME,
    message_text TEXT,
    message_chat_id CHAR(32),
    message_user_id CHAR(32),
    PRIMARY KEY (message_id)
);

CREATE TABLE user_chat
(
    user_chat_chat_id CHAR(32),
    user_chat_user_id CHAR(32),
    PRIMARY KEY (user_chat_chat_id,user_chat_user_id)
);

CREATE TABLE chat
(
    chat_id CHAR(32),
    chat_topic VARCHAR(32),
    chat_password CHAR(64),
    user_chat_user_id CHAR(32),
    PRIMARY KEY (chat_id)
);

CREATE INDEX user_login_idx ON user (user_login);
ALTER TABLE message ADD FOREIGN KEY message_chat_id_idxfk (message_chat_id) REFERENCES chat (chat_id);

ALTER TABLE message ADD FOREIGN KEY message_user_id_idxfk (message_user_id) REFERENCES user (user_id);

ALTER TABLE user_chat ADD FOREIGN KEY user_chat_user_id_idxfk (user_chat_user_id) REFERENCES user (user_id);

ALTER TABLE chat ADD FOREIGN KEY chat_id_idxfk (chat_id,user_chat_user_id) REFERENCES user_chat (user_chat_chat_id,user_chat_user_id);

【讨论】:

有几种不同的方法可以限制传输的数据: 1. 将数据限制在最后 x 分钟内。或者 2,仅发送自您提供给刷新脚本的最后一个日期时间以来的消息数据。 感谢您接受我的回答。如果您需要,请在此处提出更多问题。 :) @TimG 也许您已经对此聊天模式有一组查询?这将非常有用。 @DmytroMedvid - 完成。我用我希望的改进稍微更新了架构。 DDL 在 mysql 中应该可以正常工作【参考方案2】:

为什么没有这样的表结构:

聊天

聊天ID user1ID user2ID 开始日期时间 结束日期时间

聊天内容

聊天内容ID 聊天ID 留言 日期时间 状态

这样,您的数据更易于搜索和组织。例如,如果您想在 X 时间说出某条消息怎么办?或者您想获取所有带有 X 状态的聊天消息?

将数据分成 2 个表应该会更好更整洁。

【讨论】:

非常感谢。我试图使用最少数量的表和字段,这就是我这样做的原因,但这似乎不是一个好的解决方案 可能值得更新您的架构以节省您的麻烦。 实际上,如果将表格合二为一,您可以获得相同的结果。组合表将有一个 Message_id,它是 PK 和 AI,并且还将包含一个 Message_Sent_Timestamp 字段,由于您有一个 AI,您将能够知道第一条消息是何时发送的,这当然是“startedDateTime”。 “EndedDateTime”也是如此——Message_id 的最后一行将包含该日期。您需要问自己的问题是“聊天桌是否有重要意义?如果有,那么在聊天中什么重要到我需要它成为一张桌子?”【参考方案3】:

考虑在表中每行存储一条消息:

id、user1id、user2id、消息、状态、时间戳

其中 id 是一个自增列。

【讨论】:

以上是关于在 MySql 表中存储聊天消息的主要内容,如果未能解决你的问题,请参考以下文章

在 MySQL DB 中保存聊天消息,架构设计

使用 PHP 和 jQuery 进行实时聊天。在哪里存储信息? mysql还是文件?

使用stanza.io将自定义属性添加到不在服务器上的存档表中存储消息的消息

由于 openfire 连接丢失而丢失消息

在 IOS 中存储聊天消息和对话的最佳方式是啥

如何将聊天消息存储在数据库中?