news 2026/7/22 13:59:28

《Redis与MySQL在即时通讯聊天室中的应用与设计》

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《Redis与MySQL在即时通讯聊天室中的应用与设计》

目录

内容简介:

详细内容:

1:数据库的引入

2: MySQL基础及在聊天室中的应用

2.1 MySQL基础

1 建库,建表,增删查改

2 数据表的约束

3 数据表数据的插入,更新,删除

4 数据表查询

1 select基础查询

2 WHERE条件查询

3 ORDER BY排序

4 LIMIT

2.2 聊天室中数据表的设计

3: Redis基础及在聊天室中的应用

1 Redis基本概念

2 聊天室中Redis常用数据结构:

1 String

2 Hash

3 List

4 Set

4: C++程序和数据库之间的通信

5: 总结


内容简介:

1. 聊天室为什么需要数据库

2. MySQL基础和聊天室中的使用

3. Redis基础和聊天室中的使用

4. C++程序和数据库之间的通信

5. 总结

详细内容:

1:数据库的引入

能不能不用任何数据库?

把用户信息、在线状态存在服务器内存里,就像:

打开手机备忘录,只打字不保存,一旦闪退、关机,所有内容全部消失.

即:断电即清空、重启数据全丢

如果聊天室不用数据库,会出现:

服务器一旦重启,所有注册的用户账号、好友关系、聊天记录全部清零,用户每次打开软件都要重新注册,无法正常使用。

因此,需要数据库.

进一步的,我们会发现,聊天室的数据有完全不同的特点,可分成两类:

第一类:需要永久保存、很少变动的数据。比如账号密码、个人资料、好友关系、群组信息、历史聊天记录。这些数据哪怕服务器重启、电脑关机,也必须完好保留。

第二类:实时变动、不用永久保存、访问极频繁的数据。比如用户在线状态、临时验证码、用户离线消息。有人上线、下线,在线状态一秒变动好几次;用户登录后验证码就失效,这些数据不需要长期存,但是需要秒级快速查询

这就引出:单一数据库虽然可以实现所有功能,但是不同数据对存储性能和访问速度的要求不同,因此聊天室通常采用MySQL和Redis结合的方案。

永久稳定的数据交给MySQL,高速实时的数据交给Redis,两者搭配,撑起一个完整、流畅的聊天室系统。

我给大家整理了一张场景对照表,方便大家直观理解:

数据类型

数据特点

适配数据库

用户账号、密码、资料

长期保存、稳定不变

MySQL

好友、群组关系、历史消息

结构化、需留存、关系复杂

MySQL

用户在线状态

高频变动、实时查询

Redis

离线消息、临时验证码

短期有效、快速读写

Redis

2: MySQL基础及在聊天室中的应用

在聊天室中,我们要学,如何设计表、如何存取数据、如何保证数据关系合理

安装教程:MYSQL安装教程

2.1 MySQL基础

1 建库,建表,增删查改
mysql -u root -p (登录)

show databases;


create databaseStu;默认的编码方式 latin1 (单字节编码)(建库)

->

create databaseStucharacter set utf8;设置成 utf-8中文能正常显示

/

alterdatabase Stucharsetutf8;修改


use Stu;


select database();



show tables;


create table `信息`( (建表)

`姓名` varchar(20),

`年龄` int

);


show create table `信息`;


alter table `信息` add(/drop/modify) `性别` char(10);

2 数据表的约束

引入:

为防止 重复用户名、用户没有密码、好友表里出现一个不存在的用户 ID、年龄填负数这类错误数据 被插入到数据表,MySQL中定义了一些维护数据库完整性的规则;这些规则常称为表的约束。

聊天室常用约束如下:

约束条件说明
PRIMARY KEY主键约束用于唯一标识对应的记录
FOREIGN KEY外键约束
NOT NULL非空约束
UNIQUE唯一性约束

在聊天室的应用:

比如,用户表

CREATE TABLE user(
id INTPRIMARY KEYAUTO_INCREMENT,
username VARCHAR(50)UNIQUENOT NULL,
password VARCHAR(100)NOT NULL
);

PRIMARY KEY:保证id不会重复

UNIQUE:保证同一个人不可以重复注册

3 数据表数据的插入,更新,删除

以聊天室user表为例:

1准备一张表

CREATE TABLE user( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(100) NOT NULL, nickname VARCHAR(50), create_time DATETIME );
字段作用聊天室用途
id用户唯一编号好友关系、消息记录中引用
username账号名登录、注册
password密码登录验证
nickname昵称显示给好友
create_time注册时间记录用户信息

2插入数据

