微服务通讯系统(2)

news2024/12/26 17:29:57
  • 软件设计及核心代码展示
  • 数据库表设计,ES搜索表设计,Redis键值对设计
  1. 数据库表设计

(1)用户表设计

这里的ID是指的是在系统中用户是第几个注册的(从1开始)

user_id是指用户的唯一ID是通过uuid()函数生成的一串数字(会与第一个ID有点冗余)

Nickname是用户的昵称

Description是用户的一个简介

Password是用户的密码

Phone是用户的电话号码

avatar_id是用户的头像ID(会通过这个ID找到对应在服务端的文件头像)

这张表对对应的C++类如下

 private:

        friend class odb::access;

        #pragma db id auto

        unsigned long _id;

        #pragma db type("varchar(64)") index unique 

        std::string _user_id;

        #pragma db type("varchar(64)") index unique

        odb::nullable<std::string> _nickname; //用户昵称-不一定存在

        odb::nullable<std::string> _description; //用户签名 - 不一定存在

        #pragma db type("varchar(64)")

        odb::nullable<std::string> _password; //用户密码 - 不一定存在

        #pragma db type("varchar(64)") index unique

        odb::nullable<std::string> _phone; //用户手机号 - 不一定存在

        #pragma db type("varchar(64)")

        odb::nullable<std::string> _avatar_id; //用户头像文件ID - 不一定存在

  1. 聊天会话表

ID是指每个会话在数据库中的创建次序(从1开始)

chat_session_id是指这个会话通过uuid()函数生成的唯一字符串

chat_session_name是指会话名字

chat_session_id是指会话的类型(群聊会话还是单聊会话)

它所对应的C++类

private:

        friend class odb::access;

        #pragma db id auto

        unsigned long _id;

        #pragma db type("varchar(64)") index unique

        std::string _chat_session_id;

        #pragma db type("varchar(64)")

        std::string _chat_session_name;

        #pragma db type("tinyint")

        ChatSessionType _chat_session_type; //1-单聊; 2-群聊

  1. 聊天会话成员表

ID和前面的一样

session_id每个会话的ID,和上一张表的回话ID对应

user_id用户ID

所对应的C++类

private:

        friend class odb::access;

        #pragma db id auto

        unsigned long _id;

        #pragma db type("varchar(64)") index 

        std::string _session_id;

        #pragma db type("varchar(64)")

        std::string _user_id;

  1. 聊天消息表

message_id是消息的一个唯一ID,通过uuid()生成

Session_id是消息所属于那个的回话的ID

user_id是消息发送者的ID

message_type是指消息的类型(文字消息,图片消息,文件消息,语音消息)

create_time消息创建时间

Content信息内容(只有文字消息才有)

file_id文件ID(只有图片,文件,语音消息才有)

file_name文件名字(只有图片,文件,语音消息才有)

file_size文件大小(只有图片,文件,语音消息才有)

对应的C++类

 private:

        friend class odb::access;

        #pragma db id auto

        unsigned long _id;

        #pragma db type("varchar(64)") index unique

        std::string _message_id;

        #pragma db type("varchar(64)") index

        std::string _session_id;                //所属会话ID

        #pragma db type("varchar(64)")

        std::string _user_id;                   //发送者用户ID

        unsigned char _message_type;            //消息类型 0-文本;1-图片;2-文件;3-语音

        #pragma db type("TIMESTAMP")

        boost::posix_time::ptime _create_time;  //消息的产生时间

        odb::nullable<std::string> _content;    //文本消息内容--非文本消息可以忽略

        #pragma db type("varchar(64)")

        odb::nullable<std::string> _file_id;    //文件消息的文件ID -- 文本消息忽略

        #pragma db type("varchar(128)")

        odb::nullable<std::string> _file_name;  //文件消息的文件名称 -- 只针对文件消息有效

        odb::nullable<unsigned int> _file_size; //文件消息的文件大小 -- 只针对文件消息有效

  1. 关系表

User_id用户的ID

peer_id用户ID对应的好友的ID(表是双向存在的,有用户添加成功时,要同时添加两条数据)

