mongodb和redis的区别


show dbs
切换数据库
如果数据库不存在,则指向数据库,但不创建,直到插入数据或创建集合时数据库才被创建
use 数据库名称
默认的数据库为test,如果你没有创建新的数据库,集合将存放在test数据库中
数据库删除
删除当前指向的数据库
如果数据库不存在,则什么也不做
db.dropDatabase()

集合操作

集合创建
语法
db.createCollection(name, options)
name是要创建的集合的名称
options是一个文档,用于指定集合的配置
选项参数是可选的,所以只需要到指定的集合名称。以下是可以使用的选项列表:

例1:不限制集合大小
db.createCollection("stu")

例2:限制集合大小,后面学会插入语句后可以查看效果
参数capped:默认值为false表示不设置上限,值为true表示设置上限
参数size:当capped值为true时,需要指定此参数,表示上限大小,当文档达到上限时,会将之前的数据覆盖,单位为字节

db.createCollection("sub", { capped : true, size : 10 } )


查看当前数据库的集合
语法
show collections


删除
语法
db.集合名称.drop()

数据操作


数据类型
下表为MongoDB中常用的几种数据类型:
Object ID:文档ID
String:字符串,最常用,必须是有效的UTF-8
Boolean:存储一个布尔值,true或false
Integer:整数可以是32位或64位,这取决于服务器
Double:存储浮点值
Arrays:数组或列表,多个值存储到一个键
Object:用于嵌入式的文档,即一个值为一个文档
Null:存储Null值
Timestamp:时间戳
Date:存储当前日期或时间的UNIX时间格式


object id
每个文档都有一个属性,为_id,保证每个文档的唯一性
可以自己去设置_id插入文档
如果没有提供,那么MongoDB为每个文档提供了一个独特的_id,类型为objectID

objectID是一个12字节的十六进制数
前4个字节为当前时间戳
接下来3个字节的机器ID
接下来的2个字节中MongoDB的服务进程id
最后3个字节是简单的增量值

插入
语法
db.集合名称.insert(document)
插入文档时,如果不指定_id参数,MongoDB会为文档分配一个唯一的ObjectId

db.stu.insert({name:'gj',gender:1})

s1={_id:'20160101',name:'hr'}
s1.gender=0
db.stu.insert(s1)

查询语法
db.集合名称.find()


更新语法
db.集合名称.update(<query>,<update>, {multi: <boolean>})
参数query:查询条件,类似sql语句update中where部分
参数update:更新操作符,类似sql语句update中set部分
参数multi:可选,默认是false,表示只更新找到的第一条记录,值为true表示把满足条件的文档全部更新
db.stu.update({name:'hr'},{name:'mnc'})
指定属性更新,通过操作符$set
db.stu.insert({name:'hr',gender:0})
db.stu.update({name:'hr'},{$set:{name:'hys'}})
修改多条匹配到的数据
db.stu.update({},{$set:{gender:0}},{multi:true})


保存语法
db.集合名称.save(document)
如果文档的_id已经存在则修改,如果文档的_id不存在则添加
db.stu.save({_id:'20160102','name':'yk',gender:1})
db.stu.save({_id:'20160102','name':'wyk'})


删除语法
db.集合名称.remove(<query>, { justOne: <boolean> })

参数query:可选,删除的文档的条件
参数justOne:可选,如果设为true或1,则只删除一条,默认false,表示删除多条
db.stu.remove({gender:0},{justOne:true})

全部删除
db.stu.remove({})

备份与恢复

备份
语法
mongodump -h dbhost -d dbname -o dbdirectory
-h:服务器地址,也可以指定端口号
-d:需要备份的数据库名称
-o:备份的数据存放位置,此目录中存放着备份出来的数据
例1
sudo mkdir test1bak
sudo mongodump -h 192.168.196.128:27017 -d test1 -o ~/Desktop/test1bak
恢复
语法
mongorestore -h dbhost -d dbname --dir dbdirectory
-h:服务器地址
-d:需要恢复的数据库实例
--dir:备份数据所在位置
例2
mongorestore -h 192.168.196.128:27017 -d test2 --dir ~/Desktop/test1bak/test1

