# 事务 (transaction)

# 何为事务?

  • 一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元 (unit)。在计算机术语中,事务通常就是指数据库事务。

# 事务在数据库的作用

  • 一个数据库事务通常包含对数据库进行读或写的一个操作序列。它的存在包含有以下两个目的:
    • 1、为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
    • 2、当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

# 事务的四大原则

# 原子性 (Atomicity)

  • 原子性保证将每个事务视为一个单独的 “单元”,它要么完全成功,要么完全失败:如果构成事务的任何语句未能完成,则整个事务都会失败,并且数据库将保持不变。
  • 例如:用户 A 给用户 B 进行银行转账,数据库要确保这一事务的两个操作都成功:这两个操作即 A 成功转账给 B,B 成功收到 A 的转账。两个操作缺少一个就失败,这两个操作可看成一个事务。

# 一致性 (Consistency)

  • 事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
  • 例如:用户 A 给用户 B 转账前与转账后,双方的总资产保持不变,即转账事务前后的一致性。

# 隔离性 (Isolation)

  • 多个事务并发时,一个事务不会影响到另一个事务。
  • 例如:用户 B 同时受到用户 A 与 C 的银行转账,此时当两个转账操作结束后,B 的总金额为其原金额加上 A 与 C 转给其的金额总数。即 A 转账 B 和 C 转账 B 两个事务相互隔离,当 A、C 没有确认提交之前,两者转账的钱具有隔离性。

# 持久性 (Durability)

  • 一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。
  • 例如:当 A 把钱转账到 B 账户上时,双方的账户金额在数据库中就会永久保存。

# 隔离的一些问题

# 脏读

  • 指一个事务读取了另一个事务未提交的数据

# 不可重复读

  • 在一个事务内读取表中的某一行数据,多次读取结果不同(不一定是错误,只是场合不对)

# 幻读

  • 指在一个事务内读到了别的事务插入的数据,导致前后读取不一致

# 事务的使用

-- 在默认状态下 MySQL 是开启事务自动提交的
SET autocommit = 0 -- 关闭
SET autocommit = 1 -- 开启
-- 手动处理事务
SET autocommit = 0 -- 关闭自动提交
-- 事务开启
START TRANSACTION -- 标记一个事务的开始,从这里为一个事务内的 SQL
INSERT .....
-- 提交:持久化,即成功
COMMIT
-- 回滚:回到原来的样子,即失败
ROLLBACK
-- 事务结束
SET autocommit = 1 -- 开启

# 索引 (Index)

# 何为索引?

  • 索引是存储引擎用于快速找到记录的一种数据结构.
  • 最常见的例子为书本的目录,我们在一本很厚的书中,需要通过目录找到需要的知识,可以快速精确定位到第几页中,不必一页一页的查找,提高查询效率

# 索引分类

  • 主键索引
    • PRIMARY KEY, 主键不可重复,一个表只有一列可作为主键
  • 唯一索引
    • UNIQUE KEY,唯一索引的使用可以重复,但不可出现相同字段的唯一索引
  • 常规索引
    • INDEX/KEY
  • 全文索引
    • FULLTEXT,只有在 MyISAM 数据库引擎下才有,可快速定位数据

# 基本语法

-- 索引的使用
-- 1. 再创建表的时候给字段增加索引
-- 2. 创建完毕后,增加索引
-- 显示索引的索引信息
SHOW INDEX FROM student
-- 增加一个全文索引
ALTER TABLE school.student ADD FULLTEXT INDEX `studentName` (`studentName`);
-- EXPLAIN 分析 sql 执行情况
EXPLAIN SELECT * FROM student; -- 非全文索引

# 索引原则

  • 索引并不是越多越好
  • 不要对进程变得数据加索引
  • 小数据量的表不需要加索引
  • 素养一把加在常用来查询的字段上

# 索引背后的数据结构

参考文档:http://blog.codinglabs.org/articles/theory-of-mysql-index.html

# 权限管理与备份

# 权限管理的作用

  1. 可以限制用户访问哪些库、哪些表
  2. 可以限制用户对哪些表执行 SELECT、CREATE、DELETE、DELETE、ALTER 等操作
  3. 可以限制用户登录的 IP 或域名
  4. 可以限制用户自己的权限是否可以授权给别的用户

