数据库

数据库

Mysql数据库

Mysql语句

  1. SQL: Structure Query Language:结构化查询语言
    • DDL:数据定义语言:定义数据库,数据表他们的结构:create(创建) drop(删除) alert(修改)
    • DML:数据操纵语言:主要用来操作数据 insert(插入) update(修改)delete(删除)
    • DCL:数据控制语言:定义访问权限,取消访问权限,安全设置 grant
    • DQL:数据查询语言:select(查询) from子句 where子句

数据备份和恢复

通过cmd命令进入dos窗口:

导出: mysqldump -u账户 -p密码 数据库名称 > 脚本文件存储地址

导入:mysql -u账户 -p密码 数据库名称 < 脚本文件存储地址

数据库的CRUD操作

  • 创建数据库

    • create database 数据库的名字

    • create database character set 字符集

    • create database 数据库的名字 character set 字符集 collate 校对规则

      create database test character set utf8 collate utf8-bin

  • 查看数据库

    • 查看数据库定义的语句:
      • show create database 数据库的名字
        • 查看所有的数据库:
        • show databases
  • 修改数据库的操作

    • 修改数据库的字符集

      • alter database 数据库的名字 character set 字符集

        alter database test character set gbk

  • 删除数据库

    • drop database 数据库的名字

      drop database test

  • 其他的数据库操作命令

    • 选中数据库

      • user 数据库的名字

        use test

      • 查看当前正在使用的数据库

        select database()

表的CRUD操作

  • 创建表

    • create table 表名{

      ​ 列名 列的类型 约束

      ​ 列名 列的类型 约束

      };

    • 列的类型

      | Java | Sql | Explain |
      | :———: | :———-: | :——————————————————: |
      | int | int | |
      | char/string | char/varchar | char:固定长度,char(3)代表了字符的个数 varchar:可变的长度 |
      | double | double | |
      | float | float | |
      | boolean | boolean | |
      | | data | YYYY-MM-DD |
      | | time | HH:mm:ss |
      | | datatime | YYYY-MM-DD HH:mm:ss (默认null) |
      | | timestamp | YYYY-MM-DD HH:mm:ss (用于不同时区,默认使用当前时间) |
      | | text | 主要用来存放文本 |
      | | blob | 存放的是二进制 |

    • 列的约束

      主键约束: primary key

      唯一约束: unique

      非空约束: not null

      默认值约束: DEFAULT:使用形式为:DEFAULT 常量

      限制列的取值范围: CHECK:使用形式为:CHECK(约束表达式)

      外键约束: 使用形式为:【FOREIGN KEY(<列名>)】REFERENCES<外表名>(<外表列名>)

    • 例子

      1
      2
      3
      4
      5
      6
        create table student(
      Sid int primary key,
      Sname varchar(31),
      Sex int,
      Age int
      );
  • 查看表

    • 查看所有的表

      show tables;

    • 查看表的创建过程

      show create table student

    • 查看表的结构

      desc student

  • 修改表

    • 添加列(add)

      • alter table 表明 add 列名 列的类型 列的约束

        alter table student add chengji int not null;

    • 修改列(modify)

      • alter table student modify sex varchar(2);
    • 修改列名(change)

      • alter table student change sex gender varchar(2);
    • 删除列(drop)

      • alter table student drop chengji1;
    • 修改列名(rename)

      • rename table student to newname;
    • 修改表的字符集

      • alter table student character set utf8;
    • 修改存储引擎:修改为myisam

      • alter table tableName engine=myisam;
    • 删除外键约束:keyName是外键别名

      • alter table tableName drop foreign key keyName;
    • 创建索引

      • CREATE INDEX indexName ON mytable(username(length));
      • ALTER TABLEtable_nameADD INDEX index_name (column1,column2,column3);
    • 使用sql语句创建唯一索引,格式如下:

      • create unique index 索引名 on 表名(列名1,列名2……);
  • 删除表:

    • Drop table student

