Mysql数据转移Redis

       最近毕业设计上想加上一个redis,就必须要把MySQL里面的数据转移到redis当中。那么问题来了,关系型数据库的数据怎么转移到非关系型数据库中呢?然后百度MySQL数据迁移redis,然后果不其然,各个博客保持了高度统一,看那么几篇博客,几乎都是转载的,有原创的也很少。当然我也只是个小白,摸索了很久才成功了。

       如果百度过了的同学对events_all_time这个表很熟悉吧,哈哈。我也不多说了,原文写的没问题,也不是说没问题,是思路没问题,语法也没问题,但是实际操作后会报错,这个报错原因也不知道为啥。我在Stack Overflow上面看到的解决方法不是用的redisprotocol。对于我这个小白来说,文章里面有的地方没有解释。看起来有点费劲,搞不明白为啥这么写。然后我这篇就是先解释下redisprotocol,再说下mysql转redis命令的方法,最后说下mysql里面多条数据以什么格式,怎么存到redis。(这里附一下那个不知道被转了多少遍的events_all_time  2333)

CREATE TABLE events_all_time (
  id int(11) unsigned NOT NULL AUTO_INCREMENT,
  action varchar(255) NOT NULL,
  count int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (id),
  UNIQUE KEY uniq_action (action)
);

       正文

       百度上的mysql迁移redis的方法,看不懂的同学,结合官网的解释https://redis.io/topics/mass-insert,食用更佳哦。

       用redis普通的客户端插入大量数据并不好,所以官方推荐的方法是生成一个符合redis协议的text文件,用redis统一去调用。text文件可以写redis命令,也可以写redis协议。协议格式如下

*<args><cr><lf>
$<len><cr><lf>
<arg0><cr><lf>
<arg1><cr><lf>
...
<argN><cr><lf>

        <cr>对应的  '\r'  (ASCII码13),<lf>对应的  '\n' (ASCII码10)。然后那个*和$符号的意义就是。*号后面加数字,表示整个命令总共有多少个参数,包括命令本身。$后面加数字,表示对应的参数,有多少字节。

       举个栗子    SET  key1 value1

转化为redis的协议就是   *3\r\n$3\r\nSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n

*3-->有set,key1,value1三个

$3-->后面SET有三个字节

$4-->后面key1有4个字节

$6-->后面value1有6个字节

是不是很简单^_^!!!!!

然后看看那个不知道被转了多少遍的events_to_redis.sql。明白了redis protocol之后再看这个代码,一目了然。作者的意图就是把数据库里面查询出的值,拼接成相应的命令。

SELECT CONCAT(
  "*4\r\n",
  '$', LENGTH(redis_cmd), '\r\n',
  redis_cmd, '\r\n',
  '$', LENGTH(redis_key), '\r\n',
  redis_key, '\r\n',
  '$', LENGTH(hkey), '\r\n',
  hkey, '\r\n',
  '$', LENGTH(hval), '\r\n',
  hval, '\r'
)
FROM (
  SELECT
  'HSET' as redis_cmd,
  'events_all_time' AS redis_key,
  action AS hkey,
  count AS hval
  FROM events_all_time
) AS t

最终用

mysql  -h  'ip地址'  -u'用户名'  -p'密码'  'database'  --skip-column-names  --raw < events_to_redis.sql | redis-cli --pipe

这条命令意思就是 mysql登录后,用‘database’这个数据库, --skip-column-names(使mysql输出不包含列名)  --raw(使mysql不转换字段值中的换行符),然后就是运行events_to_redis.sql,用管道传入redis-cli当中运行即可。

这里有一个问题,就是按照 *3\r\n$3\r\nSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n这样的方式是不行的。总是报错 

ERR Protocol error: expected '$', got ' '

具体原因我并不太清楚,如果有同学解决了,希望可以评论说一下,让我这个小白也学习一下。

解决方案

我最后的解决方案其实就是在前面了解了的基础上,把sql语句修改了,让mysql最终输出的格式是普通的 SET  key  value的格式,然后运行即可。

SELECT 
  CONCAT(
    redis_cmd,' ',
    redis_key,
    idval,' ',
    ACTION,' ',
    actionval,' ',
    COUNT,' ',
    countval,' '
  ) 
FROM
  (SELECT 
    'HSET' AS redis_cmd,
    'events_all_time' AS redis_key,
    id AS idval,
    'action' AS ACTION,
    ACTION AS actionval,
    'count' AS COUNT,
    COUNT AS countval
  FROM
    events_all_time) AS t

总而言之,不管你用的是mysql,java,python,C/C++,甚至是记事本。只要输出的格式是redis protocol或redis命令,传入redis-cli当中就可以完成这个任务。

mysql多条数据存入redis

然后对于mysql 的多条数据,我使用的是redis的hmset命令。

HMSET key  field  value  [field  value ..]

key就是表名称+id,这样查询的时候进行简单处理即可得到对应数据表一条的数据。hmset  表名+id  列名  值  列名 值 ...

其实用HSET也是可以的,key就是表名称+id,然后一条数据,可以用String存上,同样简单处理也可得到数据。

猜你喜欢

转载自blog.csdn.net/qq_36571422/article/details/105383186