当前位置: 首页 > news >正文

1-【JavaWeb】数据库基础

计算机网络基础

1. 理解 Socket 技术的基础

Socket 是一种网络编程的工具,能够在网络设备之间传输数据。Java 的 SocketServerSocket 类用于建立 TCP 连接。

2. 使用 Socket 进行数据传输的简单示例

以下代码展示了如何使用 Java 的 SocketServerSocket 类在客户端和服务器端之间传输数据。

服务器端代码:

import java.io.*;
import java.net.*;public class SimpleServer {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8080)) {System.out.println("Server is listening on port 8080");Socket socket = serverSocket.accept();System.out.println("Client connected");// 从客户端读取数据InputStream input = socket.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(input));String message = reader.readLine();System.out.println("Received from client: " + message);// 向客户端发送数据OutputStream output = socket.getOutputStream();PrintWriter writer = new PrintWriter(output, true);writer.println("Hello, client!");socket.close();} catch (IOException ex) {System.out.println("Server exception: " + ex.getMessage());}}
}

客户端代码:

import java.io.*;
import java.net.*;public class SimpleClient {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 8080)) {// 向服务器发送数据OutputStream output = socket.getOutputStream();PrintWriter writer = new PrintWriter(output, true);writer.println("Hello, server!");// 从服务器读取数据InputStream input = socket.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(input));String message = reader.readLine();System.out.println("Received from server: " + message);} catch (IOException ex) {System.out.println("Client exception: " + ex.getMessage());}}
}

3. 使用 Socket 传输文件

Socket 也可以用于传输文件。以下代码示例展示了如何通过 Socket 传输文件:

服务器端代码(接收文件):

import java.io.*;
import java.net.*;public class FileServer {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8080)) {System.out.println("Server is listening on port 8080");Socket socket = serverSocket.accept();System.out.println("Client connected");// 接收文件InputStream input = socket.getInputStream();FileOutputStream fileOutput = new FileOutputStream("received_file.txt");byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = input.read(buffer)) != -1) {fileOutput.write(buffer, 0, bytesRead);}fileOutput.close();socket.close();System.out.println("File received");} catch (IOException ex) {System.out.println("Server exception: " + ex.getMessage());}}
}

客户端代码(发送文件):

import java.io.*;
import java.net.*;public class FileClient {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 8080)) {// 发送文件File file = new File("send_file.txt");FileInputStream fileInput = new FileInputStream(file);OutputStream output = socket.getOutputStream();byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = fileInput.read(buffer)) != -1) {output.write(buffer, 0, bytesRead);}fileInput.close();System.out.println("File sent");} catch (IOException ex) {System.out.println("Client exception: " + ex.getMessage());}}
}

4. 使用浏览器访问 Socket 服务器

我们可以创建一个非常简单的 HTTP 服务器,来响应浏览器的请求。浏览器通过发送 HTTP 请求访问服务器,服务器响应 HTML 页面。

服务器端代码(响应浏览器请求):