INSERT INTO user(username,password,nickname,create_time) VALUES( 'jack', '123456', 'Jack', NOW() );

执行后:

idusernamepasswordnicknamecreate_time
1jack123456Jack2026-07-21 20:00:00

注意:

这里没有插入id

因为:

id INT PRIMARY KEY AUTO_INCREMENT

表示:

id由MySQL自动生成

3更新数据

UPDATE user SET password='888888' WHERE username='jack'; //jack修改密码修改密码:123456->888888

执行后:

idusernamepassword
1jack888888

4删除数据

DELETE FROM user WHERE username='jack'; //注销账号

执行前:

idusernamepasswordnickname
1jack123456Jack
2tomabcdefTom

执行后:

idusernamepasswordnickname
2tomabcdefTom

但是,在实际聊天室中,用户注销通常采用逻辑删除,即修改状态字段从1到0,而不是直接删除数据,避免影响好友关系和历史消息

补充:

TRUNCATE和DETELE的区别
TRUNCATE和DETELE都能实现删除表中的所有数据的功能,但两者也是有区别的:
1、DELETE语句后可跟WHERE子句,可通过指定WHERE子句中的条件表达式只删除满足条件的部分记录;但是,TRUNCATE语句只能用于删除表中的所有记录。
2、使用TRUNCATE语句删除表中的数据后,再次向表中添加记录时自动增加字段的默认初始值重新由1开始;使用DELETE语句删除表中所有记录后,再次向表中添加记录时自动增加字段的值为删除时该字段的最大值加1
3、DELETE语句是DML语句,TRUNCATE语句通常被认为是DDL语句

4 数据表查询

目标:服务器收到客户端请求后,通过SQL查询数据库,找到需要的数据,然后返回给客户端

1 select基础查询

1> *查询所有字段

SELECT *

FROM 表名;

2> 查询指定字段

SELECT 字段1,字段2

FROM 表名;

->eg:

SELECT username,password
FROM user;

2 WHERE条件查询

SELECT 字段
FROM 表
WHERE 条件;

->

用户Jack登录时

客户端:username=jack

服务器查询:

SELECT password
FROM user
WHEREusername='jack';

数据库返回:

123456

服务器比较密码

还可以查询好友(WHERE user_id=1)和聊天记录(WHERE sender=1ANDreceiver=2)

聊天室常用多条件查询,例如:

查询好友:

SELECT * FROM friend WHERE user_id=1 AND friend_id=2;

聊天室中的查询大部分都是带条件查询,而不是简单查询全部数据。

3 ORDER BY排序

可用于查询历史消息

查询:

SELECT *
FROM message
ORDER BYtime;

结果:

10:01
10:02
10:03

4 LIMIT

SELECT *
FROM message
ORDER BYtime DESC(DESC最新消息放最上面,ASC最早消息放最上面)
LIMIT20;

假设:

聊天记录100万条,用户打开聊天窗口,不可能一次加载100万条.只取最近20条消息

2.2 聊天室中数据表的设计

目的:以用户表,好友关系表,消息表,群成员表为例,熟悉MYSQL在聊天室中的用法和约束

约束条件说明
PRIMARY KEY主键约束用于唯一标识对应的记录
FOREIGN KEY外键约束
NOT NULL非空约束
UNIQUE唯一性约束

故可设计为:

1. 用户表 user

作用:

保存用户基本信息,用于:

  • 注册
  • 登录
  • 查询用户资料

表结构:

字段类型约束说明
idINTPRIMARY KEY用户唯一编号
usernameVARCHAR(50)UNIQUE、NOT NULL用户名
passwordVARCHAR(100)NOT NULL密码
nicknameVARCHAR(50)昵称
create_timeDATETIME注册时间
CREATE TABLE user( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(100) NOT NULL, nickname VARCHAR(50), create_time DATETIME );
2. 好友关系表 friend

作用:

保存用户之间的好友关系

表结构:

字段类型说明
idINT关系编号
user_idINT用户id
friend_idINT好友id
create_timeDATETIME建立好友时间
CREATE TABLE friend( id INT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, friend_id INT NOT NULL, create_time DATETIME );
3. 消息表 message

作用:

保存聊天历史记录

用于:

  • 查看聊天记录
  • 离线消息补偿
  • 消息查询

表结构:

字段类型说明
idINT消息编号
sender_idINT发送者id
receiver_idINT接收者id
contentTEXT消息内容
send_timeDATETIME发送时间
CREATE TABLE message( id INT PRIMARY KEY AUTO_INCREMENT, sender_id INT NOT NULL, receiver_id INT NOT NULL, content TEXT, send_time DATETIME );

查询Jack和Tom聊天记录:

