私信功能

2023-11-01

最近在做一个私信的功能

一张message表:存储消息内容和创建者id;一张user_message表:存储发送者、接收者及消息id

本以为考虑还算周全,今天又查看了一些文章,发现还是差的远。 下面是从OSChina转来的一篇文章,比我设计的要高明得多。

转自:http://www.oschina.net/question/12_70252


OSChina 的留言表 osc_msgs ,表结构如下:

字段说明:

id : 留言主键字段,自增长
user : 留言的主人
friend : 对方的ID
sender : 留言发送者
receiver : 留言接收者
type : 留言类型(普通消息、系统消息)
content : 留言内容
send_time : 发送时间
read_time : 阅读时间
status : 留言状态

其中 user 和 friend 稍显特殊,其他的字段意义已非常明确不再说明。

当 A 给 B 发送一条留言时,会往 osc_msgs 表中插入两条相同的记录,唯一不同的是 user 和 friend 这两个字段的值是对调的,当然 id 因为是自增长的所以也不同。

为什么要这么做?

1. 一条留言保存两条记录:因为每个人都有收到的留言和已发送留言,当发送人删除了已发送留言,不会影响到接收人查看收到的留言

2. user/friend/sender/receiver 这四个字段是不是多余?

关键的问题就在于此,你还记得 osc 的留言箱吗?进入留言箱里显示的是你最近的留言往来,包含你接收到的和你发出的,它们是按照时间进行排序的。

假设只有 sender/receiver 这两个字段,那么要将接收和发送的留言放在一起,就必须用 UNION 来合并两个查询结果,然后再做排序,而且你还必须有个字段来标注到底是接收到的留言还是发出的留言。这样的 SQL 可能会是这样:

?
1
2
3
4
5
SELECT * FROM (
     SELECT * FROM osc_msgs WHERE type=<接收> AND receiver=<我>
     UNION
     SELECT * FROM osc_msgs WHERE type=<发送> AND sender=<我>
) t ORDER BY send_time DESC

这样的 SQL 语句不用执行都知道性能很差。

那么以冗余来换性能的思路,我们对这个表进行了小改造。

增加两个字段 user 和 friend,当 A 发送留言给 B 时,会写入两条记录:

记录1. user=A,friend=B,sender=A,receiver=B
记录2. user=B,friend=A,sender=A,receiver=B

再来看看在新的表结构下,我们如何改写上面的语句:

?
1
SELECT * FROM osc_msgs WHERE user = <我> ORDER BY id DESC

这两个 SQL 语句孰优孰劣,相信大家能比较得出来。

如果是要列出我跟每个人的最后一条留言的话(就好象留言箱首页显示的内容)可以这样写 SQL 语句:

?
1
SELECT MAX (id) AS id, COUNT (id) AS msgCount FROM osc_msgs WHERE user = ? GROUP BY friend ORDER BY id DESC

解释完毕。

本文只是提供一种表结构设计的参考思路,这也不是放之四海而皆准的方法,关键的问题在于你想解决什么样的问题,对 OSC 来说性能很重要,如果能简单的通过冗余来提升性能,这很划算。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