private:

        friend class odb::access;

        #pragma db id auto

        unsigned long _id;

        #pragma db type("varchar(64)") index

        std::string _user_id;

        #pragma db type("varchar(64)")

        std::string _peer_id;

  1. 好友申请表

user_id发起请求的用户ID;

peer_id接收请求的用户ID

Event_id本次事件的ID(当事件被peer_id处理以后,无论是同意或者拒绝,事件都会被删除)

 private:

  friend class odb::access;

    #pragma db id auto

    unsigned long _id;

    #pragma db type("varchar(64)") index

    std::string _user_id;

    #pragma db type("varchar(64)")  index

    std::string _peer_id;

    #pragma db type("varchar(64)")  index  unique

    std::string _event_id;

  1. ES搜索表设计

因为用户主要是搜索其他用户和历史消息,所以ES搜索引擎中只存储了这两类搜索

{

  "mappings": {

    "properties": {

      "user_id": {

        "type": "keyword",

        "fields": {

          "standard": {

            "type": "text",

            "analyzer": "standard"

          }

        }

      },

      "nickname": {

        "type": "text"

      },

      "phone": {

        "type": "keyword",

        "fields": {

          "standard": {

            "type": "text",

            "analyzer": "standard"

          }

        }

      },

      "description": {

        "type": "text",

        "analyzer": "standard"

      },

      "avatar_id": {

        "type": "keyword",

        "fields": {

          "standard": {

            "type": "text",

            "analyzer": "standard"

          }

        }

      }

    }

  }

}

上面是创建user信息的ES索引json映射,内容含有和数据库里面的user表一样

{

  "mappings": {

    "properties": {

      "user_id": {

        "type": "keyword",

        "fields": {

          "standard": {

            "type": "text",

            "analyzer": "standard"

          }

        }

      },

      "message_id": {

        "type": "keyword",

        "fields": {

          "standard": {

            "type": "text",

            "analyzer": "standard"

          }

        }

      },

      "create_time": {

        "type": "long"

      },

      "chat_session_id": {

        "type": "keyword",

        "fields": {

          "standard": {

            "type": "text",

            "analyzer": "standard"

          }

        }

      },

      "content": {

        "type": "text"

      }

    }

  }

}

上面是创建message信息的ES索引json映射,内容含有和数据库里面的message表一样

  1. Redis键值对设计

这是session键值对的设计,主要记录了当一个用户登录时,系统会为他分配一个会话ID

class Session {

        public:

            using ptr = std::shared_ptr<Session>;

            Session(const std::shared_ptr<sw::redis::Redis> &redis_client):

                _redis_client(redis_client){}

            void append(const std::string &ssid, const std::string &uid) {

                _redis_client->set(ssid, uid);

            }

            void remove(const std::string &ssid) {

                _redis_client->del(ssid);

            }

            sw::redis::OptionalString uid(const std::string &ssid) {

                return _redis_client->get(ssid);

            }

        private:

            std::shared_ptr<sw::redis::Redis> _redis_client;

    };

这是状态键值对的设计,主要是和会话键值对配合使用,当用户登录时,状态键值对会将用户添加,表示用户已经登录,当其他地方有同一个用户登录时就会查询到并拒绝

class Status {

        public:

            using ptr = std::shared_ptr<Status>;

            Status(const std::shared_ptr<sw::redis::Redis> &redis_client):

                _redis_client(redis_client){}

            void append(const std::string &uid) {

                _redis_client->set(uid, "");

            }

            void remove(const std::string &uid) {

                _redis_client->del(uid);

            }

            bool exists(const std::string &uid) {

                auto res = _redis_client->get(uid);

                if (res) return true;

                return false;

            }

        private:

            std::shared_ptr<sw::redis::Redis> _redis_client;

    };

这是验证码键值对,当用户请求发送验证码时,验证码就会记录在这里一份,拿出来和用户发的验证码进行比较,一定时间后会自动删除

class Codes {

        public:

            using ptr = std::shared_ptr<Codes>;

            Codes(const std::shared_ptr<sw::redis::Redis> &redis_client):

