JAVA后端知识点碎片化整理 基础篇(六) 数据库(Mysql)

因为马上开始2019秋招、平时的学习比较琐碎、JAVA后端博大精深,想在暑假这段时间从头开始整理JAVA知识点查缺补漏,迎战2019秋招。主要参考(微信公众号)JAVA团长与(博客园)五月的仓颉的知识点复习线,对其列出的每一个的知识点再一次的咀嚼并谈谈自己的理解。(平时从这两位学到很多,也非常感谢身边同行的人)补充一下:其中知识点的讲解参考了之前看过的博客讲解或者书籍,之所以称之为基础篇,主要是加深对Java技术栈的宏观认识。(也是对数据存储一章的补充)


数据开始在计算机中个持久化存储、优化读写、保证数据的有效性并计算离不开数据库的支持,当前物理的数据库都是按照E-R模型进行设计的,E表示entity实体,R表示Relationship,成为关系型数据库。主要分为两类一是文档型数据库,如sqlite,就是一个对文件复制,完成数据库的复制。第二种是服务型数据库,如mysql就是讲数据存在一个物理文件中,但是需要tcp/ip协议进行连接,进行数据库的读写操作。如果是单机使用数据量不大,需要方便移植或者需要频繁读写文件的话用sqlite比较合适(比如嵌入式应用,不支持用户系统,多用户应用或者大面积写入数据就不适合使用),如果是为了满足多用户的访问,或者网站的访问用mysql比较合适(实际上是作为一个独立的数据库服务器,灵活而强大)。

1、数据库的三范式:经过研究和对使用中问题的总结,对于设计数据库提出了一些规范,这些规范被称之为范式。

每后面一个范式都是见建立在前一个范式的基础上的:(1)第一范式:列的不可拆分性;保证列的原子性;(2)、第二范式:确保表的每列都和主键相关(表分离,不要都堆到一张表上),也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据表中。(3)第三范式:每一列数据都和主键直接相关,而不能是间接相关(在建立表间联系上十分重要)。这一点在设计标的简洁、明了性上十分重要,

2、数据库的字段类型:数字类型,区分TINYINT/INT/BIGINT(分别是1个字节、4个字节、8个字节)能缺点不会使用负数的字段,建议加上unsigned,能使用数字类型的字段尽量使用数字类型而不是字符串类型。字符类型:char、varchar、Text数据类型,定长类型建议是用char(),不定长字段尽量使用Varchar来自动适应长度,且仅仅设置适当的最大长度。时间类型,按选择的优先级排序DATE(精确到天),TIMESTAMP、DATETIME(精确到时间)。ENUM由于状态字段可以尝试使用ENUM来存放,避免使用NULL字段(比如男是1女是0)。中文编码记得使用utf8

3、索引索引是对数据库表中一列或者多列的值进行排序的一种结构。优点:大大加快了数据的检索速度、创建唯一性索引,保证数据库表中每一行数据的唯一性、可以加速表与表直接的连接。缺点:索引需要占用物理内存,当对表中数据进行增加,删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。(表中记录很少,经常出现插入删除和修改的表,数据重复且平均分布的表字段比如男女,这些情况避免索引)

索引的分类:普通索引:create index index1 on  table(column1); 唯一索引:索引的列的值必须唯一,但允许有空值;主键索引:不允许为k开始创建表的时候有主键就是主键索引,不允许为空create table table1(id INT PRIMARY KEY AUTO_INCREATEMENT);也可以添加alter table table1 add primary key (id);组合索引:将表中多个字段设置成索引,create table table1 (id INT PRIMARY KEY,bbb varchar(8) NOT NULL,CCC varchar(16) NOT NULL default'');       alert table table1 add INDEX 'zuhe'(bbb,ccc);这样当你查询select * from table1 where bbb=a and ccc=c;时就会用到索引。

4、事务:数据库事务是指作为单个逻辑工作单元执行一系列操作,要么完全地执行,要么完全地不执行

四大特征:1、原子性:事务必须是原子工作单元,对于其数据修改,要么完全执行,要么全不执行。2、一致性:事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态,事务执行的结果比如使数据库从一个一致性状态到另一个一致性状态。3、隔离性(关于事务又有多种隔离级别):一个事务的执行不能干扰其他事务,即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。4、持久性:事务完成之后,它对数据库中数据改变是永久性的。

在介绍隔离级别之前,先看一下如果不考虑事务的隔离性,会发生的问题:

1、脏读:事务处理过程中读取到另一个未提交的事务中的数据。比如ab都开启了两个事务,a相b转了500元,当时a未提交事务,此时b查看发现多了500,此时a回滚事务,b再查看发现根本就没有多500,这就是脏读。读到本不应该出现的东西。(针对未提交的数据)

2、不可重复读,在一个事务中查询到的结果不一致(针对updata操作)。如果在一次事务中出现了两次读入分别是a向b转钱的前后,a执行完事务的前后,b会出现两次不同的结果。这就是不可重复读。(针对其他提交后数据本身的对比)

