数据库:redis 设计 - 用户信息、聊天记录

文章目录

1. 方案设计

使用 redis列表 存储两个用户之间的聊天数据

  • 存储 内容使用json字符串封装,字段包括:fromId、toId、msg、time

使用 redis hash 存储一个用户未读的消息条数

  • 存在问题:原子性问题 ??

2. 需求分析

2.1 连接数据库

Connect();

2.2 断开数据库

disConnect();

2.3 向 redis 输入命令

// _context:连接到数据库的对象
// redisCommand:hiredis 库函数,用于向数据库输入命令
setCommand(const string & data){
	...
	redisCommand(_context, data.c_str());
	...
}

2.4 用户信息:存储格式

  • 实现:reids 哈希表

2.5 注册:添加用户信息

addUserInfo(){
	// 如果不存在,则创建
	if( !HEXISTS(userInfo,wujie) )
		hset(userInfo,wujie,123)
	else
		error
}

2.6 登陆:获取用户信息

searchUserInfo{
	hget(userInfo,wujie);
}

2.7 注销:删除用户信息

delUserInfo()
	hdel(userInfo,wujie)
}

2.8 聊天记录:存储格式

  • 实现方式:链表
  • 链表名:双方名字(eg: “wujie-chenshuai”),方便缩小遍历范围(只要找到表名就可以一次遍历出与该人的聊天记录)
  • 内容:json 字符串(方便解析,无需再手写封装、解析字符串函数)
	{ 
		"time":"2018.01.25",
		"fromId":"wujie",
		"toId":"chenshuai",
		"msg":"zaima?"
	}

2.9 聊天记录:保存

addChatRecord(int num){
		setCommand("multi"); // 开启事务

		// 向事务中添加要执行的命令	
		for(int i = 0;i < num,i++)
		{
			ret = RPUSH("wujie-chenshuai","{"time":"2018.01.25","fromId":"wujie","toId":"chenshuai","msg":"zaima?"}");
			assert(ret == QUEUED) // 输入命令可能有错误
		}
		
		ret = setCommand("exec");  // 执行事务
		assert(ret == "OK") // 可能出现运行异常
	}

2.10 聊天记录:获取

getChatRecord(int num){
	LRANGE("wujie-chenshuai",0,num);
}

3. python 代码实例 – 参考

import json
import time
import redis

pool = redis.ConnectionPool(host=‘xxxx‘,port=6379, decode_responses=True)
conn = redis.Redis(connection_pool=pool)

""" function : fromid 用户给 toid 用户发送 msg 消息 Parameters: fromid: int类型,发送消息的用户id toid: int类型,接收消息的用户id msg:str类型,消息内容 return: bool类型,消息是否发送成功 """
def msgsend(fromid,toid,msg):
    try:
        timesocre = time.time()	// 时间
        // 封装聊天记录
        dict = { "fromid":fromid,"toid":toid,"msg" :msg,"time":timesocre} 
        // 键名 - 双方名字
        key = keyname(fromid, toid)
        // 查看对方是否在线
        aliveflag = checkuseralive(toid)
        // 不在线 - 设置为未读消息数
        if not aliveflag:
            setwithoutnum(toid, key)
		// 保存到 以双方名字 命名的列表
        conn.lpush(key, json.dumps(dict))
        return True
    except:
        return False
        
""" function: toid 用户读取 fromid 用户发送过来的 msg Parameters: fromid: int类型,发送消息的用户id toid: int类型,接收消息的用户id return: list,int( 消息列表 与 toid用户未读取fromid用户发送过来的消息条数) """
def msgread(fromid,toid):
    key = keyname(fromid,toid)
    msglen = conn.llen(key)	// 查看双方聊天记录
    msglist = conn.lrange(key,0,msglen) // 获取所有聊天记录
    withoutmsgnum = returnwithoutnum(toid,key) // 获取未读消息数
    return msglist,withoutmsgnum
    
""" function : 检查 userid 用户是否在线 Parameters: userid: int类型,消息的用户id return: bool类型,在线为True,不在线为 False """
def checkuseralive(userid):
    # 检查用户在线,预留
    return True

""" function: 设置 userid用户与另一个用户未读取消息的条数 Parameters: userid: int类型,哈希表 名字 key:str类型 用户名 return: bool类型,在线为True,不在线为False """
def setwithoutnum(userid,key):
	// 如果用户在线
    if  conn.hexists(str(userid), key):
    	// 获取当前用户消息数
        msgnum = conn.hget(str(userid), key)
        // 当前用户未读消息数 + 1
        conn.hset(str(userid), key, int(msgnum)+1)
    else:
    	// 不存在,则新建哈希对
        conn.hset(str(userid), key, 1)
        
""" function: 返回 userid用户 与 另一个用户的未读消息条数 Parameters: userid: int类型,哈希表名 key:str类型,用户名 return: 未读消息条数 """
def returnwithoutnum(userid,key):
	// 若果有未读消息
    if  conn.hexists(str(userid), key):
    	// 获取(读出) 未读消息数
        msgnum = conn.hget(str(userid), key)
        // 清空未读消息数
        conn.hset(str(userid), key,0)
        return int(msgnum)
    return 0


""" function: 根据 两个id 唯一生成 一个key(做表名,标识是双方的聊天记录) Parameters: fromid: int toid: int return: str """
def keyname(fromid,toid):
	// eg: 不管 fromId = wujie & chengshuai 最终都生成 "chengshuai-wujie" 这个表名
    key = (str(fromid)+"-"+str(toid) if (fromid > toid) else str(toid)+"-"+str(fromid))
    return key

user1 = 23
user2 = 43
user3 = 212
user4 = 65

#用户1给用户2发送"你好"
msgsend(user1,user2,"你好")

#用户2读取用户1发送的消息
#第一个返回值返回全部聊天记录,第二个参数返回未读消息数量
msglist,withoutmsgnum = msgread(user1,user2)
print(msglist,withoutmsgnum)

#读取一条内容示例
print(json.loads(msglist[0]))
print(json.loads(msglist[1]))
print(json.loads(msglist[2]))
    原文作者:内核
    原文地址: https://blog.csdn.net/qq_41418343/article/details/113922553
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