表中数据的CRUD操作

  • 插入数据

    • insert into 表名(列名1,列名2,列名3) values(值1,值2,值3);

      insert into student (sid,sname,sex,age,chengji) values("1","zhangsan",1,23,80);

    • 可以简写为:

      insert into student values(3,"wangwu",1,24,81),(4,"zhaoliu",1,25,82)

    • 但是如果要设置某些项目为空的话,则必须写明列名

      insert into student (sid,sname,chengji) values(2,"lisi",80);

  • 批量插入

    • insert into student values(3,"wangwu",1,24,81),(4,"zhaoliu",1,25,82)
  • 删除记录

    • delete from 表名 [where 条件]

      delete from student where sid = 0

    • delete from student;如果没有指定条件,则会删除表中所有的数据

    • truncate:DDL语言,先删除表,再重新建立表,当表中数据量较大时,若想删除全部,则使用truncate效率很高

  • 更新记录:

    • update 表名 set 列名1 = 列的值,列名2 = 列的值[where条件];

      • 将id = 1的sname改成zhangsan
      • 如果参数为字符串,日期,要加上单引号
      • 不加where条件,则会修改所有的表列

      update student set sname = "zhangsan" where sid = 1;

  • 查询记录:

    • Seletc [distinct] [*] [列名1,列名2] from 表名 [where 条件]group by having order by

      Distinct :去重复的数据

      Select: 选择显示哪些列的内容

      查看表中的所有数据:

      select * from student;

      select cname,cdesc from category;

    • 别名查询(as关键字可以省略)

      • 表别名:

        • select p.pname,p.price from product;
        • select p.pname,p.price from product as p
      • 列别名:

        • select pname as 商品名称,price as 商品价格 from product;
        • select pname 商品名称,price 商品价格 from product
      • 去掉重复的值:

        • 查询商品的价格

          select price form product

          select distinct price from product

        • 查询运算,仅仅在查询结果上做了运算

          select * ,price*0.5 from product

          select *,price*0.5 as 折后价 from product

    • 条件查询(where关键字)

      • 指定条件,确定要查询的记录

      • select * from product where price > 60;

      • where后的条件写法:

        • <>:不等于 ,标准的sql语法

        • !=:不等于 ,非标准的sql语法

    
1
2
3
4
5
Select * from product where price > 10 and price < 100;

Select * from product where between 10 and 100;

Select * from product where price < 10 or price > 999;
+ like 模糊查询 + %:代表的是多个字符 + `select * from product where name like "%饼%"; ` (查询名字中带饼字的所有商品) + _:代表的是一个字符 + `select * from product where pname like "_饼%;" ` (查询名字中第二个字是饼字的所有商品) + in:在某个范围内中获取值 + `select * from product where cno in (1,4,5);` (查询出商品分类ID在1,4,5里面的所有商品)
  • 排序查询(order by)

    • asc:ascend 升序(默认的排序方式)

    • desc:descend 降序

      • 查询所有商品,按照价格排序

        select * from product order by price;

      • 查询所有商品,按照价格进行降序排列

        select * from product order by price desc;

      • 查询所有名称里面带小的商品的按照价格升序排列

        select * from product where name like "%小% order by price asc;"

  • 聚合函数:

    • sum():求和

    • avg():求平均值

    • count():统计数量

    • max():最大值

    • min():最小值

    • 获得所有商品价格的总和

      select sum(price) from product;

    • 获得所有商品的个数

      select count (*) from product;

    • 查出商品价格大于平均价格的所有商品:

      select * from product where price >(select avg(price) from product);

  • 分组查询(group by)

  • 过滤筛选:having关键字:可以连接聚合函数,出现在分组之后,条件筛选(根据结果集做筛选)

  • where关键字:不可以连接聚合函数,出现在分组之前,表示从全部数据中筛选出部分的数据

    • 根据cno字段分组,分组后统计商品的个数

      select cno,count(*) from product group by cno;

    • 根据cno分组,分组统计每组商品的平均价格并且商品的平均价格大于>60

      select cno,avg(price) from product group by cno having(price)>60;

  • 编写顺序:s…f…w…g…h…o(select from where group by having order by)

  • 执行顺序:f…w…g…h…s…o(from where group by having select order by)

表间操作

  • 添加外键约束:

    • foreign key

    • Alter table product add foreign key(cno) references category(cid);

      删除的时候先删除与外键关联的所有数据,才能删除分类的数据

      建立数据库的原则:

      通常情况下,一个项目/应用建立一个数据库

  • 多表之间的建表原则:

    一对多: 商品分类

    • 建表原则:在多的一方添加一个外键指向1的1方的主键。

      多对多:老师和学生,学生和课程

    • 建表原则:建立一张中间表,将多对多的关系转化为一对多的关系。中间表至少要有两个外键,这两个主键分别指向原来的那两张表。

      一对一:公民和身份证;

    • 建表原则:

    1. 将一对一的情况,当作是一对多的情况处理,在任意一张表中添加一个外键,并且这个外键要唯一指向另一张表。
    2. 将两张表的合成一张表
    3. 将两张表的主键建立起连接,让两张表里面的主键相等
      • 实际用途:做拆表操作的时候
  • 主键约束:默认就是不能为空,表内内容还必须唯一。外键都是指向另一张表的主键。

  • 唯一约束:列里面的内容必须唯一,不能出现重复的情况,但可以为空。可以有多个唯一约束。

多表查询

inner和outer可以省略

  • 交叉连接查询:

    • select * from 表1 ,表二;
  • 过滤出有意义的数据:

    • select * from 表一,表二 where 条件;
  • 内连接查询:查询两张表的笛卡尔积

    • 隐式内连接:
      • select * from 表1 别名1,表2 别名2 where 别名1.列名 = 别名2.列名;
    • 显式内连接:
      • select * from 表1 别名1 inner join 表2 别名2 on 别名1.列名 = 别名2.列名;
    • 隐式内连接: 在查询出的结果的基础上做where条件的过滤
    • 显式内连接:直接带着条件去查询,执行效率高
  • 左外连接:

    • select * from 表1 别名1 left outer join 表2 别名2 on 别名1.列名=别名2.列名 ;
    • 左外连接会将左表中的数据都查询出来,如果右表中没有对应的数据,则用null代替
  • 右外连接:

    • select * from 表1 别名1 right outer join 表2 别名2 on 别名1.列名=别名2.列名
    • 右外连接会将右表数据全部查询出来,如果左表没有对应的数据,则用null代替
  • 分页查询:

    • 将查询的结果分页,显示从几开始的几个数据

      select * from product limit 1,10; (从商品表中查询所有的数据,显示从索引0,开始的十条数据)

子查询

  • 查询分类名称为手机数码的所有商品:

    select * from product where cno = (select cid from category where cname = '手机数码');

  • 查询出(商品名称,商品分类名称)信息

    • 左连接

      select p.pname,c.cname from product p left outer join category c on p.cno = c.cid;

    • 子查询

      select pname ,(select cname from category c where p.cno = c.cid) from product p;

事务

  • 概念
    代码里面的事务主要是针对连接来的,是用来防止当出现异常时对数据库的增删改操作只完成了一般,另一半未做,造成数据的错误。关闭自动提交后,当出现异常时,已完成的一般也会被恢复。

  • 设置方法

    1. 通过conn.setAutocommit (false);来关闭自动提交的设置。
    2. 提交事务 conn.commit()。
    3. 回滚事务 conn.rollback(); 在catch中写明当出现问题时回滚。
  • 事务的特性
    事务的特性:(ACID)

    1. 原子性:

      指的是事务中包含的逻辑不可分割。

    2. 一致性:

      指的是事务执行前后,数据的完整性保持一致。

    3. 隔离性:

      指的是事务在执行期间不应该受到其他事务的影响。

    4. 持久性:

      指的是事务执行成功,那么数据应该持久保持在磁盘上。

  • 事务的安全隐患

    不考虑隔离级别设置,那么会出现以下问题
    读:

    1. 脏读,不可重复读,幻读

      脏读:一个事务读到了另一个事物还未提交的数据。 隔离级别为:读未提交

      不可重复读:一个事务可以读到另一个事务提交的数据(产生两次读出不一样的问题)。

      幻读:一个事务读到了另一个事务已提交的插入的数据,导致多次查询结果不一样。

      隔离级别:读已提交,一个事务只能读取到另一个事务提交了的数据

      隔离级别:可重复读,即使一个事务已提交数据的更改,但在另一个事务里数据仍不会变化,这是为了让事务与事务之间不产生相对影响。但是还是会产生幻读问题

      隔离级别:可串行化:最高达隔离级别.当一个事务要操作一个表时,必须得等之前的事务提交了数据或者回滚了才能执行,否则会等待。

    可重复读是为了保证在一个事务中,相同查询条件下读取的数据值不发生改变,但是不能保证下次同样条件查询,结果记录数不会增加。