3、幻读,再一次事务中两次查询到的结果不一致(针对insert操作、删除)。比如第一次查询到1000个人,中间一个事务让他增加了一个人,第二次查到了1001人数据不一致(针对其他提交后,读取数据条数的变化)(实际上就是行锁失效,仅仅锁住一行并没有用,需要锁住整个表。。。)

解释MYSQL数据库为我们提供了四种隔离级别:1Serializable串行化:可以避免脏读、不可重复读、幻读的发生;2、Repeatable read可重复读:可以避免脏读、不可重复读的发生。3、Read committed读已提交:可以避免脏读的发生。4、Read uncommitted(读未提交):最低级别,任何情况都无法保证。 mysql默认级别是可重复读。

5、数据库的锁

按模式来分:共享锁(读锁):顾名思义共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。

排他锁(写锁):就是不能与其他的锁并存,比如一个事务获取到了一个数据行的排它锁,其他事务就不能在获取该行的其他锁并存,就是说一个事务一旦获得排他锁,其他事务就不能再获取该行的其他锁,就是一个事务开始写事务,其他事务不能读。

这个时候又会有一个新的情况出现,就是更新锁。如果两个事务同时获取了资源上的共享锁,这并没有问题,然后试图同时更新数据,则两个事务都需要转换为共享锁为排他锁,并且每一个事务都等待另一个事务释放共享模式锁,因此发生了死锁。若要避免这种潜在的死锁问题,请使用跟新锁。即一次只可以一个事务获取资源的更新锁,如果事务修改资源则更新锁转换为排他锁。(提供了一种渐变态)

锁的粒度主要分为如下几个类型行锁:粒度最小,并发性最高。页锁:一次锁定一页。25个行锁可以升级为页锁。表锁:粒度比较大,并发性低。数据库锁:控制整个数据操作。

理论上来分乐观锁相对于悲观锁而言,悲观锁假设认为数据一般情况下不造成冲突,所以再数据交换更新的时候才会对数据的冲突进行检测,如果发现了冲突,则让返回用户错误的信息,让用户决定如何去做。一般的实现乐观锁方式是记录数据版本。悲观锁:顾名思义就是每次拿到数据的时候都认为别人回去修改,所以每次拿到数据的时候都上锁,这样别人想拿到这个数据就会block阻塞知道它拿到锁,传统关系型数据中就是这种锁机制,行锁、表锁等都是先上锁再操作。

6、msql五大约束:

约束作为一种限制,他通过对表中行或者列做出限制,来保证数据的完整性与唯一性。主键约束:mysql中通常有PRIMARY KEY适用于约束表中的一行,主键要求这一行数据不能有重复且不能为空,还有一种特殊的主键,主键不仅可以是表中的一列,也可以由表中的两列或者多列共同标识。默认约束:DEFAULT规定,单有DEFAULT约束的列不能为空;唯一约束也比较简单,就是不可以有数据重复;外键约束是一个表与另一个表之间连接的字段。是保证表中数据完整性,也能保证标与表之间的关系,被外键约束的列,取值比如参考对应列中是否有对应值。(cerate table table1(A1 int primary key);create table table2(B1 int,B2 int));alter table table2 add constraint FK_B2_table1A1 foreign key(B2) reference t1(A1),t1的A1必须是主键或者唯一 非空约束,听名字就能理解,被非空约束的列,插入值时必须非空。

7、mysql引擎讲解:

mysql使用的引擎:(1)Mylsam,不支持事务,适用于选择密集型插入密集型,mysql默认的引擎。(2)、innodb适用于更新密集型,支持事务,自动灾难恢复、行级锁。(3)memory出发点是速度,采用逻辑存储介质是内存。(4)MyIsam的表集合。

主要对比MyISAM和InnoDB:

1、MyISAM不支持事务高级处理,InnoDB支持。MyISAM不支持外键,InnoDB支持。2、MyISAM锁的粒度是表级,InnoDB支持行级锁。3、MySAM不支持外键,而InnoDB支持。4、MySAM支持全文索引,InnoDB不支持全文索引。5、InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数

MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。MySAM使用B+树作为索引结构,叶节点的data域存放的是数据记录的地址。在MyISAM,主索引与辅助索引没有任何区别,只是主索引要求key‘是唯一的,而辅助索引可以重复。当MyISAM检索算法首先按照B+树搜索算法来搜索索引,如果指定Key存在则去data域的值,然后data域的值为地址,读出响应的记录数据。MyISAM的索引方式也叫作“非聚集”,之所以这么称呼是为了与InnoDB的聚集索引区分。

InnoDB索引实现

然InnoDB也使用B+Tree作为索引结构,然而实现的方式却与MyISAM截然不同,InnoDB主索引是在叶节点保护了完整的数据记录,这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以Innodb表中必须包含主键,如果没有会自动选择一个唯一表示数据的记录作为主键,如果还不存在,那么会自动生成一个隐含字段long作为主键。这种索引方式使得主键索引搜索十分高效,但是辅助索引需要检索两遍索引,首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。