授权

创建超级管理员账户
use admin
db.createUser({
user:'root',
pwd:'123456',
roles:[{
role:'root',
db:'admin'
}]
})


配置文件开启权限验证
security:
authorization: enabled


mongodb查询

数据查询

基本查询
方法find():查询
db.集合名称.find({条件文档})
方法findOne():查询,只返回第一个
db.集合名称.findOne({条件文档})
方法pretty():将结果格式化
db.集合名称.find({条件文档}).pretty()
比较运算符
等于,默认是等于判断,没有运算符
小于$lt
小于或等于$lte
大于$gt
大于或等于$gte
不等于$ne
例1:查询名称等于'gj'的学生
db.stu.find({name:'gj'})
例2:查询年龄大于或等于18的学生
db.stu.find({age:{$gte:18}})
逻辑运算符
查询时可以有多个条件,多个条件之间需要通过逻辑运算符连接
逻辑与:默认是逻辑与的关系
例3:查询年龄大于或等于18,并且性别为1的学生
db.stu.find({age:{$gte:18},gender:1})
逻辑或:使用$or
例4:查询年龄大于18,或性别为0的学生
db.stu.find({$or:[{age:{$gt:18}},{gender:1}]})
and和or一起使用
例5:查询年龄大于18或性别为0的学生,并且学生的姓名为gj

db.stu.find({$or:[{age:{$gte:18}},{gender:1}],name:'gj'})
范围运算符
使用"$in","$nin" 判断是否在某个范围内
例6:查询年龄为18、28的学生
db.stu.find({age:{$in:[18,28]}})
支持正则表达式
使用//或$regex编写正则表达式
例7:查询姓黄的学生
db.stu.find({name:/^黄/})
自定义查询
使用$where后面写一个函数,返回满足条件的数据
例7:查询年龄大于30的学生
db.stu.find({$where:function(){return this.age>20}})

投影

在查询到的返回结果中,只选择必要的字段,而不是选择一个文档的整个字段
如:一个文档有5个字段,需要显示只有3个,投影其中3个字段即可
语法:
参数为字段与值,值为1表示显示,值为0不显示
db.集合名称.find({},{字段名称:1,...})
对于需要显示的字段,设置为1即可,不设置即为不显示
特殊:对于_id列默认是显示的,如果不显示需要明确设置为0
db.stu.find({},{name:1,gender:1})
db.stu.find({},{_id:0,name:1,gender:1})

排序

方法sort(),用于对结果集进行排序
语法
db.集合名称.find().sort({字段:1,...})
参数1为升序排列
参数-1为降序排列
根据性别降序,再根据年龄升序

db.stu.find().sort({gender:-1,age:1})

分页

Limit
方法limit():用于读取指定数量的文档
语法:
db.集合名称.find().limit(NUMBER)
参数NUMBER表示要获取文档的条数
如果没有指定参数则显示集合中的所有文档
例1:查询2条学生信息
db.stu.find().limit(2)
skip
方法skip():用于跳过指定数量的文档
语法:
db.集合名称.find().skip(NUMBER)
参数NUMBER表示跳过的记录条数,默认值为0
例2:查询从第3条开始的学生信息
db.stu.find().skip(2)
一起使用
方法limit()和skip()可以一起使用,不分先后顺序
创建数据集
for(i=0;i<15;i++){db.t1.insert({_id:i})}
查询第5至8条数据
db.stu.find().limit(4).skip(5)

db.stu.find().skip(5).limit(4)

统计

统计个数
方法count()用于统计结果集中文档条数
语法
db.集合名称.find({条件}).count()
也可以与为
db.集合名称.count({条件})
例1:统计男生人数
db.stu.find({gender:1}).count()
例2:统计年龄大于20的男生人数
db.stu.count({age:{$gt:20},gender:1})

去重

方法distinct()对数据进行去重
语法
db.集合名称.distinct('去重字段',{条件})
例1:查找年龄大于18的性别(去重)
db.stu.distinct('gender',{age:{$gt:18}})

python操作mongodb