SELECT * FROM message WHERE (sender_id=1 AND receiver_id=2) OR (sender_id=2 AND receiver_id=1) ORDER BY send_time;
4. 群成员表 group_member

作用:

保存群组和用户之间的关系。

例如:

群1001 成员: jack tom lucy

表结构:

字段类型说明
idINT编号
group_idINT群id
user_idINT用户id
roleINT成员身份
CREATE TABLE group_member( id INT PRIMARY KEY AUTO_INCREMENT, group_id INT NOT NULL, user_id INT NOT NULL, role INT DEFAULT 0 );

3: Redis基础及在聊天室中的应用

1 Redis基本概念

Redis采用:

key-value键值对方式存储数据

类似C++:

​ unordered_map<string,string> ​-> map["username"]="jack";
2 聊天室中Redis常用数据结构:
类型特点聊天室应用
String字符串验证码、在线状态
Hash对象存储用户信息
List列表离线消息
Set集合好友列表
1 String

1>基础

创建数据:SETusername jack

查询:GETusername jack

删除:DELusername jack

2>聊天室中应用

保存验证码

SETEX verify:jack 300 123456 //jack的验证码是123456,300s后过期,自动删除
2 Hash

1>基础

HSETuser:jack username jack

HGETuser:jack password

HGETALLuser:jack

HEXISTSuser:tom

2>聊天室中应用

保存用户基本信息

// user:10001 // username jack // password 123456 // email xxx HSET user:10001 username jack HSET user:10001 password 123456 HSET user:10001 email xxx
3 List

类似:C++队列 queue<string>

List类似双端队列,可以实现消息队列功能

1>基础

添加:

LPUSHoffline:jack hello (从左加)-永远先看到最新消息-朋友圈

RPUSHoffline:jack hi (从右加)-新的消息在后-聊天室离线消息

删除:

LPOPoffline:jack (从offline:jack的List里面,删除并取出最左边的一条消息)

注:聊天室常用RPUSH+LPOP->先入先出

查看:
LRANGEoffline:jack 0 -1 (list range,查看list中的一段数据)
这里表示获取jack离线信息中,从第一个元素到最后一个元素

2>聊天室中应用

保存离线消息

​ //B离线 //A给B发送 hi~ 服务器: RPUSH offline:B "A:hi~" //接着,C给B发送 你在干嘛? 服务器: RPUSH offline:B "C:你在干嘛?" //B上线后,服务器: LRANGE offline:B 0 -1 //发送给客户端,B看到: A:hi~ C:你在干嘛? ​
4 Set

相当于C++中unordered_set

特点:无序,不重复

在聊天室中,根据好友列表,判断私聊是否合法

(好友列表不是直接存储的,而是由好友关系表动态查询得到。MySQL保存用户之间的关系,服务器根据用户id查询friend表,生成好友列表返回给客户端)

添加:SADDfriend:jack tom

查看:

SISMEMBERSfriend:jack tom

-set is member,查看是不是成员,即判断是否存在.返回1是好友

SMEMBERSfriend:jack

-set members,获取整个集合

删除:

SREM(set remove,删除集合中的元素)
eg:tom和jack删除好友时,需要:
SREM friends:tom jack
SREM friends:jack tom

4: C++程序和数据库之间的通信

现在,从数据库知识进入项目实现

聊天室的C++服务器代码,怎么把一个C++变量传递给MySQL/Redis,让数据库真正保存数据?

核心逻辑:

C++聊天室程序 → 发送SQL → MySQL仓库

装上驱动库,C++ 就拥有了发送 SQL 的能力

伪代码模拟流程:(示例为了展示流程使用字符串拼接,实际项目使用预处理语句)

// 1.程序启动,和MySQL建立连接 连接MySQL("127.0.0.1","root","123456","chatroom"); // 2.收到客户端注册信息 string name = "jack"; string pwd = "123456"; // 3.拼凑SQL指令纸条 string sql = "INSERT INTO user(username,password) VALUES('"+name+"','"+pwd+"');"; // 4.发送纸条给MySQL 发送SQL(sql); // 5.接收MySQL的回信 if(执行成功){ 通知客户端:注册成功 }else{ 通知客户端:注册失败 }

即:

MySQL 是独立运行的程序,相当于一个仓库。C++ 程序本身不能直接操作数据库。

C++ 需要借助驱动库,把业务数据拼装成我们熟悉的 SQL 字符串,把这条 SQL 发送给 MySQL 服务。

MySQL 识别 SQL 语句,完成增删改查,同时利用主键、唯一约束等规则校验数据是否合法,最后把执行结果回传给 C++ 服务端

与之相似,C++通过Redis客户端库(redis-plus-plus/hiredis)发送Redis命令

