1.缓存数据库介绍
NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
NoSQL数据库的四大分类
1.键值(Key-Value)存储数据库
这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。[3] 举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.
2.列存储数据库
这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
3.文档型数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
4.图形(Graph)数据库
图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。[2] 如:Neo4J, InfoGrid, Infinite Graph.
因此,我们总结NoSQL数据库在以下的这几种情况下比较适用:1、数据模型比较简单;2、需要灵活性更强的IT系统;3、对数据库性能要求较高;4、不需要高度的数据一致性;5、对于给定key,比较容易映射复杂值的环境。
2.redis
介绍
redis是业界主流的key-value nosql 数据库之一。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis优点
异常快速 : Redis是非常快的,每秒可以执行大约110000设置操作,81000个/每秒的读取操作。
支持丰富的数据类型 : Redis支持最大多数开发人员已经知道如列表,集合,可排序集合,哈希等数据类型。
这使得在应用中很容易解决的各种问题,因为我们知道哪些问题处理使用哪种数据类型更好解决。
操作都是原子的 : 所有 Redis 的操作都是原子,从而确保当两个客户同时访问 Redis 服务器得到的是更新后的值(最新值)。
MultiUtility工具:Redis是一个多功能实用工具,可以在很多如:缓存,消息传递队列中使用(Redis原生支持发布/订阅),在应用程序中,如:Web应用程序会话,网站页面点击数等任何短暂的数据;
安装Redis环境
Download, extract and compile Redis with:
$ wget http://download.redis.io/releases/redis-6.0.6.tar.gz
$ tar xzf redis-6.0.6.tar.gz
$ cd redis-6.0.6
$ make
The binaries that are now compiled are available in the src directory. Run Redis with:
$ src/redis-server
You can interact with Redis using the built-in client:
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
Python操作Redis
pip3 install redis
在Ubuntu上安装Redis桌面管理器
要在Ubuntu 上安装 Redis桌面管理,可以从 http://redisdesktop.com/download 下载包并安装它。Redis 桌面管理器会给你用户界面来管理 Redis 键和数据。
redis后台启动
打开redis.conf文件,将把daemonize设置为yes,启动redis。
3.Redis API使用
redis-py 的API的使用可以分类为:
-
连接方式
-
操作
String 操作
Hash 操作
List 操作
Set 操作
Sort Set 操作 -
管道
-
发布订阅
连接方式
1 、操作模式
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
import redis
re = redis.Redis(host='127.0.0.1',port=6379)
re.set('foo','bar')
print(re.get('foo'))
2、连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
import redis
pool = redis.ConnectionPool(host='127.0.0.1',port=6379)
re = redis.Redis(connection_pool=pool)
re.set('n',3)
print(re.get('n'))
操作
1. String操作
redis中的String在在内存中按照一个name对应一个value来存储。如图:
set(name, value, ex=None, px=None, nx=False, xx=False)
#在Redis中设置值,默认,不存在则创建,存在则修改
#参数:
#ex,过期时间(秒)
#px,过期时间(毫秒)
#nx,如果设置为True,则只有name不存在时,当前set操作才执行
#xx,如果设置为True,则只有name存在时,岗前set操作才执行
SET key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL]
summary: Set the string value of a key
since: 1.0.0
group: string
#在Redis中设置值,默认,不存在则创建,存在则修改
#参数:
#ex,过期时间(秒)
#px,过期时间(毫秒)
#nx,如果设置为True,则只有name不存在时,当前set操作才执行
#xx,如果设置为True,则只有name存在时,岗前set操作才执行
setnx(name, value)
#设置值,只有name不存在时,执行设置操作(添加)
SETNX key value
summary: Set the value of a key, only if the key does not exist
since: 1.0.0
group: string
#设置值,只有key不存在时,执行设置操作(添加)
setex(name, value, time)
# 设置值
# 参数:
# time,过期时间(数字秒 或 timedelta对象)
SETEX key seconds value
summary: Set the value and expiration of a key
since: 2.0.0
group: string
# 参数:
# seconds,过期时间(数字秒 或 timedelta对象)
psetex(name, time_ms, value)
# 设置值
# 参数:
# time_ms,过期时间(数字毫秒 或 timedelta对象
PSETEX key milliseconds value
summary: Set the value and expiration in milliseconds of a key
since: 2.6.0
group: string
mset(*args, **kwargs)
#批量设置值
#如:
#mset(k1='v1', k2='v2')
#或
3mget({
'k1': 'v1', 'k2': 'v2'})
MSET key value [key value ...]
summary: Set multiple keys to multiple values
since: 1.0.1
group: string
#mset a2 2 a3 3
get(name)
#获取值
GET key
summary: Get the value of a key
since: 1.0.0
group: string
mget(keys, *args)
# 批量获取
# 如:
# mget('ylr', 'wupeiqi')
# 或
# r.mget(['ylr', 'wupeiqi'])
MGET key [key ...]
summary: Get the values of all the given keys
since: 1.0.0
group: string
#mget a2 a3
getset(name, value)
#设置新值并获取原来的值
GETSET key value
summary: Set the string value of a key and return its old value
since: 1.0.0
group: string
#127.0.0.1:6379> get a1
#"1"
#127.0.0.1:6379> getset a1 a1
#"1"
#127.0.0.1:6379> get a1
#"a1"
getrange(key, start, end)
# 获取子序列(根据字节获取,非字符)
# 参数:
# name,Redis 的 name
# start,起始位置(字节)
# end,结束位置(字节)
# 如: "牛栏山" ,0-3表示 "牛"
GETRANGE key start end
summary: Get a substring of the string stored at a key
since: 2.4.0
group: string
#127.0.0.1:6379> get a
#"0123456"
#127.0.0.1:6379> getrange a 1 3
#"123"
setrange(name, offset, value)
# 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
# 参数:
# offset,字符串的索引,字节(一个汉字三个字节)
# value,要设置的值
SETRANGE key offset value
summary: Overwrite part of a string at key starting at the specified offset
since: 2.2.0
group: string
#127.0.0.1:6379> get a
#"0123456"
#127.0.0.1:6379> getrange a 1 3
#"123"
#127.0.0.1:6379> setrange a 3 abc
#(integer) 7
#127.0.0.1:6379> get a
#"012abc6"
setbit(name, offset, value)
# 对name对应值的二进制表示的位进行操作
# 参数:
# name,redis的name
# offset,位的索引(将值变换成二进制后再进行索引)
# value,值只能是 1 或 0
# 注:如果在Redis中有一个对应: n1 = "foo",
#那么字符串foo的二进制表示为:01100110 01101111 01101111
#所以,如果执行 setbit('n1', 7, 1),则就会将第7位设置为1,
#那么最终二进制则变成 01100111 01101111