- NoSQL简介
NoSQL是Not Only SQL的缩写。它的意义是:适用关系型数据库的时候就使用关系型数据库,不适用的时候考虑使用更加合适的数据存储。
-
不需要预定义模式:不需要事先定义数据模式,预定义表结构。数据中的每条记录都可能有不同的属性和格式。当插入数据时,并不需要预先定义它们的模式。
-
无共享架构:相对于将所有数据存储的存储区域网络中的全共享架构。NoSQL往往将数据划分后存储在各个本地服务器上。因为从本地磁盘读取数据的性能往往好于通过网络传输读取数据的性能,从而提高了系统的性能。
-
弹性可扩展:可以在系统运行的时候,动态增加或者删除结点。不需要停机维护,数据可以自动迁移。
-
分区:相对于将数据存放于同一个节点,NoSQL数据库需要将数据进行分区,将记录分散在多个节点上面。并且通常分区的同时还要做复制。这样既提高了并行性能,又能保证没有单点失效的问题。
-
异步复制:和RAID存储系统不同的是,NoSQL中的复制,往往是基于日志的异步复制。这样,数据就可以尽快地写入一个节点,而不会被网络传输引起迟延。缺点是并不总是能保证一致性,这样的方式在出现故障的时候,可能会丢失少量的数据。
-
BASE:相对于事务严格的ACID特性,NoSQL数据库保证的是BASE特性。BASE是最终一致性和软事务。
- NoSQL数据库的4大分类
分类 | Examples举例 | 典型应用场景 | 数据模型 | 优点 | 缺点 |
---|---|---|---|---|---|
键值(key-value) | Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB | 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。 | Key 指向 Value 的键值对,通常用hash table来实现 | 查找速度快 | 数据无结构化,通常只被当作字符串或者二进制数据 |
列存储数据库 | Cassandra, HBase, Riak | 分布式的文件系统 | 以列簇式存储,将同一列数据存在一起 | 查找速度快,可扩展性强,更容易进行分布式扩展 | 功能相对局限 |
文档型数据库 | CouchDB, MongoDb | Web应用(与Key-Value类似,Value是结构化的,不同的是数据库能够了解Value的内容) | Key-Value对应的键值对,Value为结构化数据 | 数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构 | 查询性能不高,而且缺乏统一的查询语法。 |
图形(Graph)数据库 | Neo4J, InfoGrid, Infinite Graph | 社交网络,推荐系统等。专注于构建关系图谱 | 图结构 | 利用图结构相关算法。比如最短路径寻址,N度关系查找等 | 很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案。 |
- Redis简介
Redis (REmote DIctionary Server) 是一个key-value存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
与memcached一样,为保证效率,数据都缓存在内存中。区别是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并在此基础上实现了master-slave(主从)同步。
- 安装redis
一般安装在linux中,具体步骤如下:
#cd usr/local/src
#wget http://download.redis.io/releases/redis-3.0.1.tar.gz
#tar xzf redis-3.0.1.tar.gz
#cd redis-3.0.1
#make
#src/redis-server &
或者在其配置文件中把demon改成yes
检查redis是否启动成功
ps -ef | grep redis
netstat -lnp |grep 6379
- python连接redis服务器
Redis 命令用于在 redis 服务上执行操作。
要在 redis 服务上执行命令需要一个 redis 客户端。Redis 客户端在我们之前下载的的 redis 的安装包中。
安装python语言的客户端: pip install redis
python中连接redis服务器
1 import redis 2 3 r = redis.Redis(host="192.168.2.1", port=6379) 4 r.set("name", "This is the value!") 5 print(r.get("name"))
- redis连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立和释放连接的开销。默认,每个Redis实例都会维护一个自己的连接。可以直接建立一个连接池,然后作为redis参数,这样就可以实现多个redis实例共享一个连接池
1 import redis 2 3 pool = redis.ConnectionPool(host="192.168.2.1") 4 r = redis.Redis(connection_pool=pool) 5 r.set("name", "My name is Karl!") 6 print(r.get("name"))
- python操作redis
string操作:
set(name, value, ex=None, px=None, nx=False, xx=False)
ex, 过期时间(秒)
px, 过期时间(毫秒)
nx, 若为True,则只有name不存在时,set操作才执行
xx, 若为True,则只有name存在时,set操作才执行
get(name) 获取值
mset(name1="Karl") 批量设置值,()为dict类型
mget("name1", "name2") 批量获取key的值,()为tuple类型
append(name, value) 追加
list操作:
redis中存储list类型的数据是在内存中,一个name对应一个list
lpush(name, value) 左边追加
rpush(name, value) 右边追加
llen(name) name对应的list元素的个数
linsert(name, where, refvalue, value)
name 对应的key
where AFTER、BEFORE
refvalue list中的某个元素
value 要插入的值
lset(name, index, value) 对name对应的list中的某一个索引位置重新赋值
lrem(name, value, num) 在name对应的list中删除指定的值
num=0 删除列表中所有的指定值
num=2 从前到后,删除2个
num=-2 从后向前,删除2个
lpop(name) name对应的list中移除左边第一个元素,并将其作为返回值
rpop(name) name对应的list中移除右边第一个元素,并将其作为返回值
lindex(name, index) 在name对应的列表中根据索引获取列表元素
lrange(name, start, end) 在name对应的列表分片获取数据