最近、卒業制作にredisを追加したい場合、MySQLのデータをredisに転送する必要があります。ここで、リレーショナル データベースから非リレーショナル データベースにデータを転送するにはどうすればよいかという疑問が生じます。その後、Baidu MySQL のデータを redis に移行したのですが、予想通り各ブログは高い統一性を保っており、数少ないブログを見ると、ほぼすべてが転載で、オリジナルのものはほとんどありませんでした。もちろん、私は初心者であり、成功するまで長い間手探りでした。
Baidu に合格した学生なら events_all_time テーブルに精通しているでしょう (笑)。これ以上言いたくないのですが、原文は大丈夫です、大丈夫というわけではありませんが、考え方は大丈夫、文法も大丈夫ですが、実際に操作するとエラーが報告され、そのエラーの理由は知らない。Stack Overflow で見たソリューションでは redisprotocol を使用していません。初心者の私にとって、記事中に説明が足りない箇所があります。ちょっと大変な気がするし、なぜこのように書かれているのか理解できません。次に、私の記事では、最初に redis プロトコルについて説明し、次に mysql を redis コマンドに変換する方法について説明し、最後に mysql 内の複数のデータの形式とそれらを redis に保存する方法について説明します。(こちらは何回転送されたか分からないevent_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)
);
文章
Baidu の mysql から redis を移行する方法、理解できない学生は、公式 Web サイトhttps://redis.io/topics/mass-insertの説明と組み合わせて、食べた方が良いです。
redis の通常クライアントで大量のデータを挿入するのは良くないので、redis プロトコルに準拠したテキストファイルを生成し、それを redis で一律に呼び出す方法が公式推奨されています。テキストファイルには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つあります
$3-->次のSETには3バイトがあります
$4-->次の key1 は 4 バイトです
$6--> 後ろの値には 6 バイトがあります1
とてもシンプルですね^_^!!!!!!
次に、何度も転送されている events_to_redis.sql を確認します。Redis プロトコルを理解した後、このコードを見れば一目瞭然です。作成者の意図は、データベースでクエリされた値を対応するコマンドに接続することです。
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'パスワード' 'データベース' --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 プロトコル エラー: '$' が予期されましたが、' ' を取得しました
具体的な原因は分かりませんが、解決した方がいらっしゃいましたらコメントして初心者の私にも勉強させて頂ければ幸いです。
解決
私の最終的な解決策は、実際には、これまでの理解に基づいて SQL ステートメントを変更し、mysql の最終出力形式が通常の SET キー値形式になるようにしてから実行することです。
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 プロトコルまたは redis コマンドである限り、このタスクは redis-cli に渡すことで完了できます。
Redis に保存された MySQL の複数のデータ
次に、mysql内の複数のデータに対して、redisのhmsetコマンドを使用します。
HMSET キー フィールド値 [フィールド値 ..]
キーはテーブル名+idとなっており、クエリ時に1つのデータテーブルに対応するデータを簡単な処理で取得できます。hmset テーブル名+ID カラム名値 カラム名値...
実はHSETを使うことも可能で、テーブル名+idをキーとして、データをStringで格納することができ、簡単な処理でデータを取得することもできます。