前言
1、非关系型数据库和关系型数据库区别,优势比较?
https://www.zhihu.com/question/24225007
http://blog.csdn.net/robinjwong/article/details/18502195
3、mysql和redis的一些区别
mysql和redis的一些区别。我们知道,mysql是持久化存储,存放在磁盘里面,检索的话,会涉及到一定的IO,为了解决这个瓶颈,于是出现了缓存,比如现在用的最多的 memcached(简称mc)。首先,用户访问mc,如果未命中,就去访问mysql,之后像内存和硬盘一样,把数据复制到mc一部分。
redis和mc都是缓存,并且都是驻留在内存中运行的,这大大提升了高数据量web访问的访问速度。然而mc只是提供了简单的数据结构,比如 string存储;redis却提供了大量的数据结构,比如string、list、set、hashset、sorted set这些,这使得用户方便了好多,毕竟封装了一层实用的功能,同时实现了同样的效果,当然用redis而慢慢舍弃mc。
内存和硬盘的关系,硬盘放置主体数据用于持久化存储,而内存则是当前运行的那部分数据,CPU访问内存而不是磁盘,这大大提升了运行的速度,当然这是基于程序的局部化访问原理。
推理到redis+mysql,它是内存+磁盘关系的一个映射,mysql放在磁盘,redis放在内存,这样的话,web应用每次只访问redis,如果没有找到的数据,才去访问Mysql。
然而redis+mysql和内存+磁盘的用法最好是不同的。
前者是内存数据库,数据保存在内存中,当然速度快。
后者是关系型数据库,功能强大,数据访问也就慢。
像memcache,MongoDB,Redis,都属于No sql系列。
不是一个类型的东西,应用场景也不太一样,还是要看你的需求来决定。
一般来说,写入数据是直接到mysql,读取类的是redis。 这样就说 mysql->redis的同步用的比较多。 mysql作为数据持久化和管理比redis好太多,redis大多只用来做 数据读取缓存、队列、锁、等等的使用。 持久化的话也提供了rdb、aof 保证数据的实时不丢失。 redis和mysql要根据具体业务场景去选型
mysql:数据放在磁盘
redis:数据放在内存 redis适合放一些频繁使用,比较热的数据,因为是放在内存中,读写速度都非常快,一般会应用在下面一些场景
排行榜
计数器
消息队列推送
简介和安装
redis简介:
开源高性能key-value存储;采用内存中(in-memory)数据集的方式,也可以采用磁盘存储方式(前者性能高,但数据可能丢失,后者正好相反)
支持字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等;支持对复杂数据结构的高速操作。
特性多,支持主从同步、pub/sub等
支持多种客户端(http://redis.io/clients)
安装(Windows平台):
Redis下载地址: https://github.com/dmajkic/redis/downloads
node.js客户端:node_redis https://github.com/mranney/node_redis/
redis-2.4.5-win32-win64.zip
redis运行
解压到后运行"64bit"文件夹下的redis-server.exe
报错:
提示也比较明显,没有明确的配置文件,使用的是默认配置,请使用‘redis-server /path/to/redis.conf’指定明确的配置文件
redis-server redis.conf
node_redis安装
npm install redis
或者
npm install hiredis redis
这里采用 npm install hiredis redis 安装
注:两种都可用,区别在于性能,hiredis是非阻塞的,而且速度更快;如果安装了hiredis,node_redis则会默认以它为解析器,没安装就会用纯javascript解释器.
报错:
这个报错先记下!
文件是生成成功的
redis.createClient()连接到redis服务器
本地redis直接连接服务方式:
app_createClient.js
//app_createClient.js
var redis = require("redis"),
client = redis.createClient();
client.on("ready",function(err){
if(err){
console.log("err : "+err);
}else{
console.log("redis start ");
}
})
redis start 服务启动成功
redis.createClient():返回的是一个RedisClient的对象,大家可以输出来看一下此对象的具体信息。
ready:Redis的Connection事件之一,当与redis服务器连接成功后会触发这个事件,此时表示已经准备好接收命令,当这个事件触发之前client命令会存在队列中,当一切准备就绪后按顺序调用
具体的配置链接:
app_createClient_2.js
//app_createClient_2.js
var redis = require("redis"),
RDS_PORT = 6379, //端口号
RDS_HOST = '127.0.0.1', //服务器IP
RDS_OPTS = {}, //设置项
client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);
client.on("ready",function(err){
if(err){
console.log("err : "+err);
}else{
console.log("redis start 2");
}
});
redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);
redis的默认端口:6379
认证 client.auth(password, callback)
因为redis服务器默认不需要密码,不过这不太安全,设置一下密码
打开redis.conf文件,找到requirepass,取消注释,设置密码为:tiany
连接到有密码的redis服务器
方式一:通过设置redis.createClient()的第三个参数,也就是设置项来完成
//app_createClient_3.js
var redis = require("redis"),
RDS_PORT = 6379, //端口号
RDS_HOST = '127.0.0.1', //服务器IP
RDS_PWD = 'tiany',
RDS_OPTS = {auth_pass:RDS_PWD}, //设置项 密码
client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);
client.on("ready",function(err){
if(err){
console.log("err : "+err);
}else{
console.log("redis start 2");
}
});
上图可以连接成功,通过设置连接设置项中的auth_pass来通过认证!
auth_pass:默认值为null,默认情况下客户端将不通过auth命令连接,如果设置了此项,客户端将调用auth命令连接
方式二:通过client.auth(password, callback)
//app_createClient_4.js
var redis = require("redis"),
RDS_PORT = 6379, //端口号
RDS_HOST = '127.0.0.1', //服务器IP
RDS_PWD = 'tiany',
RDS_OPTS = {}, //设置项 密码
client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);
client.auth(RDS_PWD,function function_name () {
// body...
console.log("auth 通过 ");
})
client.on("ready",function(err){
if(err){
console.log("err : "+err);
}else{
console.log("redis start 4");
}
});
单值set和get
//app_client_set_get
var redis = require("redis"),
RDS_PORT = 6379, //端口号
RDS_HOST = '127.0.0.1', //服务器IP
RDS_PWD = 'tiany',
RDS_OPTS = {}, //设置项 密码
client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);
client.auth(RDS_PWD,function function_name () {
// body...
console.log("auth 通过 ");
});
client.on("connect",function(){
client.set("author","Tiany",redis.print);
client.get("author",redis.print);
console.log("connect");
});
client.on("ready",function(err){
if(err){
console.log("err : "+err);
}else{
console.log("redis start 4");
}
});
API:
client.set(key,value,[callback]):设置单个key和value,回调函数可选
client.get(key,[callback]):得到key得到value,回调函数可选(虽然可选,但不写回调函数获取又有什么意义呢_!)
connect:Redis的Connection事件之一,在不设置client.options.no_ready_check的情况下,客户端触发connect同时它会发出ready,如果设置了client.options.no_ready_check,当这个stream被连接时会触发connect, 这时候就可以自由尝试发命令.
redis.print:简便的回调函数,测试时显示返回值(从示例的输出结果中可以看出)
其它补充说明:
client.options.no_ready_check:默认值为false,当连接到一台redis服务器时,服务器也许正在从磁盘中加载数据库,当正在加载阶段,redis服务器不会响应任何命令,node_redis会发送一个“准备确认”的INFO命令,INFO命令得到响应表示此时服务器可以提供服务,这时node_redis会触发"ready"事件,如果该设置项设置为true,则不会有这种检查
client.set([key,value],callback):与client.set(key,value,[callback]);效果一致(可以自行对上面示例源码进行修改进行测试),必须要有回调函数
多值get和set
//app_client_hash
var redis = require("redis"),
RDS_PORT = 6379, //端口号
RDS_HOST = '127.0.0.1', //服务器IP
RDS_PWD = 'tiany',
RDS_OPTS = {}, //设置项 密码
client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);
client.auth(RDS_PWD,function function_name () {
// body...
console.log("auth 通过 ");
});
client.on("connect",function(){
client.hmset('short', {'js':'javascript','C#':'C Sharp'}, redis.print);
client.hmset('short', 'SQL','Structured Query Language','HTML','HyperText Mark-up Language', redis.print);
client.hgetall("short",function(err,res){
if(err){
console.log("err :"+err);
return;
}
console.dir(res);
});
});
client.on("ready",function(err){
if(err){
console.log("err : "+err);
}else{
console.log("redis start 4");
}
});
API:
client.hmset(hash, obj, [callback]):赋值操作,第一个参数是hash名称;第二个参数是object对象,其中key1:value1。。,keyn:valuen形式;第三个参数是可选回调函数
client.hmset(hash, key1, val1, ... keyn, valn, [callback]):与上面做用一致,第2个参数到可选回调函数之前的参数都是key1, val1, ... keyn, valn形式;
client.hgetall(hash, [callback]):获取值操作,返回一个对象
其它补充说明:
console.dir():用于显示一个对象所有的属性和方法
打包执行多个命令[事务]
//app_client_multi
var redis = require("redis"),
RDS_PORT = 6379, //端口号
RDS_HOST = '127.0.0.1', //服务器IP
RDS_PWD = 'tiany',
RDS_OPTS = {}, //设置项 密码
client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);
client.auth(RDS_PWD,function function_name () {
// body...
console.log("auth 通过 ");
});
client.on("connect",function(){
var key = "lessions";
client.sadd(key,"java");
client.sadd(key,"ndoejs");
client.sadd(key,"js");
client.sadd(key,"oracle");
client.multi()
.sismember(key,"java")
.smembers(key)
.exec(function (err,replies){
console.log("Multi length :"+ replies.length);
replies.forEach(function (reply,index) {
console.log("Reply " + index + ": " + reply.toString());
// body...
});
client.quit();
});
});
client.on("ready",function(err){
if(err){
console.log("err : "+err);
}else{
console.log("redis start 4");
}
});
API:
client.multi([commands]):这个标记一个事务的开始,由Multi.exec原子性的执行;github上描述是可以理解为打包,把要执行的命令存放在队列中,redis服务器会原子性的执行所有命令,node_redis接口返回一个Multi对象
Multi.exec( callback ):执行事务内所有命令;github上描述是client.multi()返回一个Multi对象,它包含了所有命令,直到Multi.exec()被调用;
Multi.exec( callback )回调函数参数err:返回null或者Array,出错则返回对应命令序列链中发生错误的错误信息,这个数组中最后一个元素是源自exec本身的一个EXECABORT类型的错误
Multi.exec( callback )回调函数参数results:返回null或者Array,返回命令链中每个命令的返回信息
client.sadd(key,value1,...valuen,[callback]):集合操作,向集合key中添加N个元素,已存在元素的将忽略;redis2.4版本前只能添加一个值
sismember(key,value,[callback]):元素value是否存在于集合key中,存在返回1,不存在返回0
smembers(key,[callback]):返回集合 key 中的所有成员,不存在的集合key也不会报错,而是当作空集返回
client.quit():与之对应的还有一个client.end()方法,相对比较暴力;client.quit方法会接收到所有响应后发送quit命令,而client.end则是直接关闭;都是触发end事件
end:redis已建立的连接被关闭时触发
client.on('end',function(err){
console.log('end');
});
其它
http://redis.readthedocs.org/en/latest/index.html
https://github.com/mranney/node_redis/