//常用的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

微信/电话

email

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表设计_聊天系统-数据库设计相关推荐

  1. day27 MySQL 表的约束与数据库设计

    day27  MySQL 表的约束与数据库设计 第1节 回顾 1.1  数据库入门 1.1.1 SQL 语句的分类: 1) DDL 数据定义语言 2) DML 数据操作语言 3) DQL 数据查询语言 ...

  2. java MySQL表的约束与数据库设计 详解

    1.DQL 数据查询语言 在上一篇博文中,我们已经讲述了部分数据查询语句,在此我们再次对其进行补充. 1.1 排序 通过ORDAR BY 语句,可以将查询出来的结果进行排序.(排除只是一种现实的方式, ...

  3. mysql表前缀_关于数据库表前缀的认识

    mysql数据库表前缀,这个是我们区分其它表的一个方式,当我们同一个数据库中含有多个系统的的时候,表前缀就却分的唯一标识.我们使用php开源程序安装建站的时候,一般数据库表前缀都是默认设置好的,如:w ...

  4. mysql添加有效值_物理数据库设计 - 限定列的有效值

    一.说明问题 其实这篇非常简单,因为大家都是用这个方法解决的,我决定用自己的语言来描述清楚这一个问题. 假设,我们有一个列,这个列只能够取某些有效值.比如一个用户表,我们有一个姓氏列,我们需要限定里面 ...

  5. mysql常见数据库设计_常见数据库设计

    误区1:int后面的长度与存储长度无关,仅仅是显示长度. mysql手册中这个长度/值用"M"来表示的. 细心的朋友应该有注意到过mysql手册上有这么一句话:  M指示最大显示宽 ...

  6. MySQL二十八规范数据库设计

    MySQL二十八:规范数据库设计 糟糕的数据库设计: ●数据冗余,浪费空间 ●数据库插入和删除都会麻烦.异常[ 屏蔽使用物理外键] ●程序的性能差 良好的数据库设计: ●节省内存空间 ●保证数据库的完 ...

  7. java闹钟程序设计_JAVA课程设计_闹钟的设计与实现项目-报告_附源代码.doc

    JAVA课程设计_闹钟的设计与实现项目-报告_附源代码 第2章 MACROBUTTON AcceptAllChangesInDoc [双击此处键入1级标题] PAGE 2 - PAGE 1 - .. ...

  8. 管理mysql表知识点_数据库复习提纲(必考知识点整理)

    第1章 绪论 1 数据:数据是数据库中存储的基本对象. 数据库(DB):是长期存储在计算机内.有组织的.可共享的大量数据的集合. 数据库管理系统(DBMS):提供数据定义语言(DDL),用户通过它可以 ...

  9. 会签 数据库表设计_关于数据库表设计和实体类设计的思考

    后端开发最基础的工作就是CRUD 表设计常见疑惑点: 一.表字段类型和实体类型的对应关系 数据库常用字段类型为int.bigint.varchar.datetime: 实体最好以integer.Str ...

最新文章

  1. 面试官:你简历中写用过docker,能说说容器和镜像的区别吗?
  2. Python 的闭包和装饰器
  3. 五种网络管理技巧优化网络办公环境
  4. Aspnetpage ie10下 __dopost方法未找到 不能翻页的问题
  5. [css] 用css画一个太阳
  6. BZOJ 3450: Tyvj1952 Easy [DP 概率]
  7. 柿子不能和什么食物一起吃
  8. raw socket java_记一次蛋疼的Raw socket发送经历。附:Raw socket编程总结
  9. 企业级容器镜像仓库Harbor的搭建
  10. 8.Kubernetes Service(服务)
  11. aws 亚马逊_Amazon AWS Rekognition教程
  12. 《迅雷链精品课》第七课:以太坊数据存储分析
  13. jMeter性能测试之思考时间
  14. 第5章.网站首页高可用nginx+lua
  15. 使用hMailServer搭建邮件服务器(windows邮件服务器)
  16. 【LeetCode刷题】重叠区间问题
  17. 和老婆的一次真实对话
  18. 蓝桥杯 PREV-281 时间显示【第十二届】【省赛】
  19. 【西川善司的3D图形技术连载】GPU和Shader技术的基础知识(1~8回)
  20. [springboot一本通]-3.6.使用SpEL表达式绑定配置项

热门文章

  1. 每日一练 Ding持续更新中 ~
  2. uniapp 引入 uview
  3. Android Binder框架实现之bindService详解
  4. Android:Instrumentation
  5. 单点登录(SSO)的实现—通行证的基本原理
  6. Generic Netlink机制
  7. 信息安全实践三之数字签名与认证实验【申请数字证书数字签名与认证】
  8. asp.net repeater控件
  9. 关于JPEG的那点事儿:JPEG原理篇
  10. 基于MATLAB的GSE、GSS、GDD的五天运行法计算