初学Redis(3)——用Redis作为Mysql数据库的缓存

把Mysql结果集缓存到Redis的字符串或哈希结构中以后,我们面临一个新的问题,即如何为这些字符串或哈希命名,也就是如何确定它们的键。因为这些数据结构所对应的行都属于某个结果集,假如可以找到一种唯一标识结果集的方法,那么只需为这些数据结构分配一个唯一的序号,然后把结果集标识符与该序号结合起来,就能唯一标识一个数据结构了。于是,为字符串和哈希命名的问题就转化为确定结果集标识符的问题。

经过调研,发现一种较为通用的确定结果集标识符的方法。正如我们所知道的,缓存在Redis中的结果集数据都是利用select等sql语句从Mysql中获取的。同样的查询语句会生成同样的结果集(这里暂时不讨论结果集中每条记录的顺序问题),这一性质刚好可以用来确定结果集的唯一标识符。当然,简单地把整个sql语句作为结果集标识符是不可取的,一个显而易见的理由是,未经处理的sql查询语句均包含若干空格,而Redis的键是不允许存在空格的。这时,我们需要一个可以把sql语句转换为唯一标识符的函数。通常,这一功能由散列函数完成,包括MD5,SHA系列等加密散列函数在内的很多算法均可达到这一目的。

确定结果集标识符之后,从Redis读数据或向Redis写数据的思路就很清晰了。对于一个sql语句格式的数据请求,首先计算该语句的MD5并据此得到结果集标识符,然后利用该标识符在Redis中查找该结果集。注意,结果集中的每一行都有一个相应的键,这些键都存储在一个Redis集合结构中。这个集合恰好对应了所需的结果集,所以,该集合的键必须包含结果集标识符。如果Redis中不存在这样一个集合,说明要找的结果集不在Redis中,所以需要执行相应的sql语句,在Mysql中查询到相应的结果集,然后按照上面所说的办法把结果集中的每一行以字符串或哈希的形式存入Redis。在Redis中查找相应结果集的代码如下:

// 该函数根据sql语句在Redis中查询相应的结果集,并返回结果集中每一行所对应的数据结构的键
vector<string> GetCache(sql::Connection *mysql_connection,
                      redisContext *redis_connection,
                      const string &sql, int ttl, int type) {
  vector<string> redis_row_key_vector;
  string resultset_id = md5(sql);  // 计算sql语句的md5,这是唯一标识结果集的关键
  // type==1时,该函数将查询相应的STRING集合或将结果集写入若干STRING
  string cache_type = (type == 1) ? "string" : "hash";
  // 根据type信息和结果集标识符合成SET键
  string redis_row_set_key = "resultset." + cache_type + ":" + resultset_id;
  redisReply *reply;
  // 尝试从reply中获取SET中保存的所有键
  reply = static_cast<redisReply*>(redisCommand(redis_connection,
                                               "SMEMBERS %s",
                                               redis_row_set_key.c_str()));
  if (reply->type == REDIS_REPLY_ARRAY) {
	// 如果要找的SET不存在,说明Redis中没有相应的结果集,需要调用Cache2String或
	// Cache2Hash函数把数据从Mysql拉取到Redis中
    if (reply->elements == 0) {
      freeReplyObject(reply);
      sql::Statement *stmt = mysql_connection->createStatement();
      sql::ResultSet *resultset = stmt->executeQuery(sql);
      if (type == 1) {
        redis_row_set_key = Cache2String(mysql_connection, redis_connection,
                                         resultset, resultset_id, ttl);
      } else {
        redis_row_set_key = Cache2Hash(mysql_connection, redis_connection,
                                       resultset, resultset_id, ttl);
      }
	  // 再次尝试从reply中获取SET中保存的所有键
      reply = static_cast<redisReply*>(redisCommand(redis_connection,
                                                   "SMEMBERS %s",
                                                   redis_row_set_key.c_str()));
      delete resultset;
      delete stmt;
    }
	// 把SET中的每个STRING或HASH键存入redis_row_key_vector中
    string redis_row_key;
    for (int i = 0; i < reply->elements; ++i) {
      redis_row_key = reply->element[i]->str;
      redis_row_key_vector.push_back(redis_row_key);
    }
    freeReplyObject(reply);
  } else {
    freeReplyObject(reply);
    throw runtime_error("FAILURE - SMEMBERS error");
  }
  return redis_row_key_vector;
}