私信功能 的相关文章

  • Linux centos 卸载 ceph

    在CentOS上卸载Ceph的操作步骤 1 停止Ceph集群 首先 你需要停止Ceph集群中的所有服务 在每个节点上运行以下命令来停止所有服务 systemctl stop ceph target 2 卸载Ceph软件包 在每个节点上 使用
  • 在1-100中随机生成10个数字并进行排序

    1 生成10以内的数字 可以参考rand 10 2 生成1 10之间的数字 可以参考rand 10 1 3 特定的 要生成a b之间的数字 可以参考rand b a 1 a include
  • CSharp: QuestPDF create pdf file in donet core 6

  • UE4 分屏显示

    比较简单 直接附上蓝图 注意 启动模式选择独立游戏进程启动这样能够在两个屏幕上满屏显示 在UE4 版本上可以实现 不清楚在UE5上实现不了在两个屏幕上满屏显示 有疑惑或者想法这欢迎沟通交流 还要注意设置项目里面的屏幕设置 下面附上简单的分屏
  • js如何实现数组去重的常用方法

    聚沙成塔 每天进步一点点 专栏简介 使用 Set ES6 使用 filter 和 indexOf 使用 reduce 使用对象属性 使用 includes 方法 ES6 写在最后 专栏简介 前端入门之旅 探索Web开发的奇妙世界 记得点击上
  • 有人知道乐高机器人和乐高少儿编程区别吗

    乐高机器人和乐高少儿编程区别 现在很多的家长对于孩子的学习可以说是非常的用心 就拿现在很多的家长在给孩子选择少儿编程的学习课程的时候 可以说是非常的用心 就想要给孩子选择一个对于孩子有好处的课程 但是很多的家长对于乐高机器人和少儿编程的了解
  • 老猿学5G:融合计费的Nchf和Nchf‘服务化接口消息Nchf_ConvergedCharging_Create、Update、Release和Notify

    老猿Python博文目录 一 引言 在 老猿学5G扫盲贴 中国移动的5G计费架构解读 介绍了5G融合计费的服务化接口包括 CHF提供给CTF使用的Nchf接口 OCF提供给CHF使用的Nchf 接口 这两个接口消息的内容都相同 只是服务端和
  • 安卓端自行实现工信部要求的隐私合规检测一(教你手写Xposed模块代码)

    前言 原文地址 安卓端自行实现工信部要求的隐私合规检测一 教你手写Xposed模块代码 转载者言 只是简单监控隐私权限可以使用Android 11的新特性AppOpsManager OnOpNotedCallback 参考下面文章 隐私合规
  • Maven中GeoTools的引入 - Maven 的 repository 与 mirror

    Maven中GeoTools的引入 Maven 的 repository 与 mirror 在Maven中引入GeoTools时找不到jar包 搜索了蛮久才明白是自己maven没有学明白 于是重学了一次maven 解决了这个问题 关键在于理
  • python-共现矩阵(共词矩阵)计算

    共现矩阵 共词矩阵 统计文本中两两词组之间共同出现的次数 以此来描述词组间的亲密度 code 我这里求的对角线元素为该字段在文本中出现的总次数 import pandas as pd def gx matrix vol li 整合一下 输入
  • knife4j介绍及使用

    Knife4jInsight是一款致力于基于OpenAPI2及OpenAPI3规范进行聚合的独立中间件 在Knife4j 4 0版本发布之际 作者也对该组件进行了了架构重新设计 代码重构 并也发布了该独立中间件的2 0版本 基于Spring
  • windows使用makefile的三种方法

    windows使用makefile的三种方法 想再在windows上尝试makefile的可以试一试 注意需要下载好mingw 配置好gcc路径 才能成功使用make 第1种方法只需要命令行 2 3种方法需要借助vscode实现 当用户编译
  • Rokoko for Maya

    Rokoko for Maya 动捕应用 一 什么是Rokoko 二 使用 Rokoko Stufio 暂时没打算记录如何操作 Maya插件 rokoko studio live 下载安装 如何使用 三 其他 一 什么是Rokoko Rok
  • Raspberry Pi 与Arduino SPI通信

    本教程介绍了使用SPI 串行外围设备接口总线 进行Raspberry Pi与Arduino通讯和控制的基本框架 SPI代表了一种非常完善的芯片间通信方法 该方法在两种设备的硬件中均实现 在这里 我们将详细探讨SPI 讨论硬件和软件注意事项
  • 波次

    播种式分拣是以汇总了多份订单的一个批次为单位进行分拣作业的 业内通常将这个作业的批次称为 波次 为了达到较高的工作效率 播种式分拣一般希望每个波次汇总较多的订单 但由于以下原因 每个波次汇总的订单绝不是越多越好 1完成订单的时间限制 通常情
  • JavaMail邮件发送不成功的那些坑人情况及分析说明

    前言 JavaMail的使用本身并不难 网上有不少案例 简单易懂 而且有详细的中文注解 但是由于JavaMail的机制设置不够完善 特别是异常出错时的参考信息太少 给初学者造成了不少麻烦 而我就是其中之一 在此 把我遇到过得那些坑总结出来
  • 图解人工智能知识架构(从知识角度告诉你人工智能到底学些啥)

    很多人都想学习人工智能 但是却不知道该学些啥 从宏观的视角搞清楚人工智能到底需要学习哪些领域的知识是至关重要的 这就好比要去逛一座大的商场 非常需要一份商场的楼层导览图 它能够告诉你各个楼层商户的分布 又好比去一个风景区游玩 非常需要一份景
  • VS2022安装easyx图形库教程

    下载easyx图形库 下载地址 EasyX Graphics Library for C 下载好后安装 点击安装 安装 前两项 easyx会自动识别VS版本 我们点击安装 安装好以后重启VS 测试一下 安装easyx推行库成功 问题 那么e
  • 5分钟带你快速了解微服务框架的前世今生

    目录 原始时代 青铜时代 黄金时代 铂金时代 钻石时代 星耀时代 王者时代 总结 原始时代 1969年11月 为了便于高校间共享资源 美国国防部高级研究计划管理局建立一个名为阿帕网络ARPAnet 起初只有四个节点 阿帕网起源 一年后阿帕网
  • 编程是一种“组合的艺术”

    编程是一种 组合的艺术 WPF实例分析 金旭亮 有这么一句名言 政治是一种妥协的艺术 这一规律同样适用于软件技术 就我个人的观点 软件开发在一定意义上是一种 组合的艺术 优秀的软件工程师类似于优秀的厨师 能将一些常见的原料变成一盘色香味俱全