安装python包
pip install pymongo
引入包pymongo
import pymongo
连接,创建客户端
client=pymongo.MongoClient("localhost", 27017)
获得数据库test1
db=client[test1]
获得集合stu
stu = db[stu]
添加文档
s1={name:'gj',age:18}
s1_id = stu.insert_one(s1).inserted_id
查找一个文档
s2=stu.find_one()
查找多个文档1
for cur in stu.find():
print cur
查找多个文档2
cur=stu.find()
cur.next()
cur.next()
cur.next()
获取文档个数
print stu.count()

redis基础

Redis简介

Remote DIctionary Server(Redis) 是一个key-value存储系统。
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
Redis支持数据的备份,即master-slave模式的数据备份

Ubuntu安装Redis

sudo apt-get install redis-server
停止服务
service redis stop
启动服务
service redis start
启动服务端
redis-server
启动客户端
redis-cli

Redis配置

以指定配置文件启动服务端
redis-server "C:\Program Files\Redis\redis.conf"
获取所有配置信息
config get *
获取单项配置信息
config get loglevel
config get dbfilename
...
设置单项配置信息
config set loglevel warning
config set ...


设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id
databases 16
绑定的主机地址
bind 127.0.0.1
绑定的主机端口
port 6379

指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
save <seconds><changes>
Redis默认配置文件中提供了三个条件:
save 900 1
save 300 10
save 60 10000
分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
指定本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb
指定本地数据库存放目录
dir ./
设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
requirepass foobared
设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
slaveof <masterip><masterport>
当master服务设置了密码保护时,slav服务连接master的密码
masterauth <master-password>
Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
daemonize no
当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
timeout 300


redis数据操作

数据类型

redis是key-value的数据,所以每个数据都是一个键值对
键的类型是字符串
值的类型分为五种:
字符串string
哈希hash
列表list
集合set
有序集合zset

String类型

设置
设置键值
set key value
设置键值及过期时间,以秒为单位
SETEX key seconds value
redis> setex 1001 50 'zhouzhiruo'


设置多个键值
MSET key value [key value ...]

根据键获取值,如果不存在此键则返回nil
GET key
根据多个键获取多个值
MGET key [key ...]


redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny"
OK

redis> MGET date time weather
1) "2012.3.30"
2) "11:00 a.m."
3) "sunny"


要求:值是数字
将key对应的value加1
INCR key
将key对应的value加整数
INCRBY key increment
将key对应的value减1
redis> SET page_view 20
OK

redis> INCR page_view
(integer) 21

redis> GET page_view # 数字值在 Redis 中以字符串的形式保存
"21"

键存在,并且值为数字:

redis> SET rank 50
OK

redis> INCRBY rank 20
(integer) 70

redis> GET rank
"70"
键不存在:

redis> EXISTS counter
(integer) 0

redis> INCRBY counter 30
(integer) 30

redis> GET counter
"30"
键存在,但值无法被解释为数字:

redis> SET book "long long ago..."
OK

redis> INCRBY book 200
(error) ERR value is not an integer or out of range

DECR key
将key对应的value减整数
DECRBY key decrement

对储存数字值的键 key 执行 DECR 命令:

redis> SET failure_times 10
OK

redis> DECR failure_times
(integer) 9
对不存在的键执行 DECR 命令:

redis> EXISTS count
(integer) 0

redis> DECR count
(integer) -1

其它
追加值
APPEND key value

对不存在的 key 执行 APPEND :

redis> EXISTS myphone # 确保 myphone 不存在
(integer) 0

redis> APPEND myphone "nokia" # 对不存在的 key 进行 APPEND ,等同于 SET myphone "nokia"
(integer) 5 # 字符长度
对已存在的字符串进行 APPEND :

redis> APPEND myphone " - 1110" # 长度从 5 个字符增加到 12 个字符
(integer) 12

redis> GET myphone
"nokia - 1110"

获取值长度
STRLEN key
获取字符串值的长度:

redis> SET mykey "Hello world"
OK

redis> STRLEN mykey
(integer) 11
不存在的键的长度为 0 :

redis> STRLEN nonexisting
(integer) 0

键操作