现在我们已经掌握了确定Redis中的结果集标识符以及各数据结构的键的方法。下一篇文章将研究结果集在Redis中的排序和分页问题。

时间: 2024-10-24 21:34:20

初学Redis(3)——用Redis作为Mysql数据库的缓存的相关文章

初学Redis(2)——用Redis作为Mysql数据库的缓存

用Redis作Mysql数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自Mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按表存储的:更微观地看,这些表都是按行存储的.每执行一次select查询,Mysql都会返回一个结果集,这个结果集由若干行组成.所以,一个自然而然的想法就是在Redis中找到一种对应于Mysql行的数据结构.Redis中提供了五种基本数据结构,即字符串(string).列表(list).哈希(has

用Redis作为Mysql数据库的缓存【转】

用Redis作Mysql数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自Mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按表存储的:更微观地看,这些表都是按行存储的.每执行一次select查询,Mysql都会返回一个结果集,这个结果集由若干行组成.所以,一个自然而然的想法就是在Redis中找到一种对应于Mysql行的数据结构.Redis中提供了五种基本数据结构,即字符串(string).列表(list).哈希(has

用Redis作为Mysql数据库的缓存

看到一篇不错的博文,记录下: http://blog.csdn.net/qtyl1988/article/details/39553339 http://blog.csdn.net/qtyl1988/article/details/39519951 http://blog.csdn.net/qtyl1988/article/details/39524713 http://blog.csdn.net/qtyl1988/article/details/39545531 该文是采用C++写的,PHP的

转载:使用canal让redis中的数据与mysql数据库中的保持同步

转载:http://blog.csdn.net/tb3039450/article/details/53928351?locationNum=7&fps=1

mysql 数据库的基本操作1

mysql数据库管理 day01相关概念问题数据库介绍? 存储数据的仓库 数据库服务都那些公司在使用? 购物网站 游戏网站 金融网站 数据服务存储的是什么数据?帐号信息 对应的数据信息 提供数据库服务的软件有那些?开源软件 mysql . mongodb . redis 商业软件 oracle . db2 . SQL SERVER 软件是否跨平台? Linux Unix Windows 软件包的来源: 官网下载 使用操作系统安装光盘自带软件包 mysql软件介绍? mysql mariadb关系

mysql 数据库的主从复制及备份、恢复

##远程登录MySql mysql -h62.234.124.229 -P31306 -ucrab -p123456 mysql --host=62.234.124.229 --user=yq --password=123456 ##给远程登录的用户授权: grant all on *.* to [email protected]'114.248.166.196' identified by '123456'; grant select,update,delete on *.* to [emai

MySQL 数据库中MyISAM 和 InnoDB 的区别

首先要明白,在MySQL数据库忠中的存储引擎是基于表的,而不是基于数据库的. 讲述两者区别: InnoDB 存储引擎,主要面向 OLTP(Online Transaction Processing,在线事务处理)方面的应用,是第一个完整支持 ACID 事务的存储引擎(BDB 第一个支持事务的存储引擎,已经停止开发). 特点: 行锁设计.支持外键: 支持类似于 Oracle 风格的一致性非锁定读(默认情况下读取操作不会产生锁): InnoDB 将数据放在一个逻辑的表空间中,由 InnoDB 自身进

MySQL数据库的查询缓冲机制

MySQL数据库的查询缓冲机制 2011-08-10 11:07 佚名 火魔网 字号:T | T 使用查询缓冲机制,可以极大地提高MySQL数据库查询的效率,节省查询所用的时间.那么查询缓冲机制是怎样设置的呢?本文我们就来介绍这部分内容,希望能够对您有所帮助. AD: MySQL数据库提供了查询缓冲机制.使用该查询缓冲机 制,MySQL将SELECT语句和查询结果存放在缓冲区中,以后对于同样的SELECT语句(区分大小写),将直接从缓冲区中读取结果.以节省查询时 间,提高了SQL查询的效率.本文

用Redis作Mysql数据库缓存

使用redis作mysql数据库缓存时,需要考虑两个问题: 1.确定用何种数据结构存储来自Mysql的数据; 2.在确定数据结构之后,用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按表存储的;更微观地看,这些表都是按行存储的.每执行一次select查询,Mysql都会返回一个结果集,这个结果集由若干行组成.所以,一个自然而然的想法就是在Redis中找到一种对应于Mysql行的数据结构.Redis中提供了五种基本数据结构,即字符串(string).列表(list).哈希(hash