MySQL 核心进阶:事务、隔离级别与视图实战

引言

在上一篇文章中,我们学习了 MySQL 的安装配置、基本 SQL 操作以及 C 语言连接数据库。本文将继续深入,讲解 MySQL 的核心高级特性:事务与隔离级别 、视图 、以及复杂查询的基础。这些是面试中的高频考点,也是实际项目开发中保证数据一致性的关键技术。

第一部分:MySQL 体系结构

一、整体架构

组件 功能
连接池 管理客户端连接,支持高并发
SQL 解析器 词法分析、语法分析
优化器 选择最优执行计划(如索引选择)
存储引擎 负责数据读写,可插拔(默认 InnoDB)
文件系统 数据最终持久化到磁盘

第二部分:C 语言查询数据

一、完整查询流程

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>

int main() {
    // 1. 初始化连接句柄
    MYSQL *conn = mysql_init(NULL);
    if (conn == NULL) {
        fprintf(stderr, "mysql_init 失败\n");
        return -1;
    }
    
    // 2. 连接数据库
    if (mysql_real_connect(conn, "127.0.0.1", "root", "123456",
                           "c1100db", 3306, NULL, 0) == NULL) {
        fprintf(stderr, "连接失败: %s\n", mysql_error(conn));
        mysql_close(conn);
        return -1;
    }
    printf("数据库连接成功!\n");
    
    // 3. 执行查询
    const char *sql = "SELECT * FROM student";
    if (mysql_query(conn, sql) != 0) {
        fprintf(stderr, "查询失败: %s\n", mysql_error(conn));
        mysql_close(conn);
        return -1;
    }
    
    // 4. 获取结果集
    MYSQL_RES *result = mysql_store_result(conn);
    if (result == NULL) {
        fprintf(stderr, "获取结果失败: %s\n", mysql_error(conn));
        mysql_close(conn);
        return -1;
    }
    
    // 5. 获取行数和列数
    int num_rows = mysql_num_rows(result);
    unsigned int num_fields = mysql_num_fields(result);
    printf("行数: %d, 列数: %d\n", num_rows, num_fields);
    
    // 6. 逐行逐列打印
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result))) {
        for (unsigned int j = 0; j < num_fields; j++) {
            printf("%s\t", row[j] ? row[j] : "NULL");
        }
        printf("\n");
    }
    
    // 7. 释放结果集和连接
    mysql_free_result(result);
    mysql_close(conn);
    
    return 0;
}

编译运行:

gcc query.c -o query -lmysqlclient

./query

二、结果集处理要点

API 作用 返回值
mysql_store_result() 获取结果集 MYSQL_RES*,失败返回 NULL
mysql_num_rows() 获取行数 int
mysql_num_fields() 获取列数 unsigned int
mysql_fetch_row() 逐行读取 MYSQL_ROW,读完返回 NULL
mysql_free_result() 释放结果集 无

重要提示:

  • MYSQL_ROW 本质是 char**,所有值都是字符串形式

  • 数值型数据需要手动转换(如 atoi(row[0]))

  • 结果集用完后必须调用 mysql_free_result() 释放


第三部分:事务

一、什么是事务

事务是一组 SQL 语句组成的原子操作单元,要么全部执行成功,要么全部回滚。

二、ACID 特性

特性 说明 举例
原子性 (Atomicity) 事务是不可分割的最小单元 转账的两步要么都成,要么都不成
一致性 (Consistency) 事务前后数据状态保持一致 转账前后总金额不变
隔离性 (Isolation) 事务之间互不干扰 A 转账时 B 看不到中间状态
持久性 (Durability) 提交后数据永久保存 断电重启后数据不丢失

面试重点:能够解释 ACID 四个特性及其含义。

三、事务操作命令

cpp 复制代码
-- 开启事务
BEGIN;
-- 或
START TRANSACTION;

-- 执行 SQL 操作...
INSERT INTO student VALUES (1005, '小王', 22);
UPDATE student SET age = 23 WHERE id = 1005;

-- 提交事务(永久保存)
COMMIT;

-- 回滚事务(撤销所有操作)
ROLLBACK;

四、C 语言中控制事务

cpp 复制代码
// 开启事务
mysql_query(conn, "BEGIN");

// 执行多条 SQL
mysql_query(conn, "UPDATE account SET balance = balance - 1000 WHERE id = 1");
mysql_query(conn, "UPDATE account SET balance = balance + 1000 WHERE id = 2");

// 提交事务
mysql_query(conn, "COMMIT");

// 如果出错,回滚
// mysql_query(conn, "ROLLBACK");

第四部分:隔离级别

一、四种隔离级别