查找键,参数支持正则
KEYS pattern
redis> MSET one 1 two 2 three 3 four 4 # 一次设置 4 个 key
OK

redis> KEYS *o*
1) "four"
2) "two"
3) "one"

redis> KEYS t??
1) "two"

redis> KEYS t[w]*
1) "two"

redis> KEYS * # 匹配数据库内所有 key
1) "four"
2) "three"
3) "two"
4) "one"

KEYS 的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 key ,你最好还是用 Redis 的集合结构(set)来代替。


判断键是否存在,如果存在返回1,不存在返回0
EXISTS key [key ...]
redis> SET db "redis"
OK

redis> EXISTS db
(integer) 1

redis> DEL db
(integer) 1

redis> EXISTS db
(integer) 0


查看键对应的value的类型
TYPE key
# 字符串

redis> SET weather "sunny"
OK

redis> TYPE weather
string


# 列表

redis> LPUSH book_list "programming in scala"
(integer) 1

redis> TYPE book_list
list


# 集合

redis> SADD pat "dog"
(integer) 1

redis> TYPE pat
set


删除键及对应的值
DEL key [key ...]
# 删除单个 key

redis> SET name huangz
OK

redis> DEL name
(integer) 1


# 删除一个不存在的 key

redis> EXISTS phone
(integer) 0

redis> DEL phone # 失败,没有 key 被删除
(integer) 0


# 同时删除多个 key

redis> SET name "redis"
OK

redis> SET type "key-value store"
OK

redis> SET website "redis.com"
OK

redis> DEL name type website
(integer) 3

设置过期时间,以秒为单位
创建时没有设置过期时间则一直存在,直到使用使用DEL移除
EXPIRE key seconds


redis> SET cache_page "www.google.com"
OK
redis> EXPIRE cache_page 30 # 设置过期时间为 30 秒
(integer) 1

redis> TTL cache_page # 查看剩余生存时间
(integer) 23

redis> EXPIRE cache_page 30000 # 更新过期时间
(integer) 1

redis> TTL cache_page
(integer) 29996


查看有效时间,以秒为单位
TTL key
# 不存在的 key

redis> FLUSHDB
OK

redis> TTL key
(integer) -2


# key 存在,但没有设置剩余生存时间

redis> SET key value
OK

redis> TTL key
(integer) -1


# 有剩余生存时间的 key

redis> EXPIRE key 10086
(integer) 1

redis> TTL key
(integer) 10084


hash

hash用于存储对象,对象的格式为键值对
设置
设置单个属性
HSET key field value
设置一个新域:

redis> HSET website google "www.g.cn"
(integer) 1

redis> HGET website google
"www.g.cn"
对一个已存在的域进行更新:

redis> HSET website google "www.google.com"
(integer) 0

redis> HGET website google
"www.google.com"


设置多个属性
HMSET key field value [field value ...]
redis> HMSET website google www.google.com yahoo www.yahoo.com
OK

redis> HGET website google
"www.google.com"

redis> HGET website yahoo
"www.yahoo.com"

获取
获取一个属性的值
HGET key field
域存在的情况:

redis> HSET homepage redis redis.com
(integer) 1

redis> HGET homepage redis
"redis.com"
域不存在的情况:

redis> HGET site mysql
(nil)

获取多个属性的值
HMGET key field [field ...]
redis> HMSET pet dog "doudou" cat "nounou" # 一次设置多个域
OK

redis> HMGET pet dog cat fake_pet # 返回值的顺序和传入参数的顺序一样
1) "doudou"
2) "nounou"
3) (nil) # 不存在的域返回nil值

获取所有属性和值
HGETALL key
redis> HSET people jack "Jack Sparrow"
(integer) 1

redis> HSET people gump "Forrest Gump"
(integer) 1

redis> HGETALL people
1) "jack" # 域
2) "Jack Sparrow" # 值
3) "gump"
4) "Forrest Gump"

获取所有的属性
HKEYS key
# 哈希表非空

redis> HMSET website google www.google.com yahoo www.yahoo.com
OK

redis> HKEYS website
1) "google"
2) "yahoo"


# 空哈希表/key不存在