# MYSQL 连接权限

  • 主要依据:
    • 你从哪里来? host
    • 你是谁? user
    • 你的密码是多少? password
  • 通过用户提供的这三个信息,存储 MySQL 库中的 user 表中

# MySQL 执行权限的检查顺序

quanxian

# 用户管理

# 创建用户

  • 有两种方式创建 MySQL 授权用户

    • 方法一、通过 insert 语句直接操作 MySQL 系统权限表

    • 方法二、执行 create user/grant 命令(推荐)

# 创建语法

create user [用户名]@[访问地址] identified by [密码]

# 授权语法

grant [权限1,权限2,权限3] on *.* to user@'host' identified by 'password'

详细资料参考:https://cloud.tencent.com/developer/article/1656008

# 数据库规范

# 三大范式

# 第一范式 (1NF)

  • 原子性,保证每一列不再可分

# 第二范式 (2NF)

  • 必要前提:满足第一范式
  • 每张表只描述一件事情

# 第三范式 (3NF)

  • 必要前提: 满足第一、第二范式
  • 第三范式需要确保数据表中的每一列数据和主键直接相关,而不能间接相关

# 规范与性能的问题

  • 关联查询的表不可超过三张
    • 考虑商业化的需求和目标
    • 适当考虑规范性
    • 故意给某些表增加一些冗余的字段
    • 故意增加一些计算列

# JDBC (重点)

# 数据库驱动

  • 图解:
    qudong

# Java 数据库连接(JDBC)

  • Java 数据库连接(JDBC)是 Java 编程语言的应用程序编程接口(API),它定义了客户端如何访问数据库。它是用于 Java 数据库连接的基于 Java 的数据访问技术。它是 Oracle Corporation 的 Java Standard Edition 平台的一部分。它提供了查询和更新数据库中数据的方法,并且面向关系数据库。

# 编程步骤

  1. 加载驱动程序
Class.forName(driverClass)
// 加载 MySql 驱动
Class.forName("com.mysql.jdbc.Driver")
// 加载 Oracle 驱动
Class.forName("oracle.jdbc.driver.OracleDriver")
  1. 获得数据库连接
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/abc", "root", "root");
  1. 创建 Statement\PreparedStatement 对象:
conn.createStatement();
conn.prepareStatement(sql);
  • 总结:
    • 加载驱动
    • 连接数据库 DriverManager
    • 获得执行 sql 对象 statement
    • 获得返回的结果集
    • 释放连接

# 主要 java 代码

# DriverManager

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url,username,password);
//connection 代表数据库
// 数据库设置自动提交
connection.setAutoCommit();
// 事务提交
connection.commit();
// 事务回滚
connection.rollback();

# URL

String url = "jdbc:mysql://localhost:3306/jdbcstudy......"// 按照实际的数据库 url 填写
// 3306 为 mysql 数据库的端口号

# statement 执行 SQL 的对象 PrepareStatement 执行 SQL 的对象

String sql = "SELECT * FROM users"; // 编写 SQL
statement.executeQuery();// 查询潮州返回的结果集 ResultSet
statement.execute(); // 执行任何 SQL
statement.executeUpdate(); // 为增删改使用

# ResultSet 查询的结果集,封装了所有查询结果

  • 获得指定的数据类型

    resultSet.getObject(); // 在不知道列类型的情况下使用
    // 以下为指导列类型使用
    resultSet.getString();
    resultSet.getInt();
    resultSet.getDate();
  • 遍历

    resultSet.beforeFirst(); // 移到最前面
    resultSet.afterLast(); // 移到最后面
    resultSet.next(); // 移到下一个数据
    resultSet.previous(); // 移到前一行
    resultSet.absoulute(row); // 移动到指定行

# 释放资源

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

# statement 对象

参考资料:https://www.cnblogs.com/EasonJim/p/6994014.html

请我喝[茶]~( ̄▽ ̄)~*

Peter Pan 微信支付

微信支付

Peter Pan 支付宝

支付宝