1.DDL:数据定义语言
Data Defination Language:适用范围:对数据库中的某些对象(例如,database,table)进行管理,如create、alter、drop、TRUNCATE、show等
建表- 约束
建表
①创建表 create
create table 表名( 列名 数据类型, 列名 数据类型, 列名 数据类型, ... ... )②修改表 alter
-- (1)将学生表中添加新的一列,籍贯 stu_hometown varchar(50) alter table student add stu_hometown varchar(50) -- (2)修改籍贯 stu_hometown 列名,改为 student_hometown alter table student change stu_hometown student_hometown varchar(50) -- (3)修改籍贯 stu_hometown 列数据类型,改为 varchar(25) alter table student modify column stu_hometown varchar(25) -- (4)删除籍贯 列 alter table student drop student_hometown -- (5)将表名修改为mystudent alter table student to mystudent③删除表
drop table 表名; -- 删除10部门 delete from dept where deptno = 10 -- 删除失败,原因在于在emp表中有在10部门的员工,所以不能删除 delete from dept where deptno = 50 -- 删除成功,原因在于在其他表中没有在50部门的员工,所以可以删除 --删除时的级联操作 --删除部门数据时候,对关联表emp 员工表 有什么影响? emp 表中有外键 dept(deptno) 示例: 在emp表中有在10部门的员工,现在要删除10部门 (1) NO ACTION :不允许删除,也不报错,不提示 (2) RESTRICT : 不允许删除,会报错,提示在其他表中找到该记录 (3) SET NULL :允许删除,把emp中的员工所在部门编号设置为null 【前提:emp(deptno)允许为null】 (4) CASACDE : 级联删除,删除了10部门,在10部门的员工记录也删除了
约束
作用:为了保证数据的完整性与正确性,表中数据必须有约束
① 主键约束 primary key
用于唯一识别一条记录的字段(该主键可以是一个列,也可以是多个列- 联合主键) 特征: (1)唯一性 (2)非空性 identifier 身份识别②唯一性约束 unique
列的值 是唯一的③ 非空约束 not null
列的值 不为null④外键约束
b表中的某列 数据 来源于 a 表中的 某一列
2.DML:数据操纵语言
Data Manipulation Language:适用范围:对数据库中的数据进行一些简单操作,如insert,delete,update,select等
① insert语句
插入数据
insert into 表名 (列,列,列...) values(值,值,值...); --当插入的数据时与表格列一一对应的话,则列可以省略 insert into 表名 values(值,值,值...);
②update语句
主要是用来更新表中的数据
update 表名 set 列名=新值,列名=新值 where 条件;
③delete语句
delete from 表名 where 条件;
DDL和DML区别:
1.DML操作是可以手动控制事务的开启、提交和回滚的。
2.DDL操作是隐性提交的,不能rollback!
重点:
3.事务
①事务的定义:
就是指一个任务中有一组sql语句组成,这些sql语句要么全部执行成功,要么全部不执行
注意:
在数据库中,执行业务的基本单位是事务,不是以某一条SQL
数据库在默认情况下,事务都是打开的,也就是说它是一直处在事务中的,一个事务的结束,代表着下一个事务的开启
执行commit或者rollback指令时,会结束当前事务
②作用:
用来保证数据的平稳性和可预测性
③事务的四大属性(ACID):
atomic,原子性,事务是业务逻辑单元中不可再分割的,一个任务中的多个sql语句,要么同时成功,要么不执行
consistency,一致性,事务一旦结束,内存中的数据和数据库中的数据是保持一致的 或者:几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致 或者:事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态 这种特性称为事务的一致性。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的
isolation,隔离性,事务之间互不干扰,一个事务的结束意味着下一个事务的开启
duration,持久性,事务一旦提交,则数据持久化到数据库中,永久保存
④事务的隔离级别
1.Read uncommitted(读未提交)
如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据,该隔离级别可以通过“排他写锁”,但是不排斥读线程实现。这样就避免了更新丢失,却可能出现脏读,也就是说事务B读取到了事务A未提交的数据
解决了更新丢失,但还是可能会出现脏读
2.Read committed(读提交)
如果是一个读事务(线程),则允许其他事务读写,如果是写事务将会禁止其他事务访问该行数据,该隔离级别避免了脏读,但是可能出现不可重复读。事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
解决了更新丢失和脏读问题
3.Repeatable read(可重复读取)
可重复读取是指在一个事务内,多次读同一个数据,在这个事务还没结束时,其他事务不能访问该数据(包括了读写),这样就可以在同一个事务内两次读到的数据是一样的,因此称为是可重复读隔离级别,读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务(包括了读写),这样避免了不可重复读和脏读,但是有时可能会出现幻读。(读取数据的事务)可以通过“共享读镜”和“排他写锁”实现。
解决了更新丢失、脏读、不可重复读、但是还会出现幻读
4.Serializable(可序化)
提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行,如果仅仅通过“行级锁”是无法实现序列化的,必须通过其他机制保证新插入的数据不会被执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也是最高的,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读
解决了更新丢失、脏读、不可重复读、幻读(虚读)
以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低,像Serializeble这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况来,在MYSQL数据库中默认的隔离级别是Repeatable read(可重复读)。 索引: 概念、建立原则、优缺点、类型、底层数据结构、B+ (为什么不用B树)、增删改查对索引的影响 优化SQL查询
4.索引(Index)
比如我们要在字典中找某一字,如何才能快速找到呢?那就是通过字典的目录。
对数据库来说,索引的作用就是给‘数据’加目录。创建所以的目的就是为了提高查询速度
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
①索引算法
btree(平衡树)索引 log2N
hash(哈希)索引 1
②优缺点
好处
加快了查询速度(select )
创建唯一性索引,保证数据库表中每一行数据的唯一性;
加速表和表之间的连接
在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。
坏处:
降低了增,删,改的速度(update/delete/insert),降低了数据的维护速度。
增大了表的文件大小,占物理空间(索引文件甚至可能比数据文件还大)
③索引类型
普通索引(index):仅仅是加快了查询速度,数据可以重复
唯一索引(unique):行上的值不能重复,要求所有记录都唯一
主键索引(primary key):不能重复,也就是在唯一索引的基础上相应的列必须为主键
全文索引(fulltext):仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时好空间,语法和普通索引一样
组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。
④索引语法
查看某张表上的所有索引
show index from tableName [\G,如果是在cmd窗口,可以换行];
show index from emp;建立索引
alter table 表名 add index/unique/fulltext 索引名 (列名) ; ---索引名可不写,不写默认使用列名
alter table emp add index ename_index (ename);alter table 表名 add primary key(列名) --不要加索引名,因为主键只有一个
删除非主键索引
alter table 表名 drop index 索引名;
alter table emp drop index ename_index;删除主键索引
alter table 表名 drop primary key;
全文索引与停止词
全文索引的用法:match(全文索引名) against('keyword');
⑤索引建立原则
1.经常使用
2.外键、主键
3.经常分组排序的
⑥增删改查对索引的影响
索引的原理: 索引是一个B+二叉树。从原理上说B+二叉树的特性 决定了对insert、update、delete、select的影响和作用。
如果新insert一个值,会导致B+二叉树进行再平衡重整,这个过程B+二叉树进行重新整理,索引越大。索引越多,重新整理花费的时间越大。所以有的时候再进行大批量的insert插入时,我们不会建立索引,等数据全部insert完毕,再建立索引。
Redis:
5.Redis :
1.Redis与MySQL的区别
1.类型上:
MySQL是关系型数据库,Redis是缓存数据库
2.作用上:
MySQL用于持久化的存储数据到硬盘,功能强大,速度较慢,基于磁盘,读写速度没有Redis快,但是不受空间容量限制,性价比高
Redis用于存储使用较为频繁的数据到缓存中,读取速度快,基于内存,读写速度快,也可做持久化,但是内存空间有限,当数据量超过内存空间时,需扩充内存,但内存价格贵
3.需求上
MySQL和Redis因为需求的不同,一般都是配合使用。 需要高性能的地方使用Redis,不需要高性能的地方使用MySQL。存储数据在MySQL和Redis之间做同步。
Redis优势
速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
支持丰富数据类型,支持string,list,set,sorted set,hash
支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
2.使用场景
1.缓存
作为key-value形态的内存数据库,使用Redis缓存数据非常简单,只需要通过String类型将序列化后的对象存起来即可。
作为缓存使用时,一般有两种方式保存数据:
1.读取前,先去读Redis,如果没有数据,读取数据库,将数据拉入Redis。
2.插入数据时,同时写入Redis。
2.点赞
3.排行榜
4.秒杀
3.Redis数据类型、数据结构
①string(字符串)
数据结构:数组
<KEY,VALUE>
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
能表达3中类型:字符串、整数和浮点数。根据场景相互间自动转型,并且根据需要选取底层的承载方式
value内部以int、sds作为结构存储。int存放整型数据,sds存放字节/字符串和浮点型数据
sds内部结构:
②hash(哈希)
数据结构:二维结构
第一维度:数组
第二维度:链表
<NAME: [<KEY,VALUE>].....>
Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
map又叫hash。map内部的key和value不能再嵌套map了,只能是string类型:整形、浮点型和字符串
map主要由hashtable和ziplist两种承载方式实现,对于数据量较小的map,采用ziplist实现
hashtable内部结构 (1)主要分为三层,自底向上分别是dictEntry、dictht、dict (2)dictEntry:管理一个key-value对,同时保留同一个桶中相邻元素的指针,一次维护哈希桶的内部连 (3)dictht:维护哈希表的所有桶链 (4)dict:当dictht需要扩容/缩容时,用于管理dictht的迁移
③list(列表)
数据结构:双向链表
<NAME,[VALUE,,,]>
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
list类型的value对象内部以linkedlist或ziplist承载。当list的元素个数和单个元素的长度较小时,redis会采用ziplist实现以减少内存占用,否则采用linkedlist结构
linkedlist内部实现是双向链表。在list中定义了头尾元素指针和列表的长度,是的pop/push操作、llen操作的复杂度为O(1)。由于是链表,lindex类的操作复杂度仍然是O(N)
ziplist的内部结构 (1)所有内容被放置在连续的内存中。其中zlbytes表示ziplist的总长度,zltail指向最末元素,zllen表示元素个数,entry表示元素自身内容,zlend作为ziplist定界符 (2)rpush、rpop、llen,复杂度为O(1);lpush/pop操作由于涉及全列表元素的移动,复杂度为O(N)
④set(集合)
数据结构:Hash
<NAME,[VALUE....]>
Redis 的 Set 是 string 类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
set以intset或hashtable来存储。hashtable中的value永远为null,当set中只包含整数型的元素时,则采用intset
intset的内部结构 (1) 核心元素是一个字节数组,从小到大有序存放着set的元素 (2) 由于元素有序排列,所以set的获取操作采用二分查找方式实现,复杂度O(log(N))。进行插入时,首先通过二分查找得到本次插入的位置,再对元素进行扩容,再将预计插入位置之后的所有元素向右移动一个位置,最后插入元素,插入复杂度为O(N)。删除类似
⑤sorted-set(有序集合)类型
数据结构:Hash+跳跃表
<NAME: [SCORE,VALUE]>
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
类似map是一个key-value对,但是有序的。value是一个浮点数,称为score,内部是按照score从小到大排序
内部结构以ziplist或skiplist+hashtable来实现
4.基本的数据的增删改查命令
①添加键
127.0.0.1:6379> set name 'tzhang' OK 127.0.0.1:6379> set age 10 OK
②取键值
127.0.0.1:6379> get name # 可以获取 "hello-redis"
③修改键
127.0.0.1:6379> set name 'hello-redis' OK
④删除键
127.0.0.1:6379> get name "qq" 127.0.0.1:6379> del name (integer) 1 127.0.0.1:6379> get name (nil)
5.持久化机制RDB、AOF
RDB
1.什么是RDB
RDB:每隔一段时间,把内存中的数据写入到磁盘的临时文件,作为快照,恢复的时候把快照文件读进内存。如果宕机重启,那么内存里的数据肯定会没有的,那么再次启动redis后,则会恢复。
2.RDB的优劣势
优势
1、每隔一段时间备份,全量备份(一个小时或24小时或30天的进行备份)
2、灾备简单,可远程传输
3、子进程备份的时候,主进程不会有任何io操作(不会有写入修改或删除),保证备份数据的完整性
4、相对AOF来说,当有更大文件的时候可以快速重启恢复
劣势
1、发生故障时,有可能会丢失最后一次的备份数据
2、子进程所占用的内容比较和父进程一模一样,如会造成CPU负担
3、由于定时全量备份是重量级操作,所以对于实时备份,就无法处理了
RDB适合大量数据的恢复,但是数据的完整性和一致性可能不足。
AOF
1.什么是AOF
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
RDB会丢失最后一次备份的rdb文件,如果追求数据的完整性,那就考虑使用AOF。
2.AOF特点
以日志的形式来记录用户请求的写操作。读操作不会记录,因为写操作才会存储。
文件以追加的形式而不是修改的形式。
redis的aof恢复其实就是把追加的文件从开始到结尾读取执行写操作。
3.AOF的优劣势
优势
AOF更加耐用,可以以秒级别为单位备份,如果发生问题,也只会丢失最后一秒的数据,大大增加了可靠性和数据完整性。所以AOF可以每秒备份一次,使用fsync(同步)操作。
以log日志形式追加,如果磁盘满了,会执行redis-check-aof工具。
当数据太大的时候,redis可以在后台自动重写AOF。当redis继续把日志追加到老的文件中去时,重写也是非常安全的,不会影响客户端的读写操作。
4.AOF日志包含的所有写操作,会更加便于redis的解析恢复。
劣势
相同的数据,同一份数据,AOF比RDB大。
针对不同的同步机制,AOF会比RDB慢,因为AOF每秒都会备份做写操作,这样相对与RDB来说就略低。每秒备份fsync没毛病,但是如果客户端的每次写入就做一次备份fsync的话,那么redis的性能就会降。
AOF发生过bug,就是数据恢复的时候数据不完整,这样显得AOF会比较脆弱,容易出现bug,因为AOF没有RDB那么简单,但是呢为了防止bug的产生,AOF就不会根据旧的指令去重构,而是根据当前缓存中存在的数据指令去做重构,这样就更加健壮和可靠了。
6.雪崩、击穿、穿透