                _redis_client(redis_client){}

            void append(const std::string &cid, const std::string &code,

                const std::chrono::milliseconds &t = std::chrono::milliseconds(300000)) {

                _redis_client->set(cid, code, t);

            }

            void remove(const std::string &cid) {

                _redis_client->del(cid);

            }

            sw::redis::OptionalString code(const std::string &cid)  {

                return _redis_client->get(cid);

            }

        private:

            std::shared_ptr<sw::redis::Redis> _redis_client;

    };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2253470.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

修复docker启动失败:Failed to start Docker Application Container Engine

配置了镜像源之后&#xff0c;运行sudo systemctl restart docker.service失败&#xff0c;提示让运行systemctl status docker.service或journalctl -xeu docker.service查看详细信息。 运行后者发现有如下日志&#xff1a; 红色区域是我设置的一个镜像源这个日志的意思就是…

神经网络入门实战:(十四)pytorch 官网内置的 CIFAR10 数据集,及其网络模型

(一) pytorch 官网内置的网络模型 图像处理&#xff1a; Models and pre-trained weights — Torchvision 0.20 documentation (二) CIFAR10数据集的分类网络模型&#xff08;仅前向传播&#xff09;&#xff1a; 下方的网络模型图片有误&#xff0c;已做修改&#xff0c;具…

微信小程序wx.showShareMenu配置全局分享功能

在app.js文件中配置如下即可&#xff1a; onLaunch() {//开启分享功能this.overShare()},/*** 开启朋友圈分享功能* 监听路由切换/自动执行*/overShare() {wx.onAppRoute((res) > {// console.log(route, res)let pages getCurrentPages()let view pages[pages.length - …

Java刷题常见的集合类,各种函数的使用以及常见的类型转化等等

前言 相信大家在刷算法题的过程中&#xff0c;好不容易想出来大概的思路&#xff0c;也知道去用哪个集合类&#xff0c;但各个集合类的一些命令都长得太像&#xff0c;很容易将他们弄错&#xff0c;并且在各集合之间的转化也是特别烦人&#xff0c;还有很多实用的函数都知道可…

用 NotePad++ 运行 Java 程序

安装包 网盘链接 下载得到的安装包: 安装步骤 双击安装包开始安装. 安装完成: 配置编码 用 NotePad 写 Java 程序时, 需要设置编码. 在 设置, 首选项, 新建 中进行设置, 可以对每一个新建的文件起作用. 之前写的文件不起作用. 在文件名处右键, 可以快速打开 CMD 窗口, 且路…

【金猿CIO展】复旦大学附属中山医院计算机网络中心副主任张俊钦:推进数据安全风险评估,防范化解数据安全风险,筑牢医疗数据安全防线...

‍ 张俊钦 本文由复旦大学附属中山医院计算机网络中心副主任张俊钦撰写并投递参与“数据猿年度金猿策划活动——2024大数据产业年度优秀CIO榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 数据要素时代&#xff0c;医疗数据已成为医院运营与决策的重要基石…

计算机视觉——相机标定(Camera Calibration)

文章目录 1. 简介2. 原理3. 相机模型3.1 四大坐标系3.2 坐标系间的转换关系3.2.1 世界坐标系到相机坐标系3.2.2 相机坐标系到图像坐标系3.2.3 像素坐标系转换为图像坐标系3.2.4 世界坐标转换为像素坐标 3.3 畸变3.3.1 畸变类型3.3.1.1 径向畸变&#xff08;Radial Distortion&a…

Go学习:编译器(编写程序时应该注意的点)

一、注意&#xff1a; LiteIDE工具&#xff1a; &#xff08;1&#xff09;创建项目后&#xff0c;同一个目录下的go文件 只能有一个 main函数&#xff0c;如果多个文件都有main函数&#xff0c;会出现编译错误。例如&#xff1a; &#xff08;2&#xff09;如果一个目录下多…

【计算机网络】实验9: 路由信息协议RIP