隔离级别 脏读 不可重复读 幻读 隔离性
READ UNCOMMITTED(未提交读) ✅ ✅ ✅ 最低
READ COMMITTED(提交读) ❌ ✅ ✅ 中
REPEATABLE READ(可重复读) ❌ ❌ ✅ 较高
SERIALIZABLE(可串行化) ❌ ❌ ❌ 最高

三种并发问题:

二、查看和设置隔离级别

-- 查看当前会话隔离级别

SELECT @@transaction_isolation;

-- 查看全局隔离级别

SELECT @@global.transaction_isolation;

-- 设置会话隔离级别

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 设置全局隔离级别

SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

三、可重复读 (REPEATABLE READ) 演示

这是 MySQL 默认的隔离级别。

四、提交读 (READ COMMITTED) 演示

五、隔离级别选择建议

场景 推荐级别 原因
银行转账 SERIALIZABLE 数据一致性要求极高
订单系统 REPEATABLE READ 默认,平衡性能与一致性
报表查询 READ COMMITTED 需要看到最新已提交数据
日志记录 READ UNCOMMITTED 性能优先,允许少量不一致

第五部分:视图

一、什么是视图

视图是虚拟表,不存储实际数据,数据来源于基本表的查询结果。

二、视图操作

cpp 复制代码
-- 1. 创建视图
CREATE VIEW stu_view AS 
    SELECT id, name FROM student;

-- 2. 查询视图(和查表完全一样)
SELECT * FROM stu_view;
SELECT * FROM stu_view WHERE id > 1001;

-- 3. 查看所有表(含视图)
SHOW FULL TABLES;
-- Base Table → 基本表
-- View       → 视图

-- 4. 删除视图(不影响基本表数据)
DROP VIEW stu_view;

三、视图的优缺点

优点 缺点
保护数据安全(隐藏敏感字段) 不存储数据,每次查询需重新执行
简化复杂查询(封装多表联查) 性能低于直接查询基本表
减少数据冗余 复杂视图可能降低查询效率
灵活调整展示格式 部分视图不可更新

第六部分:索引简介

索引是提升查询性能的核心手段,底层通常采用 B+树 数据结构。

cpp 复制代码
-- 创建索引
CREATE INDEX idx_name ON student(name);

-- 查看索引
SHOW INDEX FROM student;

-- 删除索引
DROP INDEX idx_name ON student;

总结

一、事务与隔离级别

要点 说明
事务操作 BEGIN → 执行SQL → COMMIT/ROLLBACK
ACID 原子性、一致性、隔离性、持久性
默认隔离级别 REPEATABLE READ(可重复读)
隔离级别排序 UNCOMMITTED < COMMITTED < REPEATABLE < SERIALIZABLE

二、视图

cpp 复制代码
CREATE VIEW 视图名 AS SELECT ...
DROP VIEW 视图名;
-- 视图不存数据,本质是封装的 SELECT 语句

三、C 语言查询数据

cpp 复制代码
mysql_init → mysql_real_connect → mysql_query
    → mysql_store_result → mysql_fetch_row (循环)
    → mysql_free_result → mysql_close

四、一句话记忆

事务保证一组 SQL 要么全做要么全不做(ACID),隔离级别控制事务之间的可见性(默认可重复读),视图是封装好的虚拟表用于保护数据和简化查询,索引通过 B+树加速查询但增删改时会付出维护代价。

相关推荐
OceanBase数据库官方博客18 分钟前
被 VLDB 2027接收OceanBase 最新论文让数据库基(技术解析与实践)
数据库·人工智能·oceanbase
颜酱41 分钟前
一栋商业大厦,讲清 InnoDB 的表空间、段、区和页
后端·mysql
创邻科技1 小时前
国产图数据库刷新 LDBC 世界纪录:创邻科技 Galaxybase 在 SF100、SF300、SF1000 测试中全面领先”
数据库·科技
GreatSQL社区1 小时前
主从复制SQL线程中断——字符集砸出的坑
java·数据库·算法
XLYcmy1 小时前
AI 赋能后中文与英文数据库对比分析报告 上
数据库·ai·llm·prompt·检索·wos·cnki
这个DBA有点耶2 小时前
ELT 工具选型完整指南:从 ETL 差异分析到工程落地
数据库·架构·代码规范
IvorySQL2 小时前
PostgreSQL 日报|堆表选择性索引更新(10 月 13 日)
数据库·人工智能·postgresql·开源·区块链
张洛闻Eren2 小时前
Ansible【第一课】:Ansible介绍
运维·数据库·云原生·kubernetes·github·ansible
PC2005-cloud2 小时前
Mysql学习笔记:InnoDB Cluster 集群从零搭建实战,基于 Docker 实现高可用读写分离架构
笔记·学习·mysql
深圳市益普科技有限公司3 小时前
中小封装厂上 MES,为什么十个项目九个坑?
大数据·数据库·人工智能