NoSql概述

为什么要用Nosql

面对大数据,一般的数据库无法分析处理了 !!!

技术和业务在发展的同时,对人的要求也越来越高了

本质:数据库(读,写)

慢慢的就开始使用分库分表来解决写的压力!MySql在那个年代推出了表分区(并没有多少公司使用)!

MySql的集群,很好的满足了那个年代的需求

2010 ~ 2020十年之间世界已经发生了翻天覆地的变化;(定位:也是一种数据,音乐 , 热榜,浏览量~~)

MySql这种关系型数据库已经不够用了!数据量很大,变化很快~!

MySQL有人用它来存储一些很大的文件,博客,图片,数据库表很大,效率就很低了

如果有一种数据来专门处理这种数据

MySQL的压力就会变得十分小(研究如何处理这些问题!)大数据的IO压力下,表几乎没法更改(1亿数据, 加列)

目前一个基本的互联网项目!!!

为什么要用NoSQL!!!

用户的个人信息,社交网络,地理位置,用户自己产生的数据,用户的日志等等的爆发式增长!

这种时候我们就需要使用NoSQL数据库,NoSQL数据库可以很好的处理以上情况

什么是NoSQL

NoSQL = Not Only SQL(不仅仅是SQL)

关系型数据库:表格(行和列)

泛指非关系型数据库,随着Web2.0网站,互联网的诞生!传统的关系型数据库很难对付web2.0时代!尤其是超大规模的高并发社区!!!,暴露出来很多难以克服的问题。

NoSQL在当今大数据环境下发展的十分迅速,Redis是发展最快的,而且是我们当下必须要掌握的技术!!!

用户的个人信息,社交网络,地理位置,用户自己产生的数据,用户的日志等等这些类型的数据的存储不需要一个固定的格式!不需要多余的操作就可以横向扩展的!Map<String, Object> 使用键值对来控制!

NoSQL的特点

  1. 方便拓展(数据之间没有关系,很好拓展!!!)
  2. 大数据量高性能(Redis 一秒写8万次,读取11万次,NoSQL的缓存记录级,是一种细粒度的缓存,性能会比较高)
  3. 数据类型是多样型的!(不需要事先设计数据库!随取随用!如果是数据量十分大的表,很多人就无法设计了)
  4. 传统RDBMS和NoSQL

传统的 RDBMS

  • 结构化组织
  • SQL
  • 数据和关系都存在单独的表中 row column
  • 数据操作,数据定义语言
  • 严格的一致性
  • 基础的事务操作
  • …..

NoSQL

  • 不仅仅是数据
  • 没有固定的查询语言
  • 键值对存储,列存储,文档存储,图形数据库(社交关系)
  • 最终一致性
  • CAP定理 和 BASE (异地多活)
  • 高性能,高可用,高可扩展性
  • ……

了解:3V+3高

大数据时代的3V:主要是描述问题的

  • 海量Volume
  • 多样Variety
  • 实时Velocity

大数据时代的3高:主要是对程序的要求

  • 高并发
  • 高可扩(随时水平拆分,机器不够了,可以添加机器解决)
  • 高性能(保证用户体验和性能)

真正在公司中的实践:NoSQL+ RDBMS一起使用才是最强的,阿里巴巴的架构引进

技术没有高低之分,就看如何使用!(提升内功,思维的提高!)

阿里巴巴演进分析

思考问题:

  • 数据类型太多了
  • 数据源繁多,经常重构 !
  • 数据要改造,需要大面积改造 ?

NoSQL的四大分类

KV键值对

  • 新浪:Redis
  • 美团:Redis + Tair
  • 阿里,百度,美团:Redis +memacache

文档型数据库(bson和json一样)

Redis入门

查看redis进程是否开启

使用redis-server 指定的配置文件,可以根据指定的配置文件启动

使用shutdown可以关闭redis 服务器

redis-benchmark性能测试

官方自带的测试工具

测试:100个并发连接,每个并发10万请求

redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

Redis基础知识

Redis默认有16个数据库

默认使用的第0个数据库

可以使用 select 来切换数据库

DBSIZE 查看数据库大小

keys * 查看数据库所有的key

