前言:本篇博客介绍如何速通MySQL的第四篇,主要介绍Mysql中主要的基础的入门,学习MySQL之前要先安装好MySQL,如果还没有安装的小伙伴可以看看博主前面的博客,里面有详细的安装教程。或者看一下下面这个链接,以及第一篇还没看的也建议先看第一篇噢~
如何安装Mysql
【MySQL】如何速通MySQL(1)
【MySQL】如何速通MySQL(2)
【MySQL】如何速通MySQL(3)
在第三篇如何速通MySQL中我们学习了MySQL中的增删改查进阶和表的设计,有基础部分就有进阶部分嘛,接下来介绍的就是一些抽象的知识和如何和Java联系起来~话不多说,走起!
关于如何速通MySQL(3)中篇幅过长,没有介绍联合查询,想看联合查询的小伙伴可以转看这里噢~
【MySQL】MySQL表之联合查询(多表查询)
✅索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现,它可以提高查询效率、减少查询时间和减轻数据库负担。
对于数据库中的索引:
要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。
创建主键约束(PRIMARY KEY)、唯一约束(UNIQUE)、外键约束(FOREIGN KEY)时,会自动创建对应列的索引。
①.查看索引
show index from 表名
//show index from company;//查看公司表已有索引
查看索引的命令很简单,我们可以查看一下上面公司表的索引:
mysql> show index from company;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| company | 0 | PRIMARY | 1 | id | A | 7 | NULL | NULL | | BTREE | | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
上面的表中表示该表名为 company,索引类型为 B-Tree 索引,包含了一个主键索引(PRIMARY KEY),非唯一性索引(Non_unique = 0),索引名为 PRIMARY,索引的第一个列(Seq_in_index)为 id,使用的排序方式(Collation)为 A(升序排序),索引的基数(Cardinality)为 7等信息。
该索引的作用是加速对 company 表中 id 列的查询和排序操作。由于该表的主键索引是唯一性索引,因此查询时不会出现重复记录。
②.创建索引
对于非主键、非唯一约束、非外键的字段,可以创建普通索引
create index 索引名 on 表名(字段名);
//create index idx_company_name on company(name);
在company表中创建关于name的索引:
mysql> show index from company;
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| company | 0 | PRIMARY | 1 | id | A | 7 | NULL | NULL | | BTREE | | |
| company | 1 | idx_company_name | 1 | name | A | 7 | NULL | NULL | | BTREE | | |
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
③.删除索引
drop index 索引名 on 表名;
//drop index idx_company_name on company(name);
在 MySQL 中,事务是指一系列操作组成的逻辑单元,这些操作要么全部执行,要么全部撤销。
为什么要有事务呢,我们先用例子来了解一下:
有一天,小绿找小蓝借钱去约会,小蓝在转钱的时候但是数据库挂了,刚执行到减少小蓝2000余额的时候,后续操作即在小绿账户增加2000的数据库命令没有被执行…
这样子不就悲剧了?小蓝没了2000,小绿没了女神,我们得到了一个笑话,不不不,对于人道主义来说,还是要解决一下的!事务的本质就是将SQL命令打包,要么全部执行成功,要么全不执行。
解决方案:使用事务来控制,保证以上两句SQL要么全部执行成功,要么全部执行失败。
这就是数据库事务四个基本特性的其中一个,原子性,并不是说真的不执行,而是遇到执行到一半失败后,执行回滚操作,恢复到执行前的状态。既然讲到数据库事务四个基本特性,我们先来简单了解一下:
ACID是数据库事务的四个基本特性的首字母缩写,分别是:
ACID是保证数据库事务正确执行和维护数据完整性的基础,这四个特性的组合能够确保在数据库的多个事务并发执行时,数据库的正确性和数据的一致性得到保障。同时,ACID也为数据库应用提供了可靠性和安全性,确保数据的正确性和稳定性。
正如上面说的一样,过去的人们将原子认为是事物能够分割的最小单位,所以原子性就是,将这一系列操作看成是一个原子事件,要么全部执行成功,要么全部执行失败,不存在部分执行的情况。在执行过程中,如果出现故障或者错误,需要进行回滚操作,将数据库恢复到事务开始前的状态。
此处需要额外的部分来记录事务中的操作步骤,数据库里专门有个用来记录事务的日志,正因为如此,使用事务的时候,执行sql的开销会更大,效率会更低
在数据库使用时:
(1)开启事务: start transaction;
(2)执行多条SQL语句
(3)回滚或提交: rollback/commit;
说明: rollback即是全部失败,commit即是全部成功。
mysql> start transaction;//开启日志
mysql> insert into company(name, role, salary) values ('虾兵','小弟', 1599.20);//中间就是本事务要执行的每一步
mysql> insert into company(name, role, salary) values ('蟹将','小弟', 2000.99);//中间就是本事务要执行的每一步
mysql> commit;//提交事务,相当于事务执行完了
一致性(Consistency)指的是事务执行前后,数据库必须保持一致性状态。这里的一致性状态主要指的是数据的约束条件和完整性,例如主键、外键、唯一性约束、默认值、检查约束等。
具体来说,在 MySQL 中,可以通过以下方式来保证数据的一致性:
在 MySQL 中,持久性(Durability)是 ACID四种属性之一,指的是一旦一个事务被提交,其所做的修改就会永久保存到数据库中,即使系统崩溃也不会丢失数据。
实现持久性通常需要使用日志(Log)机制。在 MySQL 中,每个写操作都会被记录到 redo log(重做日志)中,只有当 redo log 中的所有操作都成功写入磁盘后,事务才被认为是持久性的。
当系统故障或者重启时,MySQL 会自动从 redo log 中恢复数据,确保数据不会丢失。同时,MySQL 也提供了多种备份和恢复机制,以确保数据的可靠性和可用性。
在 MySQL 中,隔离性(Isolation)是 ACID四种属性之一,指的是在多个并发事务同时修改数据库中的数据时,每个事务所看到的数据都必须与其期望的一致。隔离性的目的是为了保证各个并发事务之间的数据相互隔离,不会互相影响。
上面说到,ACID是保证多个事务并发执行的时候不会相互影响,实际上,并发性事务可能产生的问题主要有下面几个:
1.脏读问题
一个事务A正在对数据进行修改的过程中,还没提交之前,另外的事务B,也对同一个数据进行了读取,此时B的读操作就称为"脏读",读到的数据也称为"脏数据"。
解决方法:mysql引入写操作加锁,就是写操作和读操作不能并发,当写的时候禁止读,这样的加锁操作,降低并发程序(降低效率),提高隔离性(提高数据的准确性)
2.不可重复读
当事务1已经提交数据,此时事务2开始读数据,在读取过程中,事务3又提交了新的数据,此时意味着同一个事务2之内,多次读数据,读出来的结果是不一样的(预期是一个事务中,多次读取结果是一样的,就叫做不可重复读)
解决方法:mysql引入写操作加锁,就是读操作和写操作不能并发,当读的时候禁止写,同样是降低事务的并发能力,提高事务的隔离性
3.幻读
在读加锁和写加锁的前提下,一个事务两次读取同一个数据,发现读取的数据值是一样的,但是结果集不一样(如Student.java代码内容不变,但是第一次看到的只有Student.java这个文件,第二次看到的是Student.java和Teacher.java)
解决方法:数据库"串行化"这样的方式来解决幻读,彻底放弃并发处理事务,一个接一个的串行的处理事务。这样做并发程序是最低的(效率最慢的),隔离性也是最高的。
对应上述问题,mysql提供了4种隔离级别,就对应上面几个情况:
隔离级别 | 说明 |
---|---|
read uncommitted(读取未提交的数据) | 没有进行任何锁限制,并发最高(效率最高),隔离性最低(准确性最低) |
read committed(读取已提交的数据) | 给写加锁,并发程度降低,隔离性也提高了 |
repeatable read(可重复读) | 给写和读都加锁,并发性继续降低,隔离性又提高了 |
serializable(串行化) | 串行化,并发程度最低,隔离性最高 |
以上是MySQL内置的机制,可以通过修改mysql的配置文件,来设置当前mysql工作在哪种状态下,而上面的隔离级别如何选择,需要在实际需求中看业务场景,在准确性和效率之间衡量,比如转账的时候准确性要拉满,效率并不关键,而视频点赞等,要求快狠准,追求的是效率,准确性就不那么关键了。
B+树是一种为了数据结构索引、量身定做的数据结构。它是一种高效的索引结构,被广泛用于数据库和文件系统等应用中。
B+树是一种多路搜索树,区别于二叉搜索树,它允许每个节点存储多个关键字和数据信息。在B+树 中,所有数据都存储在叶子节点中,而非内部节点,而且所有叶子节点都有序排列形成一个链表,这使得 B+树可以支持范围查询和顺序遍历等操作。
要了解B+树,我们得先了解B树:
B树是一种平衡多路搜索树,它能够在进行大量数据插入、删除、查找等操作时保持较好的平衡性能。
B树的节点有多个孩子,通常用一个数组来存放关键字和指向孩子节点的指针。B树的每个节点都有一个阶数,表示该节点最多包含的关键字数量。一棵m阶的B树有以下几个特点:
B树的平衡性能主要由它的节点阶数决定,节点阶数越大,B树高度越小,查找、插入和删除操作的效率越高。B树广泛应用于数据库系统中,如Oracle、MySQL等。
B+树的主要优点是支持高效的插入、查找、删除和遍历操作,可以快速定位到目标数据。同时,B+树还支持范围查询和排序等操作,因此被广泛应用于数据库和文件系统等领域。
B+树的特点:
①一个节点,可以存储N个key,N个key划分出了N个区间(而不是如B树的N+1个区间)
②每个节点中的key的值,都会在子节点中也存在(同时该key是子节点的最大值)
③B+树的叶子节点,是首位相连的,类似于一个链表
④由于叶子节点,是完整的数据集合,只在叶子节点这里存储数据表的每一行数据,而非叶子节点,只存key值本身即可
B+树的优势:
①.当前一个节点保存更多的key,最终树的高度是相对较矮的,查询的时候减少IO的访问次数(和B树一样,IO特指硬盘的访问)
②.所有的查询最终都会落在叶子节点上(查询任何一个数据,经过IO访问次数,是一样的),稳定,可以让程序员对于程序的执行效率有一个更准确的评估
③.B+树的所有叶子节点,构成链表,此时比较方便进行范围查询(如果查询5~11的数据,只需要先找5,再找11,沿着链表遍历即可)
B树和B+树是两种常见的平衡搜索树,它们有很多相似之处,但也有一些细节上的不同。
总之,B+树相对于B树来说,能够提高查询效率以及降低存储开销,并且适合在磁盘等外存介质上使用,因此在大规模数据存储和处理方面具有优越性。
最后,关于MySQL的表结构:MySQL组织数据的方式,我们看见一张"表"的时候,实际上这个表不一定是按照"表格"这样的数据,结构在硬盘上组织的,也有可能是按照这种树形结构组织。(具体是哪种结构,取决于表中有没有索引,以及数据库使用了哪种存储)
在各种数据库中,MySQL,Oracle,SQL Server在开发的时候,就会提供一组编程接口(API)。基于一些功能去使用就可以了。对于数据库MySQL和Java之间,我们就用到了JDBC编程。
JDBC,即Java Database Connectivity
,java数据库连接。是一种用于执行SQL语句的Java API,它是Java中的数据库连接规范。这个API由 java.sql.*,javax.sql.*
包中的一些类和接口组成,它为Java开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问。
通过DataSource(数据源)对象获取。实际应用中会使用DataSource对象:
DataSource ds = new MysqlDataSource();
((MysqlDataSource) ds).setUrl("jdbc:mysql://localhost:3306/test?");
((MysqlDataSource) ds).setUser("root");
((MysqlDataSource) ds).setPassword("root");
Connection connection = ds.getConnection();
这里不详细讲解JDBC的使用,只简单演示备份代码:
对于JDBC查询数据库数据代码:
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBC_Select {
public static void main(String[] args) throws SQLException {
//JDBC 需要通过以下步骤来完成开发
//1.创建并初始化一个数据源
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java001?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");
//2.建立连接
dataSource.getConnection();
Connection connection = dataSource.getConnection();
//3.构造SQL
String sql = "select * from student";
PreparedStatement statement = connection.prepareStatement(sql);
//4.执行SQL语句
ResultSet resultSet = statement.executeQuery();
//5.遍历结果集合
while(resultSet.next()){
// 把 resultSet 想象成一个表格,同时表格这里有一个光标, 初始情况下光标指向表最上面
// 每次调用 next,光标往下走一行
// 当光标指向某一行的时候,就可以通过 getXXX 来获取到当前这行里的数据
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("id = "+ id + ", name = "+name);
}
//6.释放必要的资源
statement.close();
connection.close();
}
}
对于JDBC增加数据库数据代码:
public class JDBC_Insert {
public static void main(String[] args) throws SQLException {
//JDBC 需要通过以下步骤来完成开发
//1.创建并初始化一个数据源
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java001?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");
//2.和数据库服务器建立连接
dataSource.getConnection();
Connection connection = dataSource.getConnection();
//3.从控制台读取用户输入信息
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生姓名:");
String name = scanner.next();
System.out.println("请输入学号:");
int id = scanner.nextInt();
//4.构造SQL语句
//String sql = "insert into student value(1, 'zs')";//插入的是写死的数据(硬代码)
//String sql = "insert into student value("+ id +", '"+ name +"')";有可能sql注入
String sql = "insert into student value(?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1,id);
statement.setString(2,name);
//5.执行SQL语句
int ret = statement.executeUpdate();
System.out.println("ret = " + ret);
System.out.println(statement);
//6.释放必要的资源
statement.close();
connection.close();
}
}
这就是本篇如何速通MySQL全部内容啦,欢迎关注。一起学习,共同努力!
还有一件事: