MySQL

目录

一,索引

1,概念

2,代价

3,基本操作

(1)查看索引:

(2)创建索引

(3)删除索引

4,索引背后的数据结构:

B树:

B+树:

二,事务

1,概念

2,回滚

3,操作:

4,事务的基本特性:

(1)原子性(最重要的特性)

(2)一致性

(3)持久性

(4)隔离性(不好解释)

1)脏读

2)不可重复读

3)幻读

A,read uncommitted 读未提交:

B,read committed 读已提交

C,repeatable read 可重复读

D,serializable 串行化

三,JDBC


一,索引

1,概念

索引相当于树的目录,数据库中的索引是为了加快查询速度,就相当于是在数据库中构建一个特殊"目录",通过这样的数据结构,加快查询的速度,尽可能避免针对表数据进行遍历操作

2,代价

引入索引需要付出额外的存储空间,引入索引后,确实能提高查询效率,但有可能会影响到增删改的效率,有时候,增删查改会更慢,因为需要同步更新维护索引

3,基本操作

(1)查看索引:

show index from 表名;

索引是针对某列创建索引

后续查询的的时候,查询条件使用的列和索引列要匹配,索引才能生效,从而提高效率.例如是针对id列建立索引,那么以id列作为条件,才能使索引生效

主键,unique和foreign key会自带索引

(2)创建索引

create index 索引名 on 表名(列名)

创建索引也是一个危险操作,如果表是空表或者表里的数据比较少,创建索引谈不上危险,一旦数据比较大,千万不要创建索引,这时会触发大量的硬盘IO,直接把机器搞卡死,所以应该再见表初,都要有那些索引,提前规划好

(3)删除索引

drop index 索引名 on 表名;

只能删除自己创建的索引,但是不能删除自动创建的

4,索引背后的数据结构:

B+树,为数据库量身定制的数据结构,B树也可以写成B-树.

B树:

本质就是N叉搜索树,每个节点可以有多个子树(树的度是N).这样就可以降低树的高度.某个节点上保存了N个key就你能延伸出N+1个子树.此时进行查询的时候,针对每个节点,都需要比较多次,才能确定下一步走哪个区间,此时虽然高度降低了,但是每个节点的比较次数增多了(访问每个节点只需要一次硬盘IO 就可以了,和某个节点进行比较的时候,用一次硬盘IO,把这个节点上的内容都读取出来,在内存上进行比较)这里的主要目的不是为了减少比较次数,而是为了减少硬盘IO的次数

B+树:

B+树是针对B树做出进一步改进的数据结构,B树也是一个N叉搜索树

1)B+树,每个节点包含N个key,划分出N个区间

2)父亲节点中的key会下沉的到子节点中,该节点作为节点中最大的的角色存在

3)叶子节点像链表一样首尾相连

4)叶子节点这一层构成了数据集合的全集

优势:

1),N叉搜索树,高度较低,此时硬盘IO次数较少

2),叶子节点时全集,并且用链表链接,非常便于范围查询

3),所有的查询都是要落到叶子节点上的,所以任何一次查询,所经历的IO次数和比较次数都是差不多的,查询的开销稳定

4)由于节点就是全集,非叶子节点就不必存储"数据行",只需要存储一个key即可,所以非叶子节点只需要存储一些数字,消耗的空间不大,我们甚至可以将这样的数据直接存储到内存中

二,事务

1,概念

所谓事务,就是相当于要将多个执行SQL打包成一个整体,这个整体在执行过程中,能够做到要不都执行完,要不都不执行,这样就可以避免转账转到一半的情况(都不执行:并不是指这些SQL真的没有执行,而是执行了一半,发现出错了,数据库就会自动进行"还原操作"相当于把前面执行过的SQL给撤销了,最终结果就看起来行一个都没有执行这样的效果)这样的机制称为"回滚".

同时,也把事务支持上述"特性"称为原子性.

2,回滚

数据库如何知道具体怎样回滚?数据库内部存在一系列的"日志体系",当开启事务是时候,此时每一步执行SQL,都对数据进行了那些修改,这些信息就会记录在案,后序如果需要回滚,就可以参考之前记录的内容进行还原,这样亦可以应对"程序崩溃"也可以应对"主机掉电",虽然主句掉电,但是回滚的日志还是存在的,此时下次主机上电,数据库启动的时候,就可以根据回滚日志的内容,进行回滚操作了

drop database是不能进行回滚的,回滚操作只针对"事务"来说,开启事务后,就会记录回滚日志,事务执行过程中,出现问题,自动触发回滚,开启事务之后,一个事务内,虽然执行多个SQL,但是也不能执行的内容过多

3,操作:

(1)开启事务:start transaction;

(2)执行多条SQL语句

(3)回滚或提交:rollback/commit;

4,事务的基本特性:

(1)原子性(最重要的特性)

(2)一致性

描述的是,事务执行前和执行后,数据库中的数据都是"合法状态"不出现非法的临时状态

(3)持久性

事务执行完毕,就会修改硬盘上的数据,事务都是持久生效的

(4)隔离性(不好解释)

