文章目录
1.索引的含义以及应用
2.索引的查看、创建
3.带主键的索引底层结构
4.事务的含义
5.事务的特性
6.JDBC
一.索引的含义及应用
1.索引我们可以认为是文章的目录,有了它,我们可以更加快速的 查看到我们想要查找的内容。
2.并不是说我们加了索引,就一定会是查找的速度变快,例如数据存在大量重复的情况或者数据量特别少的情况。
3.索引会使查找数据的速度变快,但会是增删改数据的速度变慢,因为进行增删改就需要对索引进行调整(目录),索引还提高了空间的开销,构建索引,需要额外的空间来保存,但总体上加上索引会使进行增删改查的速度变快,因为增删改查大部分时间都是在查找操作。
4.索引创建好以后,不需要我们手动使用,直接查询的时候会走索引,实际上具体这一次操作走不走索引,数据库的执行引擎会自动评估,到底走不走索引,我们也可以用expalin这个关键字,来显示查询过程中索引的具体使用情况。
二.索引的查看、创建的删除
1.索引的查看:
show index from 表名
主键会自带一个索引
2.索引的创建:
create index 索引名 on 表名(列名)
3.索引的删除:
drop index 索引名 on 表名
三.索引的底层结构:
首先大家可以考虑一下索引的底层会不会是哈希表呢?答案是否定的,因为我们哈希表只能比较相等。
那会不会是二叉搜索树呢?其实也不是的,因为当元素个数多的时候,树的高度也就会比较高,树的高度也决定了查询时候元素的比较次数会多,数据库进行比较时,是会读硬盘的。
那B树是不是呢?
我们看到一个节点上的数值多了,这样读写硬盘的次数就减少了,因为每个结点都是在硬盘上的。
实际上索引的底层结构也不是它
实际上对于带有主键的表,索引的底层是B+树
叶子结点会用一种了类似于链表的方式连接起来,叶子结点包含了所有结点的值。
这种结构的好处:1.树的高度变低,硬盘IO的次数就会减少
2.更适合范围查询,直接在叶子结点找到数据范围最小值和最大值就可以了
3.比较次数比较均匀,按照图来看,数据基本上都在3次多
4因为叶子结点包含所有的key,会包含所有的数据,而非叶子节点,只会保留一条数据id,这样非叶子结点我们可以把它放在内存里就可以了,进一步降低了硬盘IO。
事务
含义:将多个SQL打包到一起,作为一个整体执行,要么操作就全部执行,要么一旦出现异常,就都会回到原来的样子。数据库会把执行的每个操作记录下来,如果某个操作出错,就恢复到原来的样子,比如删除 会恢复到插入,修改会恢复到原来的样子,这个过程叫做‘’回滚‘’。
举个例子:我们转账的时候,我们给别人转账了50,自己的钱包会少50,而别人的钱包却没增加50,这时候会恢复到原来没转钱的状态。
事务的特性:
1.原子性。是指将多个SQL打包一同执行。
2.稳定性,事务产生的修改会保留下来会写入硬盘,不会因为突发情况而丢失,比如断电。
3.一致性,事务执行前后数据的要合法,比如像刚才的转账出现的状况就是不合法的
4.隔离性:指事务之间的影响程度。
JDBC
JDBC为多种关系数据库提供了统一的访问方式,为java开发人员操作数据库提供了统一的访问方式。
应用JDBC通常分为四个步骤:
1.建立数据库连接
2.创建操作命令
3.执行SQL语句
4.处理结果集
5.释放资源
增删改 的操作大体一样,只需换一下SQL语句
public static void main(String[] args) throws SQLException {
//1.先去创建DataSource 数据源,描述了mysql数据库在哪
MysqlDataSource datasource=new MysqlDataSource();
((MysqlDataSource)datasource).setURL("jdbc:mysql://127.0.0.1:3306/java_114?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)datasource).setUser("root");
((MysqlDataSource)datasource).setPassword("1291691906");
//2.和数据库建立连接
Connection connection=datasource.getConnection();
Scanner scanner=new Scanner(System.in);
System.out.println("请输入id");
int id=scanner.nextInt();
System.out.println("请输入name");
String name=scanner.next();
//3.构造SQL语句
String sql="insert into student values(?,?)";
//4.创建操作命令Statement对象,使用操作命令来执行SQL,将SQL语句发送到数据库里在这里对SQL语句进行词性语法的分析,SQL语句会预编译
PreparedStatement statement=connection.prepareStatement(sql);
statement.setInt(1,id);
statement.setString(2,name);
int ret=statement.executeUpdate();//executeUpdate()返回一个整数值,ret表示此次SQL语句操作影响了多少行。
System.out.println(ret);
System.out.println("sql:"+statement);
//5.断开连接,释放资源,先创立的后释放。
statement.close();
connection.close();
}
public static void main(String[] args) throws SQLException {
DataSource datasource=new MysqlDataSource();
((MysqlDataSource)datasource).setURL("jdbc:mysql://127.0.0.1:3306/java_114?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)datasource).setUser("root");
((MysqlDataSource)datasource).setPassword("1291691906");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入id");
int id=scanner.nextInt();
System.out.println("请输入name");
String name=scanner.next();
Connection connection=datasource.getConnection();
String sql="update student set id=? where name=?";
PreparedStatement statement=connection.prepareStatement(sql);
statement.setInt(1,id);
statement.setString(2,name);
//statement.setString(2,name);
int ret=statement.executeUpdate();
System.out.println(ret);
System.out.println(statement);
statement.close();
connection.close();
}
ublic static void main(String[] args) throws SQLException {
DataSource dataSource=new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java_114?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("1291691906");
Connection connection=dataSource.getConnection();
Scanner scanner=new Scanner(System.in);
System.out.println("请输入id");
int id=scanner.nextInt();
System.out.println("请输入姓名");
String name=scanner.next();
String sql="delete from student where id=? or name=?";
PreparedStatement statement=connection.prepareStatement(sql);
statement.setInt(1,id);
statement.setString(2,name);
int ret=statement.executeUpdate();
System.out.println(ret);
System.out.println("sql:"+statement);
statement.close();
connection.close();
}
查找:
public static void main(String[] args) throws SQLException {
1.先去创建DataSource 数据源,描述了mysql数据库在哪
DataSource datasource=new MysqlDataSource();
((MysqlDataSource)datasource).setURL("jdbc:mysql://127.0.0.1:3306/java_114?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)datasource).setUser("root");
((MysqlDataSource)datasource).setPassword("1291691906");
//2.和数据库建立连接
Connection connection=datasource.getConnection();
//3.构造SQL语句
String sql="select*from student";
//4.创建操作命令Statement对象,使用操作命令来执行SQL,将SQL语句发送到数据库里,对SQL语句进行词性语法的分析。
PreparedStatement statement=connection.prepareStatement(sql);
//5.ResultSet对象被称为结果集,代表符合所有SQL语句条件的数据,并且可以通过getxx方法访问每一行的数据
ResultSet resultSet=statement.executeQuery();//返回单个结果集
while(resultSet.next())//将数据一行一行的往下遍历。
{
int id=resultSet.getInt("id");//获取当前行的id的值
String name=resultSet.getString("name");//获取当前行name的值
System.out.println("id:"+id+" "+"name:"+name);
}
//释放资源。先创立的后释放
resultSet.close();
statement.close();
connection.close();
}
ResultSet是一个结果集,它里面的数据一行一行排列,每行有多个字段,并且有一个记录指针,依次往下遍历指针所指的数据叫做当前数据行,如果想要获取某一行,使用Reslut对象里的next()方法,想要获取ResultSet对象里的所有行,可以用whlie循环
Connection接口实现类由数据库提供获取Connection对象通常有两种方式:1.DriverManner(驱动管理类)的静态方法获取2.通过DataSource(数据源)对象获取,实际中我们采用DataSource对象。
这两种方式的区别1.DriverManger类获取的Connection连接,是无法重复利用的,每次使用完释放资源后,通过Connection.close()关闭物理连接。
2.DataSource提供连接池的支持,连接池在初始化时将创建一定数量的数据库连接,这些连接是可以复用的,每次使用完数据库连接时,释放资源调用connection.close()将Connection对象回收。
Statement对象,将SQL语句发送到数据库里,JDBC API主要提供了三种Statement对象
1.Statement
用于执行不带参数的简单的SQL语句
2.PreparedStatement
用于执行带或者不带参数的SQL语句
SQL语句会预编译在数据库系统
CallableStatement
用于执行数据库存储过程的调用。实际开发中,我们常用PreparedStatement对象。
PreparedStatement对象:两种执行SQL的方法
1.executeQuery()方法执行后返回单个结果集,通常用于select语句
2.executeUpdate()方法返回一个整数,表示受影响的行数,通常用于update、insert、delete语句