redis> EXISTS fake_key
(integer) 0

redis> HKEYS fake_key
(empty list or set)


返回包含属性的个数
HLEN key
redis> HSET db redis redis.com
(integer) 1

redis> HSET db mysql mysql.com
(integer) 1

redis> HLEN db
(integer) 2

redis> HSET db mongodb mongodb.org
(integer) 1

redis> HLEN db
(integer) 3


获取所有值
HVALS key
# 非空哈希表

redis> HMSET website google www.google.com yahoo www.yahoo.com
OK

redis> HVALS website
1) "www.google.com"
2) "www.yahoo.com"


# 空哈希表/不存在的key

redis> EXISTS not_exists
(integer) 0

redis> HVALS not_exists
(empty list or set)


其它
判断属性是否存在
HEXISTS key field
给定域不存在:

redis> HEXISTS phone myphone
(integer) 0
给定域存在:

redis> HSET phone myphone nokia-1110
(integer) 1

redis> HEXISTS phone myphone
(integer) 1


删除属性及值
HDEL key field [field ...]
# 测试数据

redis> HGETALL abbr
1) "a"
2) "apple"
3) "b"
4) "banana"
5) "c"
6) "cat"
7) "d"
8) "dog"


# 删除单个域

redis> HDEL abbr a
(integer) 1


# 删除不存在的域

redis> HDEL abbr not-exists-field
(integer) 0


# 删除多个域

redis> HDEL abbr b c
(integer) 2

redis> HGETALL abbr
1) "d"
2) "dog"


返回值的字符串长度
HSTRLEN key field
redis> HMSET myhash f1 "HelloWorld" f2 "99" f3 "-256"
OK

redis> HSTRLEN myhash f1
(integer) 10

redis> HSTRLEN myhash f2
(integer) 2

redis> HSTRLEN myhash f3
(integer) 4


list

列表的元素类型为string
按照插入顺序排序
在列表的头部或者尾部添加元素

设置
在头部插入数据
LPUSH key value [value ...]
# 加入单个元素

redis> LPUSH languages python
(integer) 1


# 加入重复元素

redis> LPUSH languages python
(integer) 2

redis> LRANGE languages 0 -1 # 列表允许重复元素
1) "python"
2) "python"


# 加入多个元素

redis> LPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"

在尾部插入数据
RPUSH key value [value ...]

# 添加单个元素

redis> RPUSH languages c
(integer) 1


# 添加重复元素

redis> RPUSH languages c
(integer) 2

redis> LRANGE languages 0 -1 # 列表允许重复元素
1) "c"
2) "c"


# 添加多个元素

redis> RPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"


在一个元素的前|后插入新元素
LINSERT key BEFORE|AFTER pivot value
redis> RPUSH mylist "Hello"
(integer) 1

redis> RPUSH mylist "World"
(integer) 2

redis> LINSERT mylist BEFORE "World" "There"
(integer) 3

redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"


# 对一个非空列表插入,查找一个不存在的 pivot

redis> LINSERT mylist BEFORE "go" "let's"
(integer) -1 # 失败


# 对一个空列表执行 LINSERT 命令

redis> EXISTS fake_list
(integer) 0

redis> LINSERT fake_list BEFORE "nono" "gogogog"
(integer) 0 # 失败


设置指定索引的元素值
索引是基于0的下标
索引可以是负数,表示偏移量是从list尾部开始计数,如-1表示列表的最后一个元素
LSET key index value
# 对空列表(key 不存在)进行 LSET

redis> EXISTS list
(integer) 0

redis> LSET list 0 item
(error) ERR no such key


# 对非空列表进行 LSET

redis> LPUSH job "cook food"
(integer) 1

redis> LRANGE job 0 0
1) "cook food"

redis> LSET job 0 "play game"
OK

redis> LRANGE job 0 0
1) "play game"


# index 超出范围

redis> LLEN list # 列表长度为 1
(integer) 1

redis> LSET list 3 'out of range'
(error) ERR index out of range


移除并且返回 key 对应的 list 的第一个元素
LPOP key
redis> LLEN course
(integer) 0