import java.io.*;
import java.net.*;public class HttpServer {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8080)) {System.out.println("HTTP Server is listening on port 8080");while (true) {Socket socket = serverSocket.accept();System.out.println("New client connected");// 读取浏览器请求BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String line;while (!(line = reader.readLine()).isEmpty()) {System.out.println(line);  // 打印请求头}// 向浏览器响应 HTMLOutputStream output = socket.getOutputStream();PrintWriter writer = new PrintWriter(output, true);writer.println("HTTP/1.1 200 OK");writer.println("Content-Type: text/html");writer.println();writer.println("<html><body><h1>Hello from Simple HTTP Server</h1></body></html>");socket.close();}} catch (IOException ex) {System.out.println("Server exception: " + ex.getMessage());}}
}
测试步骤:
  1. 运行服务器端程序 HttpServer
  2. 打开浏览器并访问 http://localhost:8080
  3. 浏览器会显示服务器返回的 HTML 内容。

总结

这些示例展示了 Socket 的基础应用、如何通过 Socket 传输数据和文件,以及如何使用浏览器访问一个简单的 Socket 服务器。

数据库基础

1. 什么是数据库

数据库是一种用于存储、管理和检索数据的结构化系统。它允许用户以高效和可靠的方式操作数据。常用的数据库系统管理数据的增删改查(CRUD操作,Create/Retrieve/Update/Delete)。

在 Java 中,我们通常使用 JDBC(Java Database Connectivity)与数据库进行交互。

2. 常见的数据库

以下是一些常见的数据库管理系统:

  • 关系型数据库

    • MySQL:开源、常用的关系型数据库。
    • PostgreSQL:功能丰富的开源数据库,支持复杂查询。
    • Oracle:企业级商业数据库系统。
    • SQL Server:由微软开发,广泛应用于企业。
  • 非关系型数据库(NoSQL)

    • MongoDB:面向文档的数据库,适合大规模数据存储。
    • Cassandra:分布式的NoSQL数据库,用于处理大量数据。

3. 数据模型

数据模型用于描述数据的结构、关系和约束。常见的数据模型包括:

  • 层次模型:数据以树的形式组织,每个记录有父子关系。
  • 网状模型:数据通过图来表示,记录间可以有多对多的关系。
  • 关系模型:数据通过表(关系)来表示,是目前最常用的模型。

在关系模型中,数据通过行和列存储。每个表中的一行代表一个记录,列表示字段或属性。关系数据库系统(RDBMS)使用 SQL(Structured Query Language)来操作数据。

4. 数据库的创建

我们以 MySQL 为例,展示如何通过 Java 使用 JDBC 创建数据库、表和插入数据。

连接到 MySQL 数据库并创建数据库:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;public class CreateDatabaseExample {public static void main(String[] args) {String jdbcURL = "jdbc:mysql://localhost:3306/";String username = "root";String password = "password";  // 你的MySQL密码try (Connection connection = DriverManager.getConnection(jdbcURL, username, password)) {Statement statement = connection.createStatement();String sql = "CREATE DATABASE IF NOT EXISTS TestDB";statement.executeUpdate(sql);System.out.println("Database created successfully");} catch (Exception e) {e.printStackTrace();}}
}

创建表并插入数据:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;public class CreateTableExample {public static void main(String[] args) {String jdbcURL = "jdbc:mysql://localhost:3306/TestDB";String username = "root";String password = "password";try (Connection connection = DriverManager.getConnection(jdbcURL, username, password)) {Statement statement = connection.createStatement();// 创建表String createTableSQL = "CREATE TABLE IF NOT EXISTS Users (" +"ID INT PRIMARY KEY AUTO_INCREMENT, " +"Name VARCHAR(50), " +"Email VARCHAR(50))";statement.executeUpdate(createTableSQL);System.out.println("Table created successfully");// 插入数据String insertSQL = "INSERT INTO Users (Name, Email) VALUES ('Alice', 'alice@example.com')";statement.executeUpdate(insertSQL);System.out.println("Data inserted successfully");} catch (Exception e) {e.printStackTrace();}}
}

5. 数据库的规范化

数据库规范化是一个设计过程,其目的是通过消除数据冗余、确保数据一致性来提高数据库的效率。规范化将数据库分为多个表,并通过外键(foreign key)来保持数据的关系。

  • 第一范式(1NF):确保每个表中的字段是不可分的原子值。
  • 第二范式(2NF):消除部分依赖,即非主键字段必须完全依赖主键。
  • 第三范式(3NF):消除传递依赖,非主键字段不应该依赖其他非主键字段。

举例:规范化一个数据库

假设我们有一个未规范化的表 Orders,它包括订单信息和客户信息:

OrderIDCustomerNameCustomerAddressProductNameQuantity
1Alice123 StreetLaptop1
2Bob456 AvenuePhone2

为了规范化,我们可以将这个表拆分为两个表,一个存储订单信息,另一个存储客户信息。

  • Orders

    OrderIDCustomerIDProductNameQuantity
    1101Laptop1
    2102Phone2
  • Customers

    CustomerIDCustomerNameCustomerAddress
    101Alice123 Street
    102Bob456 Avenue

这样,客户的信息被单独存储,每次订单只需引用客户的 CustomerID,避免了重复存储客户数据。

补充

BCNF(Boyce-Codd范式)是第三范式(3NF)的一个更严格的版本。它的目标是确保每个非平凡的函数依赖关系都符合范式要求,进一步消除数据冗余和异常情况。

BCNF 的定义

BCNF 要求:

  • 表格中的每一个决定属性(determinant)必须是一个候选键。

候选键是表中的唯一标识一个记录的字段或字段组合。

如果一个表已经满足第三范式,但仍然存在非主属性依赖于非主键的情况,就需要将表进一步分解到 BCNF。

BCNF 与 3NF 的区别

BCNF 主要解决的是 3NF 不能解决的“非主属性依赖于候选键的部分”问题。简单来说:

  • 3NF 解决非主键字段对主键的传递依赖问题。
  • BCNF 解决主属性依赖于非主键的问题(候选键的依赖关系)。

BCNF 的例子

假设我们有一个表 StudentCourse,记录学生选修课程的情况:

StudentIDCourseIDInstructorInstructorOffice
1CS101Dr. SmithRoom 101
2CS101Dr. SmithRoom 101
3CS102Dr. JohnsonRoom 202
  • StudentID 是学生的唯一标识。
  • CourseID 是课程的唯一标识。
  • Instructor 是课程的授课老师,每个课程由一个固定的老师教授,并且每个老师都有一个固定的办公室。

在这个例子中,我们可以看到以下依赖关系:

  • StudentID -> CourseID
  • CourseID -> InstructorInstructorOffice

我们可以看到,CourseID 决定了 InstructorInstructorOffice,这意味着 InstructorInstructorOffice 依赖于 CourseID,而不是完全依赖于 StudentID(主键)。

此时,虽然这个表可能已经符合 3NF,但它并不符合 BCNF,因为 CourseID 是一个决定属性,但它不是候选键(即它不能唯一标识一行)。

将表分解为 BCNF

要将这个表分解为符合 BCNF 的表格,我们需要把 InstructorInstructorOffice 的依赖从原始表中移除。我们可以创建两个表:

  1. StudentCourse

    StudentIDCourseID
    1CS101
    2CS101
    3CS102
  2. CourseInstructor

    CourseIDInstructorInstructorOffice
    CS101Dr. SmithRoom 101
    CS102Dr. JohnsonRoom 202

现在,StudentCourse 表中每一行的数据依赖于候选键 StudentID,而 CourseInstructor 表中,每一行的数据依赖于候选键 CourseID,这就满足了 BCNF。

BCNF 的总结

  • BCNF 是 3NF 的加强版本,它消除了 3NF 不能消除的某些依赖关系。
  • BCNF 的要求是每一个决定属性必须是候选键。
  • 当表中的非主键属性依赖于候选键的部分属性时,就需要将其分解到 BCNF。

通过将表分解为多个表,BCNF 进一步减少了数据冗余,并确保了数据一致性和完整性。

总结

  • 数据库 是存储和管理数据的工具,常见的数据库有 MySQL、PostgreSQL、MongoDB 等。
  • 数据模型 描述了数据的组织方式,关系模型是最常见的数据模型。
  • 数据库创建 通过 SQL 和 JDBC 实现,Java 提供了强大的工具来与数据库进行交互。
  • 数据库规范化 是设计数据库的关键步骤,可以消除冗余并提高数据的完整性。

SQL

1. SQL 简介

SQL(Structured Query Language,结构化查询语言)是一种用于管理关系型数据库的数据查询语言。它允许用户执行以下操作:

  • 查询数据(SELECT)
  • 插入数据(INSERT)
  • 更新数据(UPDATE)
  • 删除数据(DELETE)
  • 创建表修改表结构(CREATE、ALTER、DROP)

2. 创建数据库和表

2.1 创建数据库

CREATE DATABASE TestDB;

2.2 选择数据库

USE TestDB;

2.3 创建表

CREATE TABLE Users (ID INT PRIMARY KEY AUTO_INCREMENT,Name VARCHAR(50),Email VARCHAR(50),Age INT
);

3. 插入数据

INSERT INTO Users (Name, Email, Age)
VALUES ('Alice', 'alice@example.com', 25);INSERT INTO Users (Name, Email, Age)
VALUES ('Bob', 'bob@example.com', 30);

4. 查询数据

4.1 查询所有列

SELECT * FROM Users;

4.2 查询指定列

SELECT Name, Email FROM Users;

4.3 添加条件(WHERE)

SELECT * FROM Users WHERE Age > 25;

4.4 使用 ANDOR 条件

SELECT * FROM Users WHERE Age > 25 AND Name = 'Bob';

4.5 使用 LIKE 模糊匹配

SELECT * FROM Users WHERE Name LIKE 'A%';  -- 查找名字以A开头的用户

4.6 排序查询结果(ORDER BY)

SELECT * FROM Users ORDER BY Age DESC;

5. 更新数据

UPDATE Users
SET Age = 26
WHERE Name = 'Alice';

6. 删除数据

6.1 删除特定数据

DELETE FROM Users WHERE Name = 'Bob';

6.2 删除所有数据

DELETE FROM Users;  -- 仅删除数据,保留表结构

7. 表的修改

7.1 添加新列

ALTER TABLE Users ADD PhoneNumber VARCHAR(15);

7.2 修改列的数据类型

ALTER TABLE Users MODIFY Email VARCHAR(100);

7.3 删除列

ALTER TABLE Users DROP COLUMN PhoneNumber;

8. 连接查询(JOIN)

8.1 内连接(INNER JOIN)

SELECT Orders.OrderID, Users.Name, Orders.Product
FROM Orders
INNER JOIN Users ON Orders.UserID = Users.ID;

8.2 左连接(LEFT JOIN)

SELECT Users.Name, Orders.Product
FROM Users
LEFT JOIN Orders ON Users.ID = Orders.UserID;

9. 聚合函数

9.1 计数(COUNT)

SELECT COUNT(*) FROM Users;

9.2 最大值、最小值(MAX, MIN)

SELECT MAX(Age) FROM Users;
SELECT MIN(Age) FROM Users;

9.3 平均值(AVG)

SELECT AVG(Age) FROM Users;

9.4 求和(SUM)

SELECT SUM(Age) FROM Users;

10. 分组(GROUP BY)

SELECT Age, COUNT(*) FROM Users
GROUP BY Age;

11. 子查询

11.1 简单子查询

SELECT Name FROM Users
WHERE Age = (SELECT MAX(Age) FROM Users);

11.2 关联子查询

SELECT Name FROM Users u
WHERE EXISTS (SELECT 1 FROM Orders o WHERE o.UserID = u.ID);

12. 视图(View)

12.1 创建视图

CREATE VIEW UserOrders AS
SELECT Users.Name, Orders.Product
FROM Users
JOIN Orders ON Users.ID = Orders.UserID;

12.2 查询视图

SELECT * FROM UserOrders;

12.3 删除视图

DROP VIEW UserOrders;

13. 事务(Transactions)

事务确保一系列的 SQL 操作要么全部成功,要么全部失败。

13.1 开始事务

START TRANSACTION;

13.2 提交事务

COMMIT;

13.3 回滚事务

ROLLBACK;

14. 索引(Indexes)

索引用于加速数据检索。

14.1 创建索引

CREATE INDEX idx_name ON Users (Name);

14.2 删除索引

DROP INDEX idx_name ON Users;

15. 数据库的约束

  • NOT NULL:确保字段不能为空。
  • UNIQUE:确保字段中的所有值唯一。
  • PRIMARY KEY:唯一标识表中的每条记录。
  • FOREIGN KEY:用来链接两个表。

15.1 创建带约束的表

CREATE TABLE Orders (OrderID INT PRIMARY KEY,UserID INT,Product VARCHAR(100),FOREIGN KEY (UserID) REFERENCES Users(ID)
);

16. 正则化(Normalization)

数据库的正则化用于减少冗余数据并确保数据一致性。常见的正则化范式包括:

  • 第一范式 (1NF):消除重复的列,确保每列原子化。
  • 第二范式 (2NF):消除部分依赖,确保所有非主键字段依赖于主键。
  • 第三范式 (3NF):消除传递依赖,确保非主键字段不依赖于其他非主键字段。
  • BCNF:消除所有非主键依赖。

数据库查询语言(DQL)

在 SQL 中,根据操作类型的不同,可以将 SQL 分为不同的类别,如数据定义语言(DDL)、数据操纵语言(DML)、数据库查询语言(DQL)和数据库控制语言(DCL)。下面我们专注于 数据库查询语言(DQL)数据库控制语言(DCL)

1. 数据库查询语言(DQL)

DQL(Data Query Language,数据查询语言)主要用于从数据库中检索数据。它的核心命令是 SELECT,允许用户执行复杂的查询操作,如过滤、排序、分组、聚合等。

核心语句:SELECT

SELECT 语句是 DQL 的基础,它允许从一个或多个表中检索数据。

基础用法

SELECT column1, column2, ...
FROM table_name;
  • column1, column2:要检索的列。
  • table_name:数据所在的表名。

DQL 常见操作

  1. 查询所有数据

    SELECT * FROM Users;
    
    • 使用 * 可以检索表中的所有列。
  2. 条件查询(WHERE)

    SELECT Name, Email FROM Users WHERE Age > 25;
    
    • WHERE 子句用于过滤结果。
  3. 排序查询结果(ORDER BY)

    SELECT Name, Age FROM Users ORDER BY Age DESC;
    
    • ORDER BY 用于按指定列排序,ASC 表示升序(默认),DESC 表示降序。
  4. 分组(GROUP BY)

    SELECT Age, COUNT(*) FROM Users GROUP BY Age;
    
    • GROUP BY 用于对结果进行分组。
  5. 聚合函数

    • COUNT:计数。
    • SUM:求和。
    • AVG:求平均值。
    • MAX:求最大值。
    • MIN:求最小值。

    例子:

    SELECT AVG(Age) FROM Users;
    
  6. 连接查询(JOIN)

    SELECT Orders.OrderID, Users.Name, Orders.Product
    FROM Orders
    INNER JOIN Users ON Orders.UserID = Users.ID;
    
    • INNER JOIN 通过匹配两个表的字段来获取相关联的数据。

复杂查询示例

SELECT u.Name, u.Email, o.Product
FROM Users u
INNER JOIN Orders o ON u.ID = o.UserID
WHERE u.Age > 25
ORDER BY u.Name ASC;
  • 该查询会检索用户 Users 和订单 Orders 中的相关数据,按用户名升序排列。

2. 数据库控制语言(DCL)

DCL(Data Control Language,数据控制语言)用于控制数据库中的权限和访问,主要是对用户的权限进行授予和撤销,确保数据库的安全性。

核心语句:GRANTREVOKE
  • GRANT:用于向用户授予权限。
  • REVOKE:用于从用户撤销权限。
常见 DCL 操作
  1. 创建用户
    在授予权限之前,通常需要先创建用户:

    CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
    
    • username 是新用户的用户名,password 是用户的密码。
  2. 授予权限(GRANT)

    GRANT SELECT, INSERT ON TestDB.Users TO 'username'@'localhost';
    
    • 该语句授予用户 usernameTestDB 数据库中的 Users 表执行 SELECT(查询)和 INSERT(插入)的权限。
  3. 查看当前用户的权限

    SHOW GRANTS FOR 'username'@'localhost';
    
    • 该语句显示给定用户的权限列表。
  4. 撤销权限(REVOKE)

    REVOKE SELECT ON TestDB.Users FROM 'username'@'localhost';
    
    • 该语句撤销用户 usernameTestDB.Users 表的 SELECT 权限。
  5. 授予所有权限

    GRANT ALL PRIVILEGES ON TestDB.* TO 'username'@'localhost';
    
    • ALL PRIVILEGES 表示授予所有权限,TestDB.* 表示该用户拥有对 TestDB 数据库中所有表的完全访问权限。
  6. 撤销所有权限

    REVOKE ALL PRIVILEGES ON TestDB.* FROM 'username'@'localhost';
    
    • 该语句撤销用户对 TestDB 数据库中所有表的所有权限。
权限级别

权限可以在不同级别上授予:

  • 数据库级别:对整个数据库授予权限。
    GRANT SELECT ON TestDB.* TO 'username'@'localhost';
    
  • 表级别:仅对指定表授予权限。
    GRANT INSERT, UPDATE ON TestDB.Users TO 'username'@'localhost';
    
  • 列级别:仅对指定列授予权限。
    GRANT SELECT (Name, Email) ON TestDB.Users TO 'username'@'localhost';
    
  • 特定操作:如授予某些高级权限,比如 GRANT OPTION 允许用户向其他用户授予权限。

3. 总结

DQL(数据库查询语言)
  • 主要用于从数据库中检索数据,核心命令是 SELECT
  • 可以通过 WHEREORDER BYGROUP BYJOIN 等来实现复杂查询和数据分析。
DCL(数据库控制语言)
  • 用于管理用户权限,确保数据库安全。
  • GRANT 用于授予权限,REVOKE 用于撤销权限。

通过熟练掌握 DQL 和 DCL,您可以轻松实现数据库的数据查询操作,并确保数据库访问的安全性。

视图、索引、触发器、事务

1. 视图(View)

概念

视图是一个虚拟表,它基于 SQL 查询的结果集。视图并不存储实际数据,它只是一个查询的逻辑表示,帮助简化复杂查询、提高安全性和增强数据抽象。

使用场景
  • 简化查询:将复杂的 SQL 查询封装在视图中,简化数据访问。
  • 数据安全:通过视图限制用户对敏感数据的访问。
  • 提高可重用性:避免多次重复相同的复杂查询。

创建视图的语法

CREATE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;

视图的示例

创建一个显示用户信息的视图:

CREATE VIEW UserDetails AS
SELECT Name, Email, Age
FROM Users
WHERE Age > 18;

现在你可以像查询表一样查询 UserDetails 视图:

SELECT * FROM UserDetails;

更新视图

有些视图是可更新的,允许通过视图更新基础表的数据。更新视图的语法与更新表相同:

UPDATE UserDetails
SET Age = 30
WHERE Name = 'Alice';

注意:并不是所有视图都是可更新的,尤其是涉及到多表连接、聚合等操作的视图。

删除视图

DROP VIEW UserDetails;

2. 索引(Index)

概念

索引是数据库对象,用于加快查询操作的速度。索引类似于书本的目录,它使得数据库能够更快速地定位所需数据。

使用场景

  • 加速查询:大幅提高 SELECT 语句的执行速度。
  • 强制唯一性:例如在主键或唯一约束上创建索引。
  • 排序:索引还可以用于加速排序操作(ORDER BY)。

创建索引的语法

CREATE INDEX index_name ON table_name (column1, column2, ...);

索引的示例

Users 表的 Name 列创建索引:

CREATE INDEX idx_name ON Users (Name);

删除索引

DROP INDEX idx_name ON Users;

索引的注意事项

  • 虽然索引能加速查询,但也会占用存储空间,并可能减慢插入、更新和删除操作。
  • 不要在小表或者频繁更新的列上创建索引,因为索引维护的开销可能大于它带来的性能提升。

3. 触发器(Trigger)

概念

触发器是一个自动执行的 SQL 语句,它在某些事件发生时触发。触发器通常与 INSERTUPDATEDELETE 操作相关联,能够在这些操作之前或之后自动执行某些操作。

使用场景
  • 数据完整性:确保在插入或更新数据时满足特定业务规则。
  • 自动日志记录:在数据更新时自动保存修改记录。
  • 复杂验证:在数据修改前后执行复杂的业务逻辑。

创建触发器的语法

CREATE TRIGGER trigger_name
AFTER | BEFORE INSERT | UPDATE | DELETE
ON table_name
FOR EACH ROW
BEGIN-- 触发器逻辑
END;

触发器的示例

Users 表中创建一个触发器,当插入新用户时,自动将他们的姓名转换为大写:

CREATE TRIGGER before_insert_user
BEFORE INSERT ON Users
FOR EACH ROW
BEGINSET NEW.Name = UPPER(NEW.Name);
END;
  • BEFORE:在 INSERT 之前触发。
  • NEW:表示新插入的数据。

删除触发器

DROP TRIGGER trigger_name;

触发器的注意事项

  • 触发器是自动执行的,因此要谨慎使用,以免引起循环或性能问题。
  • 过多的触发器会影响数据库的性能,尤其是高频率触发的操作。

4. 事务(Transaction)

概念

事务是一组 SQL 操作的集合,这些操作要么全部成功,要么全部失败。事务的主要作用是保证数据库的完整性和一致性,尤其是在涉及多个表的复杂操作时。事务遵循 ACID 特性:

  • A(原子性):事务是不可分割的操作单位,要么全部完成,要么全部不执行。
  • C(一致性):事务执行前后,数据库处于一致的状态。
  • I(隔离性):多个事务并发执行时,互不干扰。
  • D(持久性):事务提交后,其结果永久保存,即使数据库系统崩溃。

使用场景

  • 多步操作:比如银行转账,涉及账户扣款和存款,两步操作必须要么都成功,要么都失败。
  • 数据一致性要求:确保多个相关表的更新操作一致完成。

事务的语法

  1. 开启事务

    START TRANSACTION;
    
  2. 提交事务

    COMMIT;
    
  3. 回滚事务(撤销未提交的更改):

    ROLLBACK;
    

事务的示例

银行转账示例,用户 A 转账给用户 B:

START TRANSACTION;-- 从用户 A 的账户中扣除 100
UPDATE Accounts
SET Balance = Balance - 100
WHERE UserID = 'A';-- 向用户 B 的账户中存入 100
UPDATE Accounts
SET Balance = Balance + 100
WHERE UserID = 'B';-- 提交事务
COMMIT;

如果在操作过程中任何一步失败,则可以回滚事务,取消所有更改:

ROLLBACK;

自动提交和手动提交

  • 默认情况下,很多数据库系统(如 MySQL)在每个独立的 SQL 语句之后自动提交事务。这种模式称为 自动提交
  • 如果你想要手动控制事务,应该禁用自动提交:
    SET AUTOCOMMIT = 0;
    

事务的注意事项

  • 在执行批量操作时,使用事务可以保证数据一致性。
  • 过多的长时间事务会锁定资源,导致性能下降,因此要合理使用事务。

总结

  • 视图:视图是 SQL 查询的逻辑表示,它帮助简化查询、提高安全性和数据抽象。
  • 索引:索引用于加快查询速度,但需要权衡其在插入、更新和删除操作上的性能开销。
  • 触发器:触发器是在特定事件发生时自动执行的 SQL 语句,适用于确保数据完整性和自动化操作。
  • 事务:事务是一组 SQL 操作,确保数据库在操作失败时保持一致性,并遵循 ACID 原则。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 生日贺卡录放音芯片,多段音频录音ic生产厂商,NVF04M-32minute
  • java中redis集群模式和哨兵模式的区别和联系?
  • Java:动态代理
  • CSP-CCF★★★201812-2小明放学★★★
  • Unity 热更 之 【YooAsset 热更】Unity 可以进行热更的资源管理系统,并 【Android 端简单实现·案例热更】
  • ABAP JSON处理应用
  • CKAD-CronJob
  • 伟易特发布全新一代便携式反无人机装备
  • Vue组件:动态组件、缓存组件、异步组件
  • CentOs7 解决yum更新源报错:[Errno 14] HTTP Error 404 - Not Found 正在尝试其它镜像。
  • 微信小程序登录与获取手机号 (Python)
  • 计算机毕业设计Spark+PyTorch知识图谱中药推荐系统 中药数据分析可视化大屏 中药爬虫 机器学习 中药预测系统 中药情感分析 大数据毕业设计
  • opencv学习:信用卡卡号识别
  • 别总是“系统错误,请稍后重试!”了,解决问题要彻底!
  • 铲屎官都该知道的除浮毛神器——希喂、美的、352宠物空气净化器
  • Google 是如何开发 Web 框架的
  • [case10]使用RSQL实现端到端的动态查询
  • 2017年终总结、随想
  • CEF与代理
  • classpath对获取配置文件的影响
  • Cookie 在前端中的实践
  • Cumulo 的 ClojureScript 模块已经成型
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Javascript Math对象和Date对象常用方法详解
  • k8s 面向应用开发者的基础命令
  • LeetCode18.四数之和 JavaScript
  • linux安装openssl、swoole等扩展的具体步骤
  • PaddlePaddle-GitHub的正确打开姿势
  • React Transition Group -- Transition 组件
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Shadow DOM 内部构造及如何构建独立组件
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • windows下mongoDB的环境配置
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 机器学习学习笔记一
  • 批量截取pdf文件
  • 微信小程序填坑清单
  • 想写好前端,先练好内功
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • puppet连载22:define用法
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • # centos7下FFmpeg环境部署记录
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #nginx配置案例
  • (4.10~4.16)
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析