实验9 路由信息协议RIP 一、实验目的 本实验的主要目的是深入理解RIP&#xff08;路由信息协议&#xff09;的工作原理&#xff0c;以便掌握其在网络中的应用。通过对RIP的学习&#xff0c;我们将探讨该协议如何实现路由选择和信息传播&#xff0c;从而确保数据包能够在网络中…

如何选择适合的开源架构框架

如何选择适合的开源架构框架 一、引言二、明确项目需求 —— 筑牢基石&#xff08;一&#xff09;功能需求剖析 —— 精准锁定核心&#xff08;二&#xff09;性能要求考量 —— 追求极致卓越&#xff08;三&#xff09;可扩展性需求 —— 放眼未来蓝图 三、评估开源框架特性 —…

MongoDB-BSON 协议与类型

前言&#xff1a; MongoDB 是一个高性能、无模式的 NoSQL 数据库&#xff0c;广泛应用于大数据处理和实时数据存储。作为一个数据库系统&#xff0c;MongoDB 的核心之一就是其使用的 BSON&#xff08;Binary JSON&#xff09;格式&#xff0c;它用于存储数据以及在客户端和数据…

jmeter如何导出中文版的测试报告?

文章目录 0、初始步骤&#xff1a;把报告模板换成中文形式1、首先添加一份聚合报告2、然后点开【聚合报告】3&#xff0c;生成报告3.1 选择【工具】-【generate HTML report】3.2 【generate HTML report】参数详解3.3 、最后点击 【generate report】直接生成。 声明&#xff…

等差数列末项计算

等差数列末项计算 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给出一个等差数列的前两项a1&#xff0c;a2&#xff0c;求第n项是多少。 输入 一行&#xff0c;包含三个整数a1&#xff0c;a2&#x…

芯科科技突破性超低功耗Wi-Fi 6和低功耗蓝牙5.4模块加速设备部署

致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;今日宣布推出SiWx917Y超低功耗Wi-Fi 6和低功耗蓝牙&#xff08;Bluetooth LE&#xff09;5.4模块。 作为成功的第二代无线开发平台的新产品&…

Golang内存模型总结1(mspan、mcache、mcentral、mheap)

1.内存模型 1.1 操作系统存储模型 从上到下分别是寄存器、高速缓存、内存、磁盘&#xff0c;其中越往上速度越快&#xff0c;空间越小&#xff0c;价格越高。 关键词是多级模型和动态切换 1.2 虚拟内存与物理内存 虚拟内存是一种内存管理技术&#xff0c;允许计算机使用比…

重生之我在异世界学编程之C语言:操作符篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文1. 算术操作符2. 关系&#xff0…

深度学习图像增强介绍

目录 一、引言二、常用数据增广方法三、图像变换类3.1 AutoAugment3.2 RandAugment 四、图像裁剪类4.1 Cutout4.2 RandomErasing4.3 HideAndSeek 五、图像混叠5.1 Mixup5.2 Cutmix 六、结论 一、引言 在图像分类任务中&#xff0c;图像数据的增广是一种常用的正则化方法&#…

HBU深度学习实验14-循环神经网络(1)

前言&#xff0c;预备知识 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一类具有短期记忆能力的神经网络&#xff0e;在循环神经网络中&#xff0c;神经元不但可以接受其他神经元的信息&#xff0c;也可以接受自身的信息&#xff0c;形成具…

使用GDI对象绘制UI时需要注意的若干细节问题总结

目录 1、一个bitmap不能同时被选进两个dc中 2、CreateCompatibleDC和CreateCompatibleBitmap要使用同一个dc作为参数 3、不能删除已经被选入DC中的GDI对象 4、使用完的GDI对象&#xff0c;要将之释放掉&#xff0c;否则会导致GDI对象泄漏 5、CreateCompatibleBitmap返回错…

【Java-数据结构篇】Java 中栈和队列:构建程序逻辑的关键数据结构基石

我的个人主页 我的专栏&#xff1a;Java-数据结构&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 一、引言 1. 栈与队列在编程中的角色定位 栈和队列作为两种基本的数据结构&#xff0c;在众多编程场景中都有着独特的地位。它们为数据的有序…