以<MySQL为例,体会:

代码:C++程序接收用户名和密码,然后保存到MySQL的user表中

1>mysql准备:

mysql -u root -p


CREATE DATABASE test_chat;


USE test_chat;


create table user( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL, password VARCHAR(50) NOT NULL );

2>c++程序:

文件:

mysql_test.cpp

代码:

#include <bits/stdc++.h> #include <string> #include <mysql/mysql.h> using namespace std; int main(){ // 1.初始化mysql句柄 MYSQL* mysql = mysql_init(nullptr); if (mysql == nullptr){ cout << "mysql init error" << endl; return -1; } // 2.建立连接 地址,用户名,密码,数据库名,端口 if (!mysql_real_connect(mysql, "127.0.0.1", "root", "0527985", "test_chat", 3306, nullptr, 0)){ cout << "connect mysql error:" << mysql_error(mysql) << endl; mysql_close(mysql); return -1; } cout << "mysql connect success" << endl; // 3.接收用户输入(模拟聊天室客户端注册) string username; string password; cout << "请输入用户名:"; cin >> username; cout << "请输入密码:"; cin >> password; // 4.拼接插入SQL(简易演示,正式项目要用预处理防止注入) string sql = "INSERT INTO user(username,password) VALUES('" + username + "','" + password + "');"; // 5.执行SQL int ret = mysql_query(mysql, sql.c_str()); if (ret != 0) cout << "执行SQL失败:" << mysql_error(mysql) << endl; else cout << "注册数据写入数据库成功!" << endl; // 关闭连接 mysql_close(mysql); return 0; }

3>编译运行:

g++ mysql_test.cpp \
-o mysql_test \
-lmysqlclient


./mysql_test

4>结果:

输入:

mysql connect success

请输入用户名:
jack

请输入密码:
123456

查看数据库:

SELECT * FROM user;

5: 总结

ChatServer

|

------------------

| |

MySQL Redis

长期数据 实时数据

用户信息 在线状态

好友关系 离线消息

历史记录 验证码

MySQL负责聊天室中需要长期保存的数据,Redis负责聊天室中高频访问、实时变化的数据,两者结合实现高性能即时通讯系统。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/22 13:59:19

Navicat Premium 17 安装教程破解超详细

Premium 17、Navicat是用于MySQL的管理工具 1. 是否已经安装好Navicat Premium 工具。&#xff08;重要&#xff01;&#xff01;&#xff01;&#xff09; 1、已经安装的需要在控制面板>卸载程序 找到 Navicat Premium 右键点击卸载&#xff0c;如果未安装直接跳过这一步&…

作者头像 李华
网站建设 2026/7/22 13:57:04

AI视频生成技术解析:从工程实现到艺术表达的完整工作流

如果你是一名开发者&#xff0c;最近在关注AI视频生成技术&#xff0c;可能会发现一个有趣的现象&#xff1a;很多技术讨论都集中在工具使用和参数调整上&#xff0c;却很少深入分析一个完整作品从技术实现到艺术表达的全过程。今天我们要聊的《探子必须死》这部电影&#xff0…

作者头像 李华
网站建设 2026/7/22 13:56:30

深入解析TMS320DM6441:异构SoC系统架构与电源管理实战

1. 项目概述与核心价值在嵌入式系统&#xff0c;尤其是视频处理、工业视觉这类对实时性和能效比要求极高的领域&#xff0c;一颗芯片的“内功”往往决定了整个产品的成败。这颗“内功”的核心&#xff0c;就是其系统架构与电源管理设计。很多工程师拿到一款新的SoC&#xff08;…

作者头像 李华
网站建设 2026/7/22 13:56:27

限时开放|2024Q3唯一通过CNKI白名单认证的AI查重辅助插件,仅剩87个高校授权名额(附实名验证通道)

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;AI搜索 论文查重辅助 AI搜索技术正深度融入学术研究流程&#xff0c;尤其在论文查重环节展现出显著的智能化优势。传统查重工具依赖静态文本比对&#xff0c;而新一代AI搜索系统通过语义理解、跨语言嵌入与上…

作者头像 李华
网站建设 2026/7/22 13:54:47

我在焦圈儿死磕了一个月,最后算账把自己吓了一跳

说出来你可能不信&#xff0c;我上个月写公众号赚了6186元。而我的成本&#xff0c;只有67.9元。不是标题党&#xff0c;是真的。容我从头讲起。一切从"顺手签个到"开始几个月前&#xff0c;朋友在群里甩了个焦圈儿的邀请链接。说是福利升级了&#xff0c;签到奖励翻…

作者头像 李华