可串行化就是为了解决这个问题而存在的,他将这个查询范围都加锁了,所以就不能再往这个范围内插入数据,这就是SERIALIZABLE 隔离级别做的事情。

  1. 丢失更新:
    如果a和b事务都对同一个表进行了操作,那么第二次对数据的更新可能会导致第一次更新丢失。
解决方法:  
>悲观锁:可以在查询的时候给查询语句后面加上 for update (数据库的锁机制: 排他锁)  

>乐观锁:需要程序员自己控制,自己写代码比对,先前的事务有没有对数据进行更新,如果更新了,要重新查询。

数据库连接池

  • 数据库的连接对象创建工作比较耗费性能。

    一开始就在内存中开辟一块空间(集合),一开始先往池子里面放置多个连接对象,后面需要连接的话直接从池子里面去取,不要自己创建连接了,使用完毕,要记得归还连接,确保连接对象能够循环利用。

    1. DBCP:数据库连接池,通过数据库连接池,可以让程序自动管理数据库的释放和断开。
  1. C3P0:数据库连接池,实现了数据源和JNDI绑定,目前大量使用。
    1. Druid:Java语言中最好的数据库连接池,由阿里巴巴团队开发。Druid能够提供强大的监控扩展功能。
  • DBCP怎么使用:

    1. 导入jar文件

    2. 使用属性配置文件(指定使用哪个类型的数据库,使用哪个数据库,用户名和密码分别是多少)。

    3. 其余操作和之前相同(创建conn对象,创建prepareStatement对象,写sql语句,执行操作,释放连接(DBCP包装后的close方法))

  • C3P0怎么使用:

    1. 导入jar文件

    2. 导入属性配置文件

    3. 直接创建conn对象,使用,不需要用文件流导入配置文件了。

  • Commons DbUtils :是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序开发,同时也不会影响程序的性能。

    定义了通用的crud方法。

    • queryRunner.update();

    • queryRunner.query();

    查询时需要用到 ResultSetHandler

    ResultSetHandler 常用的实现类:

    BeanHandler 查询到的数据封装成一个对象

    BeanListHandler 查询到的多个数据封装成一个List<对象>

    ArrayHandler, 查询到的单个数据封装成一个数组

    ArrayListHandler 查询到的多个数据封装成一个集合,集合里面是数组

    MapHandler,查询到的单个数据封装成一个map

    MapListHandler 查询到的多个数据封装成一个集合,集合里面的元素是map

ColumnListHandler,

KeyedHandler,

ScalarHandler

MySQL数据库引擎

myisam:读取速度比较快,不占用大批量资源,但是又两个缺点,1、不支持事物,2、容错不好。硬盘崩溃了,数据就没了,如果说坚持要用在那个关键程序,要通过其复制特性实时的去备份数据,,MySQL能够支持这样的备份应用程序。MyISAM类型的二进制数据文件可以在不同操作系统中迁移。也就是可以直接从Windows系统拷贝到linux系统中使用。

Innodb:支持事务,外键,行锁它提供了事务控制能力功能,它确保一组命令全部执行成功,或者当任何一个命令出现错误时所有命令的结果都被回退,在电子银行中事务控制能力是非常重要的。支持COMMIT、ROLLBACK和其他事务特性。目前数据库表结构设计的时候一般都选择这种存储引擎。但是速度慢,占用磁盘空间比较多。