redis> RPUSH course algorithm001
(integer) 1

redis> RPUSH course c++101
(integer) 2

redis> LPOP course # 移除头元素
"algorithm001"

移除并返回存于 key 的 list 的最后一个元素
RPOP key
redis> RPUSH mylist "one"
(integer) 1

redis> RPUSH mylist "two"
(integer) 2

redis> RPUSH mylist "three"
(integer) 3

redis> RPOP mylist # 返回被弹出的元素
"three"

redis> LRANGE mylist 0 -1 # 列表剩下的元素
1) "one"
2) "two"


返回存储在 key 的列表里指定范围内的元素
start 和 end 偏移量都是基于0的下标
偏移量也可以是负数,表示偏移量是从list尾部开始计数,如-1表示列表的最后一个元素
LRANGE key start stop

redis> RPUSH fp-language lisp
(integer) 1

redis> LRANGE fp-language 0 0
1) "lisp"

redis> RPUSH fp-language scheme
(integer) 2

redis> LRANGE fp-language 0 1
1) "lisp"
2) "scheme"

裁剪列表,改为原集合的一个子集
start 和 end 偏移量都是基于0的下标
偏移量也可以是负数,表示偏移量是从list尾部开始计数,如-1表示列表的最后一个元素
LTRIM key start stop

# 情况 1: 常见情况, start 和 stop 都在列表的索引范围之内

redis> LRANGE alpha 0 -1 # alpha 是一个包含 5 个字符串的列表
1) "h"
2) "e"
3) "l"
4) "l"
5) "o"

redis> LTRIM alpha 1 -1 # 删除 alpha 列表索引为 0 的元素
OK

redis> LRANGE alpha 0 -1 # "h" 被删除了
1) "e"
2) "l"
3) "l"
4) "o"


# 情况 2: stop 比列表的最大下标还要大


redis> LTRIM alpha 1 10086 # 保留 alpha 列表索引 1 至索引 10086 上的元素
OK

redis> LRANGE alpha 0 -1 # 只有索引 0 上的元素 "e" 被删除了,其他元素还在
1) "l"
2) "l"
3) "o"


# 情况 3: start 和 stop 都比列表的最大下标要大,并且 start < stop

redis> LTRIM alpha 10086 123321
OK

redis> LRANGE alpha 0 -1 # 列表被清空
(empty list or set)


# 情况 4: start 和 stop 都比列表的最大下标要大,并且 start > stop

redis> RPUSH new-alpha "h" "e" "l" "l" "o" # 重新建立一个新列表
(integer) 5

redis> LRANGE new-alpha 0 -1
1) "h"
2) "e"
3) "l"
4) "l"
5) "o"

redis> LTRIM new-alpha 123321 10086 # 执行 LTRIM
OK

redis> LRANGE new-alpha 0 -1 # 同样被清空
(empty list or set)


返回存储在 key 里的list的长度
LLEN key
# 空列表

redis> LLEN job
(integer) 0


# 非空列表

redis> LPUSH job "cook food"
(integer) 1

redis> LPUSH job "have lunch"
(integer) 2

redis> LLEN job
(integer) 2

返回列表里索引对应的元素
LINDEX key index
redis> LPUSH mylist "World"
(integer) 1

redis> LPUSH mylist "Hello"
(integer) 2

redis> LINDEX mylist 0
"Hello"

redis> LINDEX mylist -1
"World"

redis> LINDEX mylist 3 # index不在 mylist 的区间范围内
(nil)


set

无序集合
元素为string类型
元素具有唯一性,不重复

添加元素
SADD key member [member ...]
# 添加单个元素

redis> SADD bbs "discuz.net"
(integer) 1


# 添加重复元素

redis> SADD bbs "discuz.net"
(integer) 0


# 添加多个元素

redis> SADD bbs "tianya.cn" "groups.google.com"
(integer) 2

redis> SMEMBERS bbs
1) "discuz.net"
2) "groups.google.com"
3) "tianya.cn"


返回key集合所有的元素
SMEMBERS key
# key 不存在或集合为空

redis> EXISTS not_exists_key
(integer) 0