不同存储引擎索引的实现方式对正确使用和诱惑索引都非常有帮助,例如知道了InnoDB索引实现后,就很容易明白。1、不建议使用过长的字段作为主键,因为所有的辅助索引都需要引用主索引,过长的主索引会令辅助索引变得过大。2、用非单调的字段用为主键在Innodb中不是一个好主意,innodb本身是一个B+树,非单调的主键在插入新纪录中为了维持B+树的特性会导致频繁分裂调整,十分低效,所以一般使用自增作为主键。

InnoDB索引和MyISAM索引区别:1、主索引区别:Innodb的数据文件本身就是索引文件,而MyISAM索引和数据是分开的。2、辅助索引的区别:InnoDB辅助索引data域存储相应记录主键的值,需要二次的主键索引查找去获得记录,而不是地址,而MyISAM的辅助索引和主键的值主键索引与辅助索引没有多大区别。


B树是一种为了提高磁盘或者外部设备查找效率而昌盛的鄂一中多路平衡查找树。B+树为了是B树的变形,用于大多数数据库或者文件系统的存储设计的。

B树相对于红黑树的区别:大规模数据存储时,红黑树往往会出现由于树的深度过大而造成了磁盘IO读取过于频繁,进而导致效率低下的情况。为什么会出现这样的情况,我们知道要获取磁盘上的数据,必须先通过磁盘移动臂移动到数据存在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在磁道,再对数据进行读写。磁盘IO代销主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO读写频繁。根据磁盘查找存取时间往往由树的高度所决定。所以我们通过某一种较好的树的结构减少树的高度。而B树就是通过多个子女,从几十到几千,可以降低树的高度。(以后专门再谈红黑树有点难)

B树与B+树的区别:列出两张图分别是B树与B+树 B树与B+树



从结构上来看:B树的所有节点都出现在同一层,叶子节点不包含任何关键字信息(只适合随机检索)。    B+树所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接,所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息)(随机和顺序都支持)

为什么说B+-树更适合实际应用中的操作系统文件索引和数据库索引:1、B+树的磁盘读写代价小,内部节点并没有指向关键字具体信息的指针。因此内部节点相对于B树更小,如果把所有内部节点的关键字放入同一盘块中,那么盘块所能容纳的关键字也会越多,而一次性读入内存中的关键字越多,相对于IO的读写次数也就降低了。2、B+树查询效率稳定,由于并非终点并不是最终指向文件内容的节点,而只是叶子节点中关键字的索引。所以任何关键字查找必须走一条从根节点到叶子节点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。(B树提升了IO性能却没有解决元素遍历低下的问题,B+树的叶及诶单使用指针顺序连接起来,只要遍历了叶子节点,就实现了整个树的遍历,而且数据库基于范围的查询十分频繁


B-Tree:如果一次检索需要访问4个节点,数据系统的设计者利用磁盘预读原理,把节点设计为一个页,那读取一个节点需要一次IO操作,完成这次检索操作,最多需要还三次IO操作。数据记录越小,每个节点存放的数据就越多,树的高度也就越小,IO减少,检索效率提高。

B+Tree:非叶子节点只存Key,大大减少了非叶子节点的大小,那么每个节点就可以存放更多的记录,树更矮了,IO操作更少了,所以B+Tree拥有更好的性能。


SQL语句

SELECT * FROM table ORDER BY field DESC;降序排列

SELECT DISTINCT field FROM table WHERE filed<100;列出字段小于100的非重复的值

INSERT INTO table (column1,column2,column3) VALUES (value1,value2,value3);插入。。。

UPDATE table_name SET column = value1,column2=value2 WHERE column=value3;吧字段3为值3的行树的字段1设为值1,字段2设为值2.

LEFT JOIN左连接 返回包括左表中所有记录和右表中连接字段相等的记录。

RIGHT JOIN右连接 返回包括右表中所有记录和左表中连接字段相等的记录。

INNER JOIN 等值连接  只返回两个表中连接字段相等的行


练习:

SELECT a.name,a,age,b.address FROM name_age a INNER JOIN name_address b WHERE a.name=b,name;返回两条

SELECT a.name,a.age,b.address FROM name_age a LEFT JOIN name_address b on a,name = b.name; 返回三条

SELECT b.name,a.age,b.address From name_age a RIGHT JOIN name_address b on a.name = b.name;返回三条


UNION操作符 用于合并两个或者多个SELECT 语句的结果集

SELECT country,name From Website WHERE country=‘CN’ 

UNION

SELECT country,app_name From app WHERE country='CN' ORDER BY country;

创建视图,就是一种虚拟状态存在的表,其内容由查询定义,同真实表一样,数据的物理地址任然在表中。A、数据安全性

B查询简单化 C逻辑数据独立性    视图的缺点:性能、修改限制、创建视图的限制。

CREATE VIEW v AS SELECT * FROM table;CREATE VIEW v AS SELECT id,name,age FROM table;

基于同一个数据库的视同

CREATE VIEW v AS (SELECT * FROM table1)UNION ALL(select * from table2);

不同数据库

CREATE VIEW db.v1 as (select * from db1.table1) union all(select * from db2.table2);

远程创建

create view 本地数据库.v as (select * from 本地数据库.table1) union all (select * from 远程数据库.test_table);

猜你喜欢

转载自blog.csdn.net/weixin_39893439/article/details/80968806
今日推荐