MyISAM和InnoDB的区别:

  1. 存储结构

    1. MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件:名字以表的名字开始,扩展名指出文件类型.frm文件存储表定义(结构文件)。第二个文件:数据文件的扩展名为.MYD (MYData)。第三个文件:索引文件的扩展名是.MYI (MYIndex)。
    2. InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。
  2. 存储空间

    1. MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。
    2. InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。
  3. 可移植性,备份和恢复

    1. MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
    2. InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。
  4. 事务支持

    1. MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
    2. InnoDB:提供事务,支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
  5. AUTO_INCREMENT
    1. MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
    2. InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。
  6. 表锁差异
    1. MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
    2. InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的性能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。
  7. 全文索引
    1. MyISAM:支持 FULLTEXT类型的全文索引
    2. InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。
  8. 表主键
    1. MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。非聚集索引
    2. InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。聚集索引
  9. 表的具体行数
    1. MyISAM:保存有表的总行数,如果select count(*) from table;会直接取出出该值。
    2. InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。
  10. CRUD操作
    1. MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
    2. InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。
  11. 外键
    1. MyISAM:不支持
    2. InnoDB:支持

通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、存储 过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。

存储引擎选择的基本原则

采用MyISAM引擎

  • R/W > 100:1 且update相对较少
  • 并发不高
  • 表数据量小
  • 硬件资源有限

采用InnoDB引擎

  • R/W比较小,频繁更新大字段
  • 表数据量超过1000万,并发高
  • 安全性和可用性要求高

采用Memory引擎

  • 有足够的内存
  • 对数据一致性要求不高,如在线人数和session等应用
  • 需要定期归档数据

Mysql索引

B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于

走右结点;

B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键

字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;

B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点

中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;

B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率

从1/2提高到2/3;

红黑树:红黑树(Red-Black Tree)是二叉搜索树(Binary Search Tree)的一种改进。我们知道二叉搜索树在最坏的情况下可能会变成一个链表(当所有节点按从小到大的顺序依次插入后)。而红黑树在每一次插入或删除节点之后都会花O(log N)的时间来对树的结构作修改,以保持树的平衡。也就是说,红黑树的查找方法与二叉搜索树完全一样;插入和删除节点的的方法前半部分节与二叉搜索树完全一样,而后半部分添加了一些修改树的结构的操作。红黑树的每个节点上的属性除了有一个key、3个指针:parent、lchild、rchild以外,还多了一个属性:color。它只能是两种颜色:红或黑。而红黑树除了具有二叉搜索树的所有性质之外,还具有以下4点性质:

  1. 根节点是黑色的。
  2. 空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的空节点)。
  3. 红色节点的父、左子、右子节点都是黑色。
  4. 在任何一棵子树中,每一条从根节点向下走到空节点的路径上包含的黑色节点数量都相同。

Redis数据库

