這裡來演示下REDIS和MYSQL之間的資料轉換問題,REDIS 是典型的KEY -VALUE型NOSQL資料庫,並且提供了額外豐富的資料型別。這裡簡單列舉了標籤型別的應用問題。

比如在MySQL裡面,對內容的標籤有以下簡單的幾張表,我這裡只列出來拆分過後的表結構

第一,MySQL部分,

內容表:

CREATE TABLE `content` (
  `id` int(10) unsigned NOT NULL, -- 內容ID,唯一。
  `name` varchar(60) DEFAULT NULL, -- 內容的名字
  `created_timestamp` timestamp NULL DEFAULT NULL, -- 內容的加入時間
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

標籤表:

CREATE TABLE `tag` (
  `tag_name` varchar(60) NOT NULL, -- 標籤名字,唯一
  `visit_count` int(10) unsigned NOT NULL DEFAULT `0`, -- 標籤的訪問次數
  PRIMARY KEY (`tag_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

內容與標籤的關係,多對多。

CREATE TABLE `content_tag_relation` (
  `content_id` int(10) unsigned NOT NULL, -- 內容ID
  `tag_name` varchar(60) NOT NULL -- 標籤名字
) ENGINE=InnoDB DEFAULT CHARSET=latin1

假設我們有以下的需求:
1. 得到標籤對應的文章名字,
SELECT a.name FROM content AS a,content_tag_relation AS b
WHERE a.id = b.content_id AND b.tag_name = `mysql`
2. 按照訪問量顯示前三的標籤,
SELECT tag_name FROM tag WHERE 1 ORDER BY visit_count DESC LIMIT 3;

下來我們在REDIS裡面儲存這部分資料。

第二,redis部分,

1. a,內容,我們用STRING型別來做,值用JSON來儲存,

t_girl:6379> set string:content_id:4  `{"name":"test48601","created_timestamp":"2012-01-01 05:41:01"}`
OK
t_girl:6379> get string:content_id:4
"{"name":"test48601","created_timestamp":"2012-01-01 05:41:01"}"
但是如果想得到內容對應的名字和建立時間,REDIS方面獲取困難,就得交給程式來做了。

 b,或者也可以用HASH型別來儲存,

t_girl:6379> hset `hset:content_id:4` name `test48601`
(integer) 1
t_girl:6379> hset `hset:content_id:4` created_timestamp `2012-01-01 05:41:01`
(integer) 1
那這時想獲取對應的名字以及時間非常容易
t_girl:6379> hget hset:content_id:4 name
"test48601"
t_girl:6379> hget hset:content_id:4 created_timestamp
"2012-01-01 05:41:01"
t_girl:6379>

2. 標籤,我們用有序集合來做,這麼做的好處是可以用REDIS對應的有序來做訪問量的排序。

t_girl:6379> zadd zset:tag 680 database 469 db2
(integer) 2
比如我們想要得到訪問前三的標籤名字?
t_girl:6379> zrevrangebyscore zset:tag +inf 0 limit 0 3
1) "mongodb"
2) "sql"
3) "postgresql"

3. 標籤與內容的關係,我們用集合來做,

t_girl:6379> sadd set:content_id:4 role mongodb role database 
(integer) 3
那麼也很容易得到指定內容對應的標籤
t_girl:6379> smembers set:content_id:4
1) "database"
2) "role"
3) "mongodb"

4.  a, 如果用上面的設計我們實現稍微複雜些的需求:比如得到標籤對應的文章名字。這樣的需求貌似沒有可以直接拿來用的方法,比如下面我寫的一段PYTHON程式碼來獲取:

    import redis
    content_id_keys = r.keys(`set*`)
    content_id_keys_len = len(content_id_keys)
    i = 0
    j = 0
    content_name_list = []
    while i < content_id_keys_len:
        if r.sismember(content_id_keys[i],`mysql`) == 1:
            content_name_list.append(eval(r.get(content_id_keys[i].replace(`set`,`string`)))[`name`])
            print(`Content name is :` + content_name_list[j])
            j += 1
        i += 1

b.那其實我們可以在REDIS裡面做一份冗餘的集合來儲存,這樣就可以直接把資訊拿出來。

t_girl:6379> sadd tag:mysql test123 test133 test144 test155
(integer) 4
t_girl:6379> smembers tag:mysql
1) "test133"
2) "test155"
3) "test123"
4) "test144"