描述的是多个事务并发执行的时候,相互之间产生的影响是怎样的?

并发执行中会出现的三个问题:

1)脏读

当有两个事务A,B并发执行,其中事务A在针对某个表中的数据进行修改,A执行过程中,B也去读取这个表中的数据,当B读完后,A又将表里的数据改为别的.这将导致B读到的数据不是最终的"正确数据"而是读到了临时性的"脏数据"

解决:给写操作加锁

2)不可重复读

此时有三个事务ABC,首先,事务A执行一个修改操作,A执行完毕后,提交数据,接下来事务B执行,事务B读取刚刚A提交的数据,在B读取的过程中,又来了一个事务C,C又对刚才的A修改的数据再次进行修改,此时,对B来说,后序在读取这个数据,读到的结果就和第一次读到的结果不一样,这个过程就叫做"不可重复读"

注意:这里强到的是一个事务里多次读到的结果是不一样的,但是如果有多个事务,那么每次读到的数据不一样是被认为正常的事情

解决:给读操作加锁(一个数据在读的过程中,其他事务不能进行修改)

3)幻读

相当于不可重复读中的"特殊情况".有一个事务A在读数据,读过程中,另一个事务B新增了/删除了一些其他的数据,此时站在A的视角下,多次读取的内容虽然一样,但是"结果集"不同

解决:"串行化"

MySQL提供了四个隔离等级,提议通过配置文件来设置当前服务器的隔离级别(设置不同的隔离级别,就会使事务之间的并发执行的影响产生不同的差别,从而影响上述三个问题的执行情况):

A,read uncommitted 读未提交:

这种情况下,一个事务可以读取另一个事务未提交的数据,此时,就可能会产生脏读,不可重复读,幻读三种问题,但此时,多个事务并发执行的程度最高,执行速度也是最快的

B,read committed 读已提交

这种情况下,一个事务只能读取另一个事务提交后的数据(写操作加锁),可能会产生不可重复读和幻读,此时,并发执行程度降低,执行速度也会变慢,同时也称为,事务之间的隔离性提高了

C,repeatable read 可重复读

这个情况下,相当于给写操作和读操作都加锁了,可能会产生幻读的问题,但是解决的脏读和不可重复读的问题,此时并发程度进一步降低,执行速度进一步变慢,事务之间的隔离性进一步加强了

D,serializable 串行化

此时,所有的事务都是在服务器上一个接一个执行的,解决了上述所有问题.并发程度最低,执行速度最慢,隔离性最高,数据最准确

三,JDBC

每个数据库本身已经有一套API,比如MySQL,本身的API是C语言的API,就需要把原生C语言的API转化成兼容JDBC的javaAPI.MySQL官方提供了一个mysql-connector,这个既不是MySQL自带的,也不是java自带的,需要通过第三方的途径,把这个东西下载下来导入到自己的项目中

JDBC,即Java Database Connectivity,java数据库连接。是一种用于执行SQL语句的Java API,它是 Java中的数据库连接规范。

复制:  (https://mvnrepository.com/)

粘贴:

-------------------------------------------------------------------------------------------------------------------------

Scanner scanner=new Scanner(System.in);
System.out.println("请输入sn: ");
String sn=scanner.next();
System.out.println("请输入name: ");
String name=scanner.next();

(1)创建数据源对象,描述数据从哪里来的,服务器在哪里

DataSource dataSource =new MysqlDataSource();

((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/myjava?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("0203");
"jdbc:mysql://127.0.0.1:3306/myjava?characterEncoding=utf8&useSSL=false"

URL称为"唯一资源定位符"用来描述一个网络上的资源位置

jdbc:mysql:表示是给jdbc的MySQL来使用的

127.0.0.1:IP地址,描述了MySQL服务器所在主机的位置,这个是一个特殊的ip,表示是是"你本机"

3306:端口号,用来区分一个主机上的应用程序

myjava:数据库名

characterEncoding=utf8:额外的参数起到了针对这次数据库连接解释说明

也可以写成以下写法:

MysqlDataSource mysqlDataSource=new MysqlDataSource();
mysqlDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/myjava?characterEncoding=utf8&useSSL=false");
mysqlDataSource.setUser("root");
mysqlDataSource.setPassword("0203");

(2)和数据库服务器建立连接

Connection connection=dataSource.getConnection();

(3)程序构造SQL语句

String sql="insert into student(sn,name) values(?,?)";
PreparedStatement statement=connection.prepareStatement(sql);
statement.setString(1,sn);
statement.setString(2,name);

(4)把SQL语句发送到服务器中进行执行

int n=statement.executeUpdate();
System.out.println(n);

(5)释放上述资源

statement.close();
connection.close();

-------------------------------------------------------------------------

上述操作为修改数据的操作,查询以下步骤略有不同:

(4)把SQL语句发送到服务器中进行执行

ResultSet resultSet=statement.executeQuery();

(5),遍历

while (resultSet.next()){

System.out.print(resultSet.getString("sn")+" ");

System.out.println(resultSet.getString("name"));

}

(6),释放上述资源

resultSet.close();

statement.close();

connection.close();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值