概念

  • redis是一款高性能的NOSQL系列的非关系型数据库
  • NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。
  • 随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
  • NOSQL和关系型数据库的比较

    • 优点:

      1. 成本:nosql数据库简单易部署,基本都是开源软件,不需要像使用oracle那样花费大量成本购买使用,相比关系型数据库价格便宜。
      2. 查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及nosql数据库。
      3. 存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。
      4. 扩展性:关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。
    • 缺点:

      1. 维护的工具和资料有限,因为nosql是属于新的技术,不能和关系型数据库10几年的技术同日而语。
      2. 不提供对sql的支持,如果不支持sql这样的工业标准,将产生一定用户的学习和使用成本。
      3. 一部分不提供关系型数据库对事务的处理。
  • Redis概念
    • Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
      1. 字符串类型 string
      2. 哈希类型 hash
      3. 列表类型 list
      4. 集合类型 set
      5. 有序集合类型 sortedset
    • redis的应用场景:
      • 缓存(数据查询、短连接、新闻内容、商品内容等等)
      • 聊天室的在线好友列表
      • 任务队列。(秒杀、抢购、12306等等)
      • 应用排行榜
      • 网站访问统计
      • 数据过期处理(可以精确到毫秒
      • 分布式集群架构中的session分离

命令操作

  1. redis的数据结构:

    • redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构
      • value的数据结构:
        1. 字符串类型 string
        2. 哈希类型 hash : map格式
        3. 列表类型 list : linkedlist格式。支持重复元素
        4. 集合类型 set : 不允许重复元素
        5. 有序集合类型 sortedset:不允许重复元素,且元素有顺序
  2. 字符串类型 string

    1. 存储: set key value
      127.0.0.1:6379> set username zhangsan
      OK
    2. 获取: get key
      127.0.0.1:6379> get username
      “zhangsan”
    3. 删除: del key
      127.0.0.1:6379> del age
      (integer) 1
  3. 哈希类型 hash

    1. 存储: hset key field value

      127.0.0.1:6379> hset myhash username lisi
      (integer) 1

      127.0.0.1:6379> hset myhash password 123
      (integer) 1

    2. 获取:

      • hget key field: 获取指定的field对应的值
        127.0.0.1:6379> hget myhash username
        “lisi”
      • hgetall key:获取所有的field和value
        127.0.0.1:6379> hgetall myhash
        1) “username”
        2) “lisi”
        3) “password”
        4) “123”
  4. 删除: hdel key field
    127.0.0.1:6379> hdel myhash username
    (integer) 1

  5. 列表类型 list:可以添加一个元素到列表的头部(左边)或者尾部(右边)

    1. 添加:

      1. lpush key value: 将元素加入列表左表

      2. rpush key value:将元素加入列表右边

        127.0.0.1:6379> lpush myList a
        (integer) 1

        127.0.0.1:6379> lpush myList b
        (integer) 2

        127.0.0.1:6379> rpush myList c
        (integer) 3

    2. 获取:
      • lrange key start end :范围获取
        127.0.0.1:6379> lrange myList 0 -1
        1) “b”
        2) “a”
        3) “c”
    3. 删除:
      • lpop key: 删除列表最左边的元素,并将元素返回
      • rpop key: 删除列表最右边的元素,并将元素返回
  6. 集合类型 set : 不允许重复元素

    1. 存储:sadd key value

      127.0.0.1:6379> sadd myset a

  (integer) 1


  127.0.0.1:6379> sadd myset a


  (integer) 0

2. 获取:smembers key:获取set集合中所有元素
             127.0.0.1:6379> smembers myset


    1) "a"

3. 删除:srem key value:删除set集合中的某个元素    
             127.0.0.1:6379> srem myset a


    (integer) 1
  1. 有序集合类型 sortedset:不允许重复元素,且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

    1. 存储:zadd key score value
127.0.0.1:6379> zadd mysort 60 zhangsan


(integer) 1


127.0.0.1:6379> zadd mysort 50 lisi


(integer) 1


127.0.0.1:6379> zadd mysort 80 wangwu


(integer) 1
  1. 获取:zrange key start end [withscores]

    127.0.0.1:6379> zrange mysort 0 -1

  1) "lisi"


  2) "zhangsan"


  3) "wangwu"



  127.0.0.1:6379> zrange mysort 0 -1 withscores


  1) "zhangsan"


  2) "60"


  3) "wangwu"


  4) "80"


  5) "lisi"


  6) "500

3. 删除:zrem key value

      127.0.0.1:6379> zrem mysort lisi

      (integer) 1
  1. 通用命令
    1. keys * : 查询所有的键
    2. type key : 获取键对应的value的类型
    3. del key:删除指定的key value

持久化

  1. redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
  2. redis持久化机制:
    1. RDB:默认方式,不需要进行配置,默认就使用这种机制
      • 在一定的间隔时间中,检测key的变化情况,然后持久化数据
    2. AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据

