Nosql介绍:
1> 解决传统关系型数据库在大数据量,高并发的情况下容易出现速度慢,易崩溃的问题
2> 特点:
a. 不支持sql语法,不支持事务,不保证关系数据的acid特性
b. 大部分以key-value方式存储,还有存储文档json,xml等等
c. 没有通用的语言,每种都有自己的api和语法,以及擅长的业务场景
d. 种类很多,MongoDB,Redis, HBASE Hadoop, Cassandra Hadoop
3> 优势:
a 易扩展:数据之间无关系,易拓展
b. 大数据量,高性能
c. 灵活的数据模型:无需事先为存储的数据设置类型。随时可以自定义数据格式
4> 结论:
a. Nosql数据库出现,弥补了关系型数据库的不足,极大节省开发成本
b. 取长补短,关系型适用于关系复杂的查询场景,Nosql主要用于数据存储。两者呈融合状态
Redis:
1> 特点:
a. 存储键值对的内存数据库
b. 性能极高,支持丰富的数据类型,支持string,list,set,hash,ordered set等
c. 丰富的特性,支持master-slave模式数据备份,支持key过期,原子性操作,通知,publish/subpublish等
d. 支持数据持久化,可以将内存的数据存储在磁盘中,重启时调用
2> 应用场景:
a. 用来做缓存,所有数据存放于内存中
c. 网站的特定功能,如session,历史记录,购物车详情页等
3> 点击中文官网查看命令文档 http://redis.cn/commands.html
string 类型:
1> redis最基本类型,最大能存储512MB,二进制安全,可以存储任何数据,包括数字图片等
2> 命令:
a. 增、改:set, mset
>>> set name itcast
>>> mset age 20 sex 0
>>> get name
>>> mget name sex age
b. 追加:append
>>> append name itheima
(integer) 13
>>> get name
‘itcastitheima’
c. 删除: del
>>> keys *
1) "sex"
2) “age"
3) “name"
2) “age"
3) “name"
>>> del sex name
(integer) 2
键命令:
a. 查找键:keys
>>> keys *
>>> mset age 20 salary 10000
>>> keys a*
1) “age”
>>> keys *e
1) “age"
2) “bame”
b. 判断是否存在:exists
>>> exists name age
(integer) 2
>>> get sex
(nil)
c. 查看类型: type
>>> type age
string
d. 设置有效期: setex, expire,ttl(-1 -2 +)
>>> setex sex 10 0
>>> ttl sex
(integer) 5
>>> ttl sex
(integer) -2 # 表示已经删除
>>> ttl name
(integer) -1 # 表示永久
>>> expire name 10 # 修改有效期
list 类型:
1> 列表类型必须为string,即不能嵌套列表,按照插入顺序排序
2> 命令:
a. 增:lpush, rpush, linsert … before/after
>>> lpush key val1 val2 # 左侧插入
>>> rpush key val1 val2 # 右侧插入
>>> linsert key before/after exist_val insert_val
b. 查:lrange s_val end_val # 左闭右闭
>>> lpush mylist a b c
>>> lrange mylist 0 -1 # 取出所有元素
1) "c"
2) "b"
3) "a"
2) "b"
3) "a"
c. 改:lset
>>> lset mylist 1 11
1) "c"
2) “11"
3) "a”
2) “11"
3) "a”
d. 删:del, lrem(0 + -)
>>> lrem mylist -2 a
>>> lrem mylist 0 a
>>> del mylist
无序集合集合:唯一性
1> 命令:
a. 增:sadd
>>> sadd myset a b c b
1) “b"
2) "a"
3) “c"
2) "a"
3) “c"
b. 查:smembers
>>> smembers myset
c. 删:del srem
>>> srem myset a
有序集合:
1> 唯一性,关联一个double类型的score,代表权重,没有修改操作
2> 命令:
a. 增:zadd
>>> zadd myzset 100 a 90 b 80 c
b. 查: zrange(升序), zrevrange, zrangebyscore
>>> zrange myzset 0 -1
>>> zrangebyscore myzset 90 100 # min max
c. 删:zrem, zremrangebyscore
hash 类型:
1> 用于存储对象,对象结构为属性、值,值得类型为string
2> 命令:
a. 增:hset,hmset
>>> hset user_1 name jack
>>> hmset user_1 salary 1000 age 10
b. 查:hget, hmget
>>> hmget user_1 name salary age
c. 删:hdel
>>> hdel user_1 name
d. 查询所有:hlen, hvals, hkeys
>>> hkeys user_1
其他命令:
flushdb # 清空当前你数据库
flushall # 清空所有数据库
与python进行交互:主要是StrictRedis对象
1> 安装: pip install redis
2> 增删改查:
from redis import StrictRedis
if __name__ == '__main__':
try:
# create StrictRedis obj
# strict_redis = StrictRedis(host='127.0.0.1', port=6379, db=0)
# decode_response: bit -> string
strict_redis = StrictRedis(decode_responses=True)
# add, alter
strict_redis.set('name', 'redix')
strict_redis.set('age', 20)
# search
name = strict_redis.get('name')
age = strict_redis.get('age')
print(name, age)
# del
strict_redis.delete('name')
my_keys = strict_redis.keys()
print(my_keys, type(my_keys))
except Exception as e:
print(e)
Django与redis交互: 存储session
1> 安装: pip install django-redis-sessions==0.5.6
2> 修改settings.py:
# 使用redis保存session数据
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 4
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session’ # 保存在数据库字段的前缀session:
3> 配置url: url(r'^set_session$', views.set_session), # 保存session数据
url(r'^get_session$', views.get_session), # 获取session数据
4> 配置views:
def set_session(request):
""""保存session数据"""
request.session['username'] = 'Django'
request.session['verify_code'] = '123456'
return HttpResponse('保存session数据成功')
def get_session(request):
"""获取session数据"""
username = request.session.get('username')
verify_code = request.session.get('verify_code')
text = 'username=%s, verify_code=%s' % (username, verify_code)
return HttpResponse(text)
5> redis-cli查看:
>>> keys *
>>> get session_key
# redis分布式锁:
# getset 如果会返回设置新的过期时间结果,如果和get返回的不同,则已经有其他客户端占用。
# coding=utf-8 import time import redis LOCK_TIMEOUT = 3 lock = 0 lock_timeout = 0 lock_key = 'lock.foo' redis_client = redis.StrictRedis(host='', port=6379, db=0) # 获取锁 while lock != 1: now = int(time.time()) lock_timeout = now + LOCK_TIMEOUT + 1 lock = redis_client.setnx(lock_key, lock_timeout) if lock == 1 or (now > int(redis_client.get(lock_key))) and now > int(redis_client.getset(lock_key, lock_timeout)): break else: time.sleep(0.001) # 已获得锁 # do job # 释放锁 now = int(time.time()) if now < lock_timeout: redis_client.delete(lock_key)