随机推荐

  • git常用命令合集(建议收藏)

    1 git init将本文件夹初始化成一个本地git仓库 2 git clone xxx 将github上的远程克隆到本地 3 git add file1 file2 添加文件到暂存区 包括修改的文件 新增的文件 4 git add dir
  • 技术人修炼之道阅读笔记(四)低效的7个行为习惯

    技术人修炼之道阅读笔记 四 低效的7个行为习惯 如今 在许多企业为了提高团队的产出 996 非常盛行 但是效果却往往不令人满意 那么怎么来提高团队的工作效率呢 这里我们进行逆向思维 从造成低效的7个坏习惯说起 因为避免了低效的行为习惯 离高
  • 无限脉冲响应 (IIR) 滤波器

    1 基础知识 某正弦信号 频率为50Hz 这意味着 信号的模拟频率 f 50 Hz 注意它的单位是Hz 信号的表达式为 注意 模拟滤波器设计中用的频率是指模拟角频率 数字滤波器设计中用的频率是指归一化数字角频率 w 2 数字滤波器简介 数字
  • 程序员应对35岁中年危机的措施

    都说程序员是吃青春饭 我也问了一些身边周围的朋友 有已经在工作的 有正在出于中年危机的 有猎头公司工作的 觉得年龄问题对于程序员是一个致命的问题 正处在25左右的我们 应该如何应对10年后的中年危机呢 李开复给程序员的7建议 我觉得很对 特
  • 第二章正则表达式

    第二章 正则表达式 1 学习目标 掌握正则表达式的作用 掌握正则表达式的语法 了解常见的正则表达式 2 内容讲解 2 1 正则表达式的概念 正则表达式是对字符串操作的一种逻辑公式 就是用事先定义好的一些特定字符 及这些特定字符的组合 组成一
  • c中malloc申请堆空间使用及案例

    c中malloc申请堆空间 void test22 int pr pr int malloc sizeof int 128 申请128个int4字节空间 if pr NULL 判断是否申请成功 return memset pr 0 size
  • elasticsearch字符串包含查询

    query string 在查询的时候经常会遇到查询字符串是否包含的某个特定字符传的查询 可以使用query string实现 GET pv search query query string default field name quer
  • NodeJS-进程管理pm2/forever/nodemon/supervisor/ts-node-dev

    无论在开发阶段还是在上线阶段 对进程的管理是大大解决时间和成本的 pm2 node js server tools 1 安装 全局安装 yarn global add pm2 OR npm install pm2 g 局部安装 yarn a
  • springcloud报错:com.netflix.discovery.shared.transport.TransportException

    1 完整报错信息 com netflix discovery shared transport TransportException Cannot execute request on any known server 2 问题分析 1 服
  • 图片风格快速转换的简单web实现

    图片风格快速转换的简单web实现 图片风格转换 是指利用深度学习算法学习某种风格图片的特征 将其应用到另一张图片中 合成新风格的图片 目前技术较为成熟 github上有很多有趣的项目与应用 本项目核心代码基于fast neural styl
  • NCC常用操作自助工具

    selftool 介绍 NChome操作自助工具 对常用操作进行了集成 类图 工具使用 功能介绍 初始化配置 点击按钮可对nchome进行关联 重启服务 点击按钮一键重启服务 sysConfig 点击按钮一键打开home配置界面 clear
  • 云计算技术与应用赛项竞赛试题(样卷)

    选手须知 1 竞赛试题通过在线 云计算技术与应用 竞赛考试系统和书面文档共同发布 内容完全一致 如出现纸质任务书缺页 字迹不清 与考试系统中不一致等问题 请及时向裁判示意 并进行任务书的更换 2 参赛团队应在4小时内完成任务书规定内容 选手
  • 尝试实现带有迭代器的 vector

    两个注意点 1 底层内存分配采用 new 和 delete 非 stl 书中所示 2 移动元素为集体后移 并非原书中拆解后移 原书移动方式原因未知 include
  • docker部署多个mysql容器,并使用java连接

    测试springboot多个数据源配置时 需要安装多个mysql容器 由于资源限制 当前只有一台虚拟机 如果在一台机器上安装多个mysql实例 是可以的 但步骤比较繁琐 使用docker来安装MySQL容器 非常简单 只需要简单几步 对于测
  • vue创建WebSocket进行实时通讯

    vue WebSocket创建实现实时通讯 websocket async initWebSocket if websock return if const chatid return if typeof WebSocket undefin
  • C++标准库头文件(工具库->typeinfo)

    参考网址 https zh cppreference com w cpp header https blog csdn net w55100 article details 80330812 工具库 typeinfo 运行时类型信息工具 类
  • 3. Unity之三维模型

    1 网格 Mesh 三维物体模型在unity中一般称为mesh 即网格数据 模型一般使用专用的建模软件设计 将mesh文件导入到unity中进行使用 一般mesh中保存的是三维模型的面和顶点数据 在unity中通过下图方法进行调整 其中 S
  • JUC 十三. CountDownLatch 与 CyclicBarrier 与 Semaphore 基础使用与底层原理

    目录 一 CountDownLatch 减少计数器 二 CyclicBarrier 循环栅栏 三 Semaphore 信号灯 四 CountDownLatch 底层实现 await 判断state 也可以简单理解为计数 如果为0获取锁成功
  • css背景 背景颜色 颜色渐变

    背景全屏 body background image url imgs bj png background repeat no repeat background size 100 100 background attachment fix
  • 私信功能

    最近在做一个私信的功能 一张message表 存储消息内容和创建者id 一张user message表 存储发送者 接收者及消息id 本以为考虑还算周全 今天又查看了一些文章 发现还是差的远 下面是从OSChina转来的一篇文章 比我设计的