flushall 清空全部数据库

flushdb 清空当前数据库

思考为什么:redis端口号是6379

Redis 是单线程的:明白Redis是很快的,Redis是基于内存操作的,CPU不是Redis的性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程实现,就使用单线程了

EXISTS xxx 判断字段是否存在

move xxx 移除字段

EXPIRE xxx [seconds] 设置字段过期时间

ttl xxx 可以看到字段还有多久过期

type key 查看key类型

incr key

decr key

incrby key 指定增量

decrby key 指定减量

getrange key start end 获取范围值(闭区间)

getrange key 0 -1 获取全部字符串

setrange key offest xxx 相当于replace

setex 设置过期时间

setnx 不存在在设置

mset 批量设置

mget 批量获取

设置对象

数据结构是相通的

List

类似链表 每一个key对应一个链表

LPUSH : Lpush key v1 v2 ….

LRANGE: lrange key start end

RPUSH:

LPOP: LPOP key 从左边取出

RPOP

LINDEX: LIndex key 最左边为0的index

LLEN

LREM :LREM key count value 移除指定个数的value 从左边开始

LTRIM:截取一段 Ltrim key start end(0 ~ n)(最左边下标为0)

RPOPLPUSH:右出左进

LSET :替换指定key指定index的value
LINSERT: 插入指定的key的指定的value的前后

SET(集合)

set中的值是不能重复的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "kuangshen"
(integer) 1
127.0.0.1:6379> sadd myset "lovekuangshen"
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "lovekuangshen"
2) "kuangshen"
3) "hello"
127.0.0.1:6379> SISMEMBER myset hello
(integer) 1
127.0.0.1:6379> SISMEMBER myset kuang
(integer) 0
127.0.0.1:6379>
  • SADD
  • SMEMBERS
  • SISMEMBER
  • SCARD:求SIZE
  • SREM
  • SRANDMEMBER:随机取出指定个数
  • SPOP:随机删除
  • SDIFF: 求差集
  • SINTER:求交集
  • SUNION:求并集

Hash

  • HSET
  • HGET
  • HMSET
  • HMGET
  • HGETALL
  • HDEL
  • HLEN
  • HEXISTS
  • HKEYS
  • HVALS
  • HINCRBY
  • HSETNX

ZSet

  • ZADD
  • ZRANGE
  • ZRANGEBYSCORE
  • ZREM
  • ZCARD
  • ZCOUNT

Geospatial

  • GEOADD
  • GEOPOS
  • GEODIST
  • GEORADIUS
  • GEORADIUSBYMEMBER
  • GEOHASH

Hyperloglog

  • PFADD
  • PFCOUNT
  • PFMERGE

如果允许容错就可以使用这个

如果不允许容错就使用set或者自己的数据类型即可

Bitmaps

  • setbit
  • getbit
  • bitcount

事务

知其然并知其所以然,授人以渔!慢慢来会很快

首先导入依赖

1
2
3
4
5
6
7
8
9
10
11
12
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.33</version>
</dependency>

测试连接

1
2
3
4
5
6
7
8
9
10
public class testPing {
public static void main(String[] args) {
// new jedis对象即可
Jedis jedis = new Jedis("127.0.0.1",6379);
// jedis 所有的命令就是我们之前学习的所有指令!所以之前学习的指令很重要
System.out.println(jedis.ping()); // 输出PONG 连接成功


}
}

总计之前学习过的命令

String(字符串)

List(列表)

Set(集合)

Hash(散列)

ZSet(有序集合)

Geospatial(地理位置)

Hyperloglog

Bitmaps

Jedis开启事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Jedis jedis = new Jedis("127.0.0.1", 6379);

JSONObject jsonObject = new JSONObject();
jsonObject.put("name","kuangshen");
jsonObject.put("hello","world");
jedis.flushDB();
Transaction multi = jedis.multi();
String result = jsonObject.toString();

try {
multi.set("name1",result);
multi.set("name2",result);
int i = 1/0;
multi.exec();
} catch (Exception e) {
multi.discard();
throw new RuntimeException(e);
} finally {
System.out.println(jedis.get("name1"));
System.out.println(jedis.get("name2"));
jedis.close();
}