1).Redis是NoSQL数据库,不是传统的关系型数据库
官网: http://redis.io/ 和http://www.redis.cn/
2).Redis:REmote DIctionary Server(远程字典服务器),Redis的性能非常高,单机可以达到15W gps.通常适合做缓存,也可以持久化
3)是完全开源免费的,高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化Nosql数据库,是最热门的NoSql数据库之一,也称为数据结构服务器
网址:https://github.com/tporadowski/redis/releases
下载好后的目录结构,其中有两个是redis的关键文件
redis客户端文件:redis-cli.exe
redis服务器文件:redis-server.exe
redis结构示意图
启动Redis的服务器端程序(redis-server.exe),直接双击即可运行
说明:
1)使用telnet操作Redis
2)使用redis-cli.exe操作Redis,双击即可进入客户端
3)Golang操作redis
redis基本指令
http://redisdoc.com(已失效)
-1.添加key-val [set]
-2.查看当前redis的所有key [key * 获取key对应的值[get key]
-3.切换redis数据库[select index]
-4.如何查看当前数据库的key-val数量[dbsize]
-5.清空当前数据库的key-val和清空所有数据库的key -val[flush db flushall]
(字符串)-介绍
-1.string是redis的基本类型,一个key对应一个value
-2.string是类型是二进制安全的。除普通的字符串外,也可以存放图片数据。
-3.redis中字符串value最大值是512M
举例,存放一个地址信息:
address北京天安门
说明:
key :address
value : 北京天安门
127.0.0.1:6379> set address beijing
OK
127.0.0.1:6379> get address
"beijing"
127.0.0.1:6379>
-4.String(字符串)-CRUD
举例说明Redis的String字符串的CRUD操作
set如果存在就相当于修改,不存在就是添加 /get/del
127.0.0.1:6379> del address
(integer) 1
127.0.0.1:6379> get address
(nil)
127.0.0.1:6379>
-5.String(字符串)-使用细节和注意事项
127.0.0.1:6379> setex mess01 10 hello,you
OK
127.0.0.1:6379> get mess01
"hello,you"
127.0.0.1:6379> get mess01
"hello,you"
127.0.0.1:6379> get mess01
"hello,you"
127.0.0.1:6379> get mess01
"hello,you"
127.0.0.1:6379> get mess01
(nil) //mess01有效期就10秒,10秒后就销毁
127.0.0.1:6379>
? MSET key vlaue [key value …]
? 同时设置一个或多个key-value对
? 如果某个给定key值已经存在,那么MSET会用新值覆盖原来的旧值
127.0.0.1:6379> mset worker01 tom worker02 scott
OK
127.0.0.1:6379> get worker01
"tom"
127.0.0.1:6379> get worker02
"scott"
127.0.0.1:6379> mget worker01 worker02
1) "tom"
2) "scott"
(哈希,类似于golang里的Map)-介绍
Redis hash是一个键值对象集合。var user1 map[string]string
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象
举例。存放一个User信息
user1 name 张三 age 10
说明
key : user1
name 张三 和 age 30 就是两对 field-value
实操:演示添加user的信息案例(name age job)
127.0.0.1:6379> hset user1 name "smith"
(integer) 1
127.0.0.1:6379> hset user1 age 30
(integer) 1
127.0.0.1:6379> hset user1 job "golang coder"
(integer) 1
127.0.0.1:6379> hget user1 name
"smith"
127.0.0.1:6379> hget user1 age
"30"
127.0.0.1:6379> hget user1 job
"golang coder"
127.0.0.1:6379>
Hash使用细节和注意事项
在给user设置name和age时,前面我们是一步一步设置,使用hmset和hmget可以一次性来设置多个field的值和返回多个field的值
127.0.0.1:6379> hmset user2 name jerry age 110 job "java coder"
OK
127.0.0.1:6379> hmget user2 name age job
1) "jerry"
2) "110"
3) "java coder"
127.0.0.1:6379>
hlen统计一个hash有几个元素
127.0.0.1:6379> hlen user2
(integer) 3
127.0.0.1:6379>
hexists key field
查看哈希表key中,给定域field是否存在
127.0.0.1:6379> hexists user2 name
(integer) 1
127.0.0.1:6379>
-1.(列表)-介绍
列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表头部(左边)或者尾部(右边)
List的本质是一个链表,List的元素的有序的,元素的值可以重复
举例,存放多个地址信息
city 北京 天津 上海
说明
北京 天津 上海 就是三个元素
127.0.0.1:6379> lpush city beijing shanghai tianjing
(integer) 3
127.0.0.1:6379> lrange city 0 -1(0表示开头 -1表示尾部)
1) "tianjing"
2) "shanghai"
3) "beijing"
127.0.0.1:6379>
-2.关于list的基本命令介绍
lpush:从左边插入数据
rpush:从右边插入数据
lrange: 用法 lrange key start stop :返回列表key中指定区间内的元素,区间以偏移量start和stop指定,下标(index)参数start和stop都是以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。你也可以使用函数负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推
lpop :从我们列表的左边弹出一个数据
rpop :从我们列表的右边弹出一个数据
del : 删掉这个列表
实战演示
127.0.0.1:6379> lpush herolist aa bb cc
(integer) 3
127.0.0.1:6379> lrange herolist 0 -1
1) "cc"
2) "bb"
3) "aa"
127.0.0.1:6379> rpush herolist dd eee
(integer) 5
127.0.0.1:6379> lrange herolist 0 -1
1) "cc"
2) "bb"
3) "aa"
4) "dd"
5) "eee"
127.0.0.1:6379> lpop herolist
"cc"
127.0.0.1:6379> lrange herolist 0 -1
1) "bb"
2) "aa"
3) "dd"
4) "eee"
127.0.0.1:6379> rpop herolist
"eee"
127.0.0.1:6379> lrange herolist 0 -1
1) "bb"
2) "aa"
3) "dd"
127.0.0.1:6379> del herolist
(integer) 1
127.0.0.1:6379> lrange herolist 0 -1
(empty list or set)
127.0.0.1:6379>
-3.List-使用细节和注意事项
(1)index,按照索引下标获得元素(从左到右,编号从0开始)
(2)LLEN key ,返回列表key的长度,如果key不存在,则key被解释为一个空列表,返回0
(3)List的其他说明
(集合)-介绍
Redis的Set是string类型的无序集合。
底层是HashTble数据结构,Set也是存放很多字符串元素,字符串元素是无序的,而且元素的值不能重复
举例,存放多个邮件列表信息
email sggg@sohu.com tom@sohu.com
说明
key :email
sggg@sohu.com tom@sohu.com 这两个就是元素
关于set的基本命令
sadd :添加元素
smembers :取出所有值
sismember :判断是否存在该成员
srem :删除指定值
127.0.0.1:6379> sadd emails tom@sohu.com jack@qq.com
(integer) 2
127.0.0.1:6379> smembers emails
1) "tom@sohu.com"
2) "jack@qq.com"
127.0.0.1:6379> sadd emails kk@yy.com uu@qq.com
(integer) 2
127.0.0.1:6379> smembers emails
1) "uu@qq.com"
2) "tom@sohu.com"
3) "jack@qq.com"
4) "kk@yy.com"
127.0.0.1:6379> sadd emails jack@qq.com
(integer) 0 //0表示添加失败,因为set的元素是不可以重复的
127.0.0.1:6379> sismember emails tom@sohu.com
(integer) 1 //查看set里面是否含有tom@souhu.com这个元素 1代表存在 0代表不存在
127.0.0.1:6379> sismember emails tom~@sohu.com
(integer) 0
127.0.0.1:6379> srem emails tom@sohu.com
(integer) 1 //演示删除元素
127.0.0.1:6379> smembers emails
1) "kk@yy.com"
2) "uu@qq.com"
3) "jack@qq.com"
127.0.0.1:6379>
1)使用第三方开源的redis库:github.com/garyburd/redigo/redis
2)在使用redis前,先安装第三方Redis库,在GOPATH路径下执行安装指令:
D:\myfile\go\project>go get github.com/garyburd/redigo/redis
3)安装之后,可以看到如下包
特别说明:在安装Redis 库之前,确保已经安装并配置了git,因为是从github上下载安装库的,需要使用到git
Set/Get接口
说明:通过golang添加和获取key-value【比如name-tom~】
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
//通过go向redis写入数据和读取数据
//1.连接到redis
conn,err := redis.Dial("tcp","127.0.0.1:6379")
if err != nil {
fmt.Println("redis.Dial err=",err)
return
}
defer conn.Close() //关闭
//2.通过go向redis写入数据string [key-val]
_, err=conn.Do("Set","name","tomjerry毛毛和老鼠")
if err != nil {
fmt.Println("set err=",err)
return
}
//3.通过go向redis读入数据string [key-val]
r, err :=redis.String(conn.Do("Get","name"))
if err != nil {
fmt.Println("Get err=",err)
return
}
//返回的r是interfacce{}
//因为name对应的值是字符串,因此我们需要转换[在一开始就用redis提供的方法进行转换]
//nameString := r.(string) erro
fmt.Println("操作成功!",r) //操作成功! tomjerry毛毛和老鼠
}
说明:通过Golang对redis操作Hash数据类型
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
//通过go向redis写入数据和读取数据
//1.连接到redis
conn,err := redis.Dial("tcp","127.0.0.1:6379")
if err != nil {
fmt.Println("redis.Dial err=",err)
return
}
defer conn.Close() //关闭
//2.通过go向redis写入数据string [key-val]
//写入名字
_, err=conn.Do("HSet","user01","name","john")
if err != nil {
fmt.Println("hset err=",err)
return
}
//写入age
_, err=conn.Do("HSet","user01","age",10)
if err != nil {
fmt.Println("hset err=",err)
return
}
//3.通过go向redis读入数据string [key-val]
r1, err :=redis.String(conn.Do("HGet","user01","name"))
if err != nil {
fmt.Println("hGet err=",err)
return
}
r2, err :=redis.Int(conn.Do("HGet","user01","age"))
if err != nil {
fmt.Println("hGet err=",err)
return
}
fmt.Printf("操作成功! r1=%v,r2=%v\n",r1,r2) //操作成功! r1=john,r2=10
}
说明:通过Golang对Redis操作,一次操作可以Set/Get多个key-val数
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
//通过go向redis写入数据和读取数据
//1.连接到redis
conn,err := redis.Dial("tcp","127.0.0.1:6379")
if err != nil {
fmt.Println("redis.Dial err=",err)
return
}
defer conn.Close() //关闭
//2.通过go向redis写入数据string [key-val]
//写入名字和年龄
_, err=conn.Do("HMSet","user02","name","tom","age",19)
if err != nil {
fmt.Println("HMSet err=",err)
return
}
//3.通过go向redis读入数据string [key-val]
r, err :=redis.Strings(conn.Do("HMGet","user02","name","age"))
if err != nil {
fmt.Println("hGet err=",err)
return
}
// fmt.Printf("r=%v\n",r) //r=[tom 19]
for i,v := range r {
fmt.Printf("r[%d]=%v\n",i,v)
}
}
说明:通过golang对redis操作,给key-value设置有效时间
core code
//给name数据设置有效时间10s
_,err =c.Do("expire","name",10)
5)操作List
说明:通过golang对redis操作list数据类型
corecode
_,err=c.Do("lpush","herolist","no1.宋江",30,"no2.吴用",28)
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
var names string
var ages int
var skills string
//1.连接到redis
conn,err := redis.Dial("tcp","127.0.0.1:6379")
if err != nil {
fmt.Println("redis.Dial err=",err)
return
}
defer conn.Close() //关闭
fmt.Println("请输入names: ")
fmt.Scan(&names)
fmt.Println("请输入ages: ")
fmt.Scan(&ages)
fmt.Println("请输入skills: ")
fmt.Scan(&skills)
//go操作redis进行写的操作
_, err=conn.Do("HMSet","monster","name",names,"age",ages,"skill",skills)
if err != nil {
fmt.Println("HMSet err=",err)
return
}
//go操作redis进行读的操作
r, err :=redis.Strings(conn.Do("HMGet","monster","name","age","skill"))
if err != nil {
fmt.Println("HMGet err=",err)
return
}
for i,v := range r{
fmt.Printf("r[%d]=%v\n",i,v)
}
fmt.Println("操作完成")
}
说明:通过Golang对redis的操作,还可以通过redis连接池,流程如下
-1.事先初始化一定数量的连接,放入到连接池
-2.当go需要操作redis时,直接从redis连接池取出连接即可
-3.这样可以节省临时获取redis连接的时间,从而提高效率
core code
var pool *redis.Pool
pool = &redis.Pool{
MaxIdle:8
MaxActive:0
IdleTimeout:100
Dial:func()(redis.Conn,error){
return redis.Dial("tcp","localhost:6379")
},
}
c :=pool.Get()
-4.示意图
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
//定义一个全局的pool
var pool *redis.Pool
//当启动程序时就初始化连接池
func init() {
pool = &redis.Pool{
MaxIdle:8, //最大空闲连接数
MaxActive:0,//表示和数据库的最大连接数,0表示没有限制
IdleTimeout:100,//最大空闲时间
Dial:func()(redis.Conn,error){//初始化连接的代码。连接哪个ip
return redis.Dial("tcp","localhost:6379")
},
}
}
func main() {
//先从pool池取出一个连接
conn := pool.Get()
defer conn.Close()
_, err :=conn.Do("Set","name","汤姆猫~~")
if err != nil {
fmt.Println("conn.Do err=",err)
return
}
//取出
r,err :=redis.String(conn.Do("Get","name"))
if err != nil {
fmt.Println("conn.Do err=",err)
return
}
fmt.Println("r=",r)
}