redis> SMEMBERS not_exists_key
(empty list or set)


# 非空集合

redis> SADD language Ruby Python Clojure
(integer) 3

redis> SMEMBERS language
1) "Python"
2) "Ruby"
3) "Clojure"

返回集合元素个数
SCARD key
redis> SADD tool pc printer phone
(integer) 3

redis> SCARD tool # 非空集合
(integer) 3

redis> DEL tool
(integer) 1

redis> SCARD tool # 空集合
(integer) 0

求多个集合的交集
SINTER key [key ...]
redis> SMEMBERS group_1
1) "LI LEI"
2) "TOM"
3) "JACK"

redis> SMEMBERS group_2
1) "HAN MEIMEI"
2) "JACK"

redis> SINTER group_1 group_2
1) "JACK"


求某集合与其它集合的差集
SDIFF key [key ...]
redis> SMEMBERS peter's_movies
1) "bet man"
2) "start war"
3) "2012"

redis> SMEMBERS joe's_movies
1) "hi, lady"
2) "Fast Five"
3) "2012"

redis> SDIFF peter's_movies joe's_movies
1) "bet man"
2) "start war"

求多个集合的合集
SUNION key [key ...]
redis> SMEMBERS songs
1) "Billie Jean"

redis> SMEMBERS my_songs
1) "Believe Me"

redis> SUNION songs my_songs
1) "Billie Jean"
2) "Believe Me"

判断元素是否在集合中
SISMEMBER key member
redis> SMEMBERS joe's_movies
1) "hi, lady"
2) "Fast Five"
3) "2012"

redis> SISMEMBER joe's_movies "bet man"
(integer) 0

redis> SISMEMBER joe's_movies "Fast Five"
(integer) 1

zset

sorted set,有序集合
元素为string类型
元素具有唯一性,不重复
每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序
元素的score可以相同

添加
ZADD key score member [score member ...]
# 添加单个元素

redis> ZADD page_rank 10 google.com
(integer) 1


# 添加多个元素

redis> ZADD page_rank 9 baidu.com 8 bing.com
(integer) 2

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 添加已存在元素,且 score 值不变

redis> ZADD page_rank 10 google.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES # 没有改变
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 添加已存在元素,但是改变 score 值

redis> ZADD page_rank 6 bing.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES # bing.com 元素的 score 值被改变
1) "bing.com"
2) "6"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


返回指定范围内的元素
ZRANGE key start stop
redis > ZRANGE salary 0 -1 WITHSCORES # 显示整个有序集成员
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis > ZRANGE salary 1 2 WITHSCORES # 显示有序集下标区间 1 至 2 的成员
1) "tom"
2) "5000"
3) "boss"
4) "10086"

redis > ZRANGE salary 0 200000 WITHSCORES # 测试 end 下标超出最大下标时的情况
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis > ZRANGE salary 200000 3000000 WITHSCORES # 测试当给定区间不存在于有序集时的情况
(empty list or set)

返回元素个数
ZCARD key
redis > ZADD salary 2000 tom # 添加一个成员
(integer) 1

redis > ZCARD salary
(integer) 1

redis > ZADD salary 5000 jack # 再添加一个成员
(integer) 1

redis > ZCARD salary
(integer) 2

redis > EXISTS non_exists_key # 对不存在的 key 进行 ZCARD 操作
(integer) 0

redis > ZCARD non_exists_key
(integer) 0

返回有序集key中,score值在min和max之间的成员
ZCOUNT key min max
redis> ZRANGE salary 0 -1 WITHSCORES # 测试数据
1) "jack"
2) "2000"
3) "peter"
4) "3500"
5) "tom"
6) "5000"

redis> ZCOUNT salary 2000 5000 # 计算薪水在 2000-5000 之间的人数
(integer) 3

redis> ZCOUNT salary 3000 5000 # 计算薪水在 3000-5000 之间的人数
(integer) 2


返回有序集key中,成员member的score值
ZSCORE key member
redis> ZRANGE salary 0 -1 WITHSCORES # 测试数据
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"

redis> ZSCORE salary peter # 注意返回值是字符串
"3500"

