消息聊天系统MySQL表设计_聊天系统-数据库设计
//常用的redis命令
CONFIG SET requirepass "mypass"
//Hashmap
hset [key] [field] value]
hget [key] [field]
hgetall [key]
//List
LPUSH [key] [value]
RPUSH [key] [value]
LPOP [key]
RPOP [key]
//删除表头2个值为value的元素
LREM [key] [count > 0] [value]
//删除表尾2个值为value的元素
LREM [key] [count < 0] [value]
//删除所有值为value的元素
LREM [key] [count = 0] [value]
LREM mylist 2 "hello"
LREM mylist -2 "hello"
//查询0~最后1个元素(不删除)
LRANGE mylist 0 -1
BRPOP [key] [timeout]
BLPOP [key] [timeout]
//例:获取message_1最左的元素,如果没有,等待5秒,超时返回nil
BLPOP message_1 5
采用Redis进行数据存储,主要包括频控、限流、用户表、在线用户表、聊天消息表(redis list实现消息队列)、好友表(TODO)
频控
CheckFrequency(userId uint64) bool
返回true检查通过,false触发频控
visited_{user_id} >3触发
//频控key前缀
const freqPre string = "visited_"
/*
Desc: 检查频控key
Input: userId
Output:
False 触发频控/异常
True 正常请求
*/
func CheckFrequency(userId uint64) bool {
key := freqPre + strconv.FormatUint(userId, 10)
resExists, err := Client.Exists(key).Result()
if err != nil {
return false
}
if resExists == 0 { //该key不存在
Client.Set(key, 0, 100 * time.Second)
return true
}
res, err := Client.Get(key).Result()
if err != nil {
return false
}
resCnt, err := strconv.Atoi(res)
if err != nil {
return false
}
if resCnt > 2 {//10秒同一userid不能访问超过2次
fmt.Println("触发频控")
//...
return false
}
Client.Incr(key)
return true
}
频控测试
redis.CreateClient()
var res bool = true
for res {
time.Sleep(time.Second * 1)
res = redis.CheckFrequency(54508)
fmt.Println(res)
}
限流
/*
令牌桶算法API
*/
const LevelFast int = 1
const LevelMedium int = 2
const LevelSlow int = 3
var tokenBucket *ratelimit.Bucket
func InitToken(speedLevel int) {
var bucketFillDuring time.Duration
if speedLevel == LevelFast {
bucketFillDuring = 20 * time.Millisecond
} else if speedLevel == LevelMedium {
bucketFillDuring = 100 * time.Millisecond
} else if speedLevel == LevelSlow {
bucketFillDuring = 1000 * time.Millisecond
} else {
//日志
fmt.Println("speedLevel只能为Fast, Medium, Slow三个值!")
return
}
var bucketMax int64 = 1//令牌桶最大容量,初始也会有这么多个令牌,此处为1是测试所用,方便看到限流效果,后期需增加大小
tokenBucket = ratelimit.NewBucket(bucketFillDuring, bucketMax)
}
/*
True:得到访问权限,通过
False:目前无令牌,拒绝
*/
func CheckToken() bool {
if tokenBucket == nil {
return false
}
//获取令牌
available := tokenBucket.TakeAvailable(1)
if available <= 0 {
//限流处理
available = tokenBucket.TakeAvailable(1)
fmt.Println("服务器开小差啦")
return false
}
return true
}
限流测试
TokenBucket.InitToken(TokenBucket.LevelFast)
for i := 0; i < 10; i++ {
fmt.Println("尝试连接服务器...")
token := TokenBucket.CheckToken()
if !token {
return
}
fmt.Println("连接成功")
time.Sleep(time.Duration(int64(rand.Int() % 40)) * time.Millisecond)//模拟用户随机访问(间隔0~40秒访问)
}
用户表 users_{user_id}
hashmap
字段
数据类型
描述
userid
Integer
用户uid
type
string
root = 管理员, normal=普通用户,vip=特权用户
username
string
用户名
password
string
密码
password_adv
string
二级密码(密码找回保留信息)
nickname
string
昵称
telephone
string
微信/电话
string
电子邮箱
age
Integer
年龄
sex
string
枚举值{boy, gril, unknown}
remark
string
备注
name->uid映射表 username_to_id_{username}
字段
数据类型
描述
userid
Integer
用户uid
在线用户表 users_online_{user_id}
离线用户key为空
数据结构:key-value
取值:
1=在线
2=离开
3=隐身(VIP功能)
聊天消息(redis list实现消息队列) chat_log_{接收者userid}_{发送者userid}
数据结构:list
字段
数据类型
描述
send_id
Integer
发送者uid
recv_id
Integer
接收者uid
send_time
string
发送时间
send_content
string
消息内容
remark
string
保留字段
好友关系表 friendship_{userid}
数据结构:hashmap
字段
数据类型
描述
userid
Integer
用户uid
friendid
Integer
好友uid
消息聊天系统MySQL表设计_聊天系统-数据库设计相关推荐
- day27 MySQL 表的约束与数据库设计
day27 MySQL 表的约束与数据库设计 第1节 回顾 1.1 数据库入门 1.1.1 SQL 语句的分类: 1) DDL 数据定义语言 2) DML 数据操作语言 3) DQL 数据查询语言 ...
- java MySQL表的约束与数据库设计 详解
1.DQL 数据查询语言 在上一篇博文中,我们已经讲述了部分数据查询语句,在此我们再次对其进行补充. 1.1 排序 通过ORDAR BY 语句,可以将查询出来的结果进行排序.(排除只是一种现实的方式, ...
- mysql表前缀_关于数据库表前缀的认识
mysql数据库表前缀,这个是我们区分其它表的一个方式,当我们同一个数据库中含有多个系统的的时候,表前缀就却分的唯一标识.我们使用php开源程序安装建站的时候,一般数据库表前缀都是默认设置好的,如:w ...
- mysql添加有效值_物理数据库设计 - 限定列的有效值
一.说明问题 其实这篇非常简单,因为大家都是用这个方法解决的,我决定用自己的语言来描述清楚这一个问题. 假设,我们有一个列,这个列只能够取某些有效值.比如一个用户表,我们有一个姓氏列,我们需要限定里面 ...
- mysql常见数据库设计_常见数据库设计
误区1:int后面的长度与存储长度无关,仅仅是显示长度. mysql手册中这个长度/值用"M"来表示的. 细心的朋友应该有注意到过mysql手册上有这么一句话: M指示最大显示宽 ...
- MySQL二十八规范数据库设计
MySQL二十八:规范数据库设计 糟糕的数据库设计: ●数据冗余,浪费空间 ●数据库插入和删除都会麻烦.异常[ 屏蔽使用物理外键] ●程序的性能差 良好的数据库设计: ●节省内存空间 ●保证数据库的完 ...
- java闹钟程序设计_JAVA课程设计_闹钟的设计与实现项目-报告_附源代码.doc
JAVA课程设计_闹钟的设计与实现项目-报告_附源代码 第2章 MACROBUTTON AcceptAllChangesInDoc [双击此处键入1级标题] PAGE 2 - PAGE 1 - .. ...
- 管理mysql表知识点_数据库复习提纲(必考知识点整理)
第1章 绪论 1 数据:数据是数据库中存储的基本对象. 数据库(DB):是长期存储在计算机内.有组织的.可共享的大量数据的集合. 数据库管理系统(DBMS):提供数据定义语言(DDL),用户通过它可以 ...
- 会签 数据库表设计_关于数据库表设计和实体类设计的思考
后端开发最基础的工作就是CRUD 表设计常见疑惑点: 一.表字段类型和实体类型的对应关系 数据库常用字段类型为int.bigint.varchar.datetime: 实体最好以integer.Str ...
最新文章
- 面试官:你简历中写用过docker,能说说容器和镜像的区别吗?
- Python 的闭包和装饰器
- 五种网络管理技巧优化网络办公环境
- Aspnetpage ie10下 __dopost方法未找到 不能翻页的问题
- [css] 用css画一个太阳
- BZOJ 3450: Tyvj1952 Easy [DP 概率]
- 柿子不能和什么食物一起吃
- raw socket java_记一次蛋疼的Raw socket发送经历。附:Raw socket编程总结
- 企业级容器镜像仓库Harbor的搭建
- 8.Kubernetes Service(服务)
- aws 亚马逊_Amazon AWS Rekognition教程
- 《迅雷链精品课》第七课:以太坊数据存储分析
- jMeter性能测试之思考时间
- 第5章.网站首页高可用nginx+lua
- 使用hMailServer搭建邮件服务器(windows邮件服务器)
- 【LeetCode刷题】重叠区间问题
- 和老婆的一次真实对话
- 蓝桥杯 PREV-281 时间显示【第十二届】【省赛】
- 【西川善司的3D图形技术连载】GPU和Shader技术的基础知识(1~8回)
- [springboot一本通]-3.6.使用SpEL表达式绑定配置项