Java客户端Jedis

  • Jedis: 一款java操作redis数据库的工具.

  • 使用步骤:

    1. 下载jedis的jar包

    2. 使用

      1
      2
      3
      4
      5
      6
      //1. 获取连接
      Jedis jedis = new Jedis("localhost",6379);
      //2. 操作
      jedis.set("username","zhangsan");
      //3. 关闭连接
      jedis.close();
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      1) 字符串类型 string
      set
      get

      //1. 获取连接
      Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
      //2. 操作
      //存储
      jedis.set("username","zhangsan");
      //获取
      String username = jedis.get("username");
      System.out.println(username);

      //可以使用setex()方法存储可以指定过期时间的 key value
      jedis.setex("activecode",20,"hehe");//将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对

      //3. 关闭连接
      jedis.close();
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      2) 哈希类型 hash : map格式  
      hset
      hget
      hgetAll
      //1. 获取连接
      Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
      //2. 操作
      // 存储hash
      jedis.hset("user","name","lisi");
      jedis.hset("user","age","23");
      jedis.hset("user","gender","female");

      // 获取hash
      String name = jedis.hget("user", "name");
      System.out.println(name);
      // 获取hash的所有map中的数据
      Map<String, String> user = jedis.hgetAll("user");

      // keyset
      Set<String> keySet = user.keySet();
      for (String key : keySet) {
      //获取value
      String value = user.get(key);
      System.out.println(key + ":" + value);
      }

      //3. 关闭连接
      jedis.close();
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      3) 列表类型 list : linkedlist格式。支持重复元素
      lpush / rpush
      lpop / rpop
      lrange start end : 范围获取

      //1. 获取连接
      Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
      //2. 操作
      // list 存储
      jedis.lpush("mylist","a","b","c");//从左边存
      jedis.rpush("mylist","a","b","c");//从右边存

      // list 范围获取
      List<String> mylist = jedis.lrange("mylist", 0, -1);
      System.out.println(mylist);

      // list 弹出
      String element1 = jedis.lpop("mylist");//c
      System.out.println(element1);

      String element2 = jedis.rpop("mylist");//c
      System.out.println(element2);

      // list 范围获取
      List<String> mylist2 = jedis.lrange("mylist", 0, -1);
      System.out.println(mylist2);

      //3. 关闭连接
      jedis.close();
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      4) 集合类型 set  : 不允许重复元素
      sadd
      smembers:获取所有元素

      //1. 获取连接
      Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
      //2. 操作
      // set 存储
      jedis.sadd("myset","java","php","c++");

      // set 获取
      Set<String> myset = jedis.smembers("myset");
      System.out.println(myset);

      //3. 关闭连接
      jedis.close();
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序
      zadd
      zrange

      //1. 获取连接
      Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
      //2. 操作
      // sortedset 存储
      jedis.zadd("mysortedset",3,"亚瑟");
      jedis.zadd("mysortedset",30,"后裔");
      jedis.zadd("mysortedset",55,"孙悟空");

      // sortedset 获取
      Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);

      System.out.println(mysortedset);
      //3. 关闭连接
      jedis.close();

Jdeis连接池

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    * jedis连接池: JedisPool
    * 使用:
    1. 创建JedisPool连接池对象
    2. 调用方法 getResource()方法获取Jedis连接
    //0.创建一个配置对象
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(50);
    config.setMaxIdle(10);

    //1.创建Jedis连接池对象
    JedisPool jedisPool = new JedisPool(config,"localhost",6379);

    //2.获取连接
    Jedis jedis = jedisPool.getResource();
    //3. 使用
    jedis.set("hehe","heihei");
    //4. 关闭 归还到连接池中
    jedis.close();

    * 连接池工具类
    public class JedisPoolUtils {

    private static JedisPool jedisPool;

    static{
    //读取配置文件
    InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
    //创建Properties对象
    Properties pro = new Properties();
    //关联文件
    try {
    pro.load(is);
    } catch (IOException e) {
    e.printStackTrace();
    }
    //获取数据,设置到JedisPoolConfig中
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
    config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));

    //初始化JedisPool
    jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
    }
    /**
    * 获取连接方法
    */
    public static Jedis getJedis(){
    return jedisPool.getResource();
    }
    }
Thanks!