redis高级

发布订阅

发布者不是计划发送消息给特定的接收者(订阅者),而是发布的消息分到不同的频道,不需要知道什么样的订阅者订阅。

订阅者对一个或多个频道感兴趣,只需接收感兴趣的消息,不需要知道什么样的发布者发布的发布者和订阅者的解耦合可以带来更大的扩展性和更加动态的网络拓扑客户端发到频道的消息,将会被推送到所有订阅此频道的客户端。

客户端不需要主动去获取消息,只需要订阅频道,这个频道的内容就会被推送过来消息的格式。


推送消息的格式包含三部分
part1:消息类型,包含三种类型
subscribe,表示订阅成功
unsubscribe,表示取消订阅成功
message,表示其它终端发布消息

如果第一部分的值为subscribe,则第二部分是频道,第三部分是现在订阅的频道的数量
如果第一部分的值为unsubscribe,则第二部分是频道,第三部分是现在订阅的频道的数量,如果为0则表示当前没有
订阅任何频道,当在Pub/Sub以外状态,客户端可以发出任何redis命令
如果第一部分的值为message,则第二部分是来源频道的名称,第三部分是消息的内容
命令
订阅
SUBSCRIBE 频道名称 [频道名称 ...]
取消订阅
如果不写参数,表示取消所有订阅
UNSUBSCRIBE 频道名称 [频道名称 ...]
发布
PUBLISH 频道 消息

主从配置

一个master可以拥有多个slave,一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构
比如,将ip为192.168.1.10的机器作为主服务器,将ip为192.168.1.11的机器作为从服务器
设置主服务器的配置
bind 192.168.1.10
设置从服务器的配置
注意:在slaveof后面写主机ip,再写端口,而且端口必须写
bind 192.168.1.11
slaveof 192.168.1.10 6379

在master和slave分别执行info命令,查看输出信息
在master上写数据
set hello world
在slave上读数据
get hello


安全配置

Redis 安全
配置密码
查看密码
CONFIG get requirepass

设置密码
CONFIG set requirepass 123456

远程连接
redis-cli -h 127.0.0.1 -p 6379 -a 123456

登录之后授权
auth 123456


python操作redis

redis模块使用

安装
pip install redis
引入模块
import redis
连接
try:
r=redis.StrictRedis(host='localhost',port=6379)
except Exception,e:
print e.message

方式一:根据数据类型的不同,调用相应的方法,完成读写
更多方法同前面学的命令
r.set('name','hello')
r.get('name')

方式二:pipline
缓冲多条命令,然后一次性执行,减少服务器-客户端之间TCP数据库包,从而提高效率
pipe = r.pipeline()
pipe.set('name', 'world')
pipe.get('name')
pipe.execute()

封装

连接redis服务器部分是一致的
这里将string类型的读写进行封装
import redis
class RedisHelper():
def __init__(self,host='localhost',port=6379):
self.__redis = redis.StrictRedis(host, port)
def get(self,key):
if self.__redis.exists(key):
return self.__redis.get(key)
else:
return ""
def set(self,key,value):
self.__redis.set(key,value)

示例:用户登录

业务过程如下:
输入用户名、密码
密码加密
判断redis中是否记录了用户名,如果有则成功
如果redis中没有用户名,则到mysql中查询
从mysql中查询成功后,将用户名记录到redis中
from t2 import RedisHelper
from t3 import MysqlHelper
import hashlib
name=raw_input("请输入用户名:")
pwd=raw_input("请输入密码:")
sha1=hashlib.sha1()
sha1.update(pwd)
pwd1=sha1.hexdigest()
try:
redis=RedisHelper()
if redis.get('uname')==name:
print 'ok'
else:
mysql=MysqlHelper('localhost',3306,'test1','root','mysql')
upwd=mysql.get_one('select upwd from userinfos where uname=%s',[name])
if upwd==None:
print '用户名错误'
elif upwd[0]==pwd1:
redis.set('uname', name)
print '登录成功'
else:
print "密码错误"
except Exception,e:
print e.message

猜你喜欢

转载自www.cnblogs.com/ldsice/p/11106355.html