当前位置:首页 > 随笔 > 正文内容

MySQL 核心概念与高级应用实践

访客 随笔 2026年6月27日 1

数据库基础概述

数据库(Database)是用于持久化存储结构化数据的系统,而数据库管理系统(DBMS)则是管理与操作这些数据的核心工具。在关系型数据库中,数据以表格形式组织,每张表由行和列构成。

  • 表(Table):数据存储的基本单元。
  • 字段(Column):表示某一类属性,如姓名、年龄等。
  • 元组(Tuple):即表中的一行记录。
  • 主键(Primary Key):唯一标识一条记录的字段,不可为空且必须唯一。
  • 数据冗余:相同数据在多处重复出现,应尽量避免。
  • 数据完整性:确保数据准确性和一致性,例如唯一约束、外键约束等。

SQL 分类说明

结构化查询语言(SQL)按功能可分为三类:

  1. DDL(数据定义语言):用于定义或修改数据库结构。
    • CREATE TABLE:创建表
    • ALTER TABLE:修改表结构
    • DROP TABLE:删除表
  2. DML(数据操作语言):处理数据本身。
    • INSERT:插入新数据
    • UPDATE:更新已有数据
    • DELETE:删除数据
    • SELECT:查询数据
  3. DCL(数据控制语言):管理访问权限。
    • GRANT:授予权限
    • REVOKE:撤销权限

MySQL 常用操作命令

切换数据库使用:
USE database_name;

创建数据库:
CREATE DATABASE db_example;

删除数据库:
DROP DATABASE db_example;

创建与管理数据表

CREATE TABLE employee (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    gender CHAR(2),
    age INT,
    salary DECIMAL(10,2),
    hire_date DATE
);

添加主键约束(若未在建表时指定):
ALTER TABLE employee ADD CONSTRAINT PK_EMP_ID PRIMARY KEY (id);

查看表结构:
DESC employee;

查看建表语句(格式化输出):
SHOW CREATE TABLE employee \G

数据增删改查操作

插入数据:
INSERT INTO employee (name, gender, age, salary, hire_date) VALUES ('Alice', '女', 28, 8500.00, '2023-04-15');

更新数据:
UPDATE employee SET salary = 9000.00 WHERE name = 'Alice';

删除数据:
DELETE FROM employee WHERE age < 18;

复杂查询示例

查询所有员工信息:
SELECT * FROM employee;

投影特定字段:
SELECT name, salary FROM employee;

设置别名显示:
SELECT name AS 姓名, salary AS 薪资 FROM employee;

去重查询:
SELECT DISTINCT age FROM employee;

条件筛选:
SELECT * FROM employee WHERE id < 3;

分页查询(跳过前4条取2条):
SELECT * FROM employee LIMIT 4, 2;

计算字段:
SELECT name, salary, salary * 1.2 AS bonus FROM employee;

逻辑组合查询:
SELECT * FROM employee WHERE gender = '男' AND salary > 5000 AND department = '人事部';

范围查询(两种写法等价):
SELECT * FROM employee WHERE age BETWEEN 20 AND 22;
SELECT * FROM employee WHERE age >= 20 AND age <= 22;

枚举匹配:
SELECT * FROM employee WHERE age IN (19, 20, 25, 30);

模糊匹配:
SELECT * FROM employee WHERE name LIKE '%L%'; — 包含L
SELECT * FROM employee WHERE name LIKE '张%'; — 姓张
SELECT * FROM employee WHERE name LIKE '李_'; — 李开头且两个字
SELECT * FROM employee WHERE name NOT LIKE '李%'; — 不以李开头

空值判断:
SELECT * FROM employee WHERE department IS NULL;

排序规则(先按薪资降序,再按年龄升序):
SELECT * FROM employee ORDER BY salary DESC, age ASC;

聚合函数与分组统计

统计销售部门整体情况:
SELECT
COUNT(id) AS 总人数,
SUM(salary) * 12 AS 年总支出,
AVG(salary) AS 平均月薪,
MAX(salary) AS 最高薪,
MIN(salary) AS 最低薪,
AVG(age) AS 平均年龄
FROM employee
WHERE department = '销售部';

各部门平均薪资并过滤结果:
SELECT department, AVG(salary) AS avg_salary
FROM employee
GROUP BY department
HAVING avg_salary > 5000;

事务处理机制

事务具备四大特性(ACID):

  • 原子性:操作要么全部成功,要么全部回滚。
  • 一致性:事务前后数据状态保持一致。
  • 隔离性:并发执行互不干扰。
  • 持久性:提交后数据永久保存。

转账示例(张三给李四转500元):

SET autocommit = 0;
START TRANSACTION;
UPDATE bank SET balance = balance - 500 WHERE name = '张三';
UPDATE bank SET balance = balance + 500 WHERE name = '李四';

-- 若出错可回滚
ROLLBACK;

-- 正常则提交
COMMIT;

常用内置函数

字符串函数

SELECT LENGTH('hello');           -- 长度
SELECT SUBSTR('hello', 2, 3);     -- 截取子串
SELECT CONCAT('A', 'B', 'C');     -- 拼接
SELECT TRIM('  abc  ');           -- 去除空格
SELECT LOWER('ABC'), UPPER('abc');-- 大小写转换
SELECT REPLACE('张 三', ' ', ''); -- 替换字符
SELECT LOCATE('b', 'abcde');      -- 查找位置

数学函数

SELECT RAND();                    -- 随机数
SELECT POW(3, 4);                 -- 幂运算
SELECT FLOOR(5.6);                -- 向下取整
SELECT CEILING(5.6);              -- 向上取整
SELECT ROUND(5.456, 2);           -- 四舍五入保留两位

日期函数

SELECT NOW(), SYSDATE();                          -- 当前时间
SELECT DATEDIFF('2017-08-10', '2017-08-07');       -- 天数差
SELECT DATE_ADD('2017-08-07', INTERVAL 7 DAY);     -- 加减日期
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d');             -- 格式化输出

类型转换函数

SELECT CAST('123' AS UNSIGNED);                   -- 转为无符号整型
SELECT CONVERT('456', SIGNED);                     -- 转为有符号整型

自定义函数示例

创建一个计算某学员平均成绩的函数:

DELIMITER //
CREATE FUNCTION get_avg_score(student_id INT)
RETURNS DECIMAL(5,2)
READS SQL DATA
BEGIN
    DECLARE avg_result DECIMAL(5,2);
    SELECT AVG(score) INTO avg_result FROM j_score WHERE sno = student_id;
    RETURN IFNULL(avg_result, 0);
END //
DELIMITER ;

-- 使用方式
SELECT get_avg_score(1);

子查询优化建议

使用 EXISTS 替代 IN 提升性能,尤其在子查询数据量较大时:

-- 推荐写法(高效)
SELECT * FROM j_student s1 
WHERE NOT EXISTS (
  SELECT 1 FROM j_score WHERE sno = s1.sno
);

-- 不推荐(大数据量下效率低)
SELECT * FROM j_student 
WHERE sno NOT IN (SELECT sno FROM j_score);

一般建议:子查询返回记录不超过一万条时才考虑使用 IN

存储过程编写

存储过程可包含变量、流程控制和循环结构。

DELIMITER //
CREATE PROCEDURE proc_find_student()
BEGIN
    DECLARE var_name VARCHAR(50) DEFAULT '张三';
    
    -- 查询赋值
    SELECT sname INTO var_name FROM j_student WHERE sno = 1;
    
    -- 条件判断
    IF var_name = '张三' THEN
        SELECT '找到张三' AS result;
    ELSEIF var_name = '李四' THEN
        SELECT '找到李四' AS result;
    ELSE
        SELECT '未知用户' AS result;
    END IF;
END //
DELIMITER ;

循环结构示例

使用 LOOP 实现删除编号从600到699的数据:

DELIMITER //
CREATE PROCEDURE delete_batch_students()
BEGIN
    DECLARE idx INT DEFAULT 600;
    
    del_loop: LOOP
        DELETE FROM j_student WHERE sno = idx;
        SET idx = idx + 1;
        
        IF idx >= 700 THEN
            LEAVE del_loop;
        END IF;
    END LOOP;
END //
DELIMITER ;

CALL delete_batch_students();

数据库设计范式

良好的表结构设计需遵循规范化原则:

  1. 第一范式(1NF):确保每一列都是不可分割的原子值。例如地址字段不应包含"国家+省+市"混合内容。
  2. 第二范式(2NF):在满足1NF基础上,非主键字段完全依赖于整个主键(适用于联合主键场景)。
  3. 第三范式(3NF):消除传递依赖,所有非主键字段直接依赖主键,而非通过其他非主键字段间接依赖。

实际开发中,通常满足前两范式即可,过度规范化可能影响查询性能。

ER 图与模型设计

实体关系图(ER Diagram)是数据库建模的重要工具,帮助可视化表之间的关联关系,如一对多、多对多等。

相关文章

可以按小时收费的VPS

很多 VPS 提供商都支持 按小时计费(hourly billing),想短期试用 / 临时搭建节点、测试网络、短期项目等场景非常合适。下面是当前最主流且靠谱的按小时 VPS 选项,分别按不同需求场景整理: 1. Vultr(全球节点,包括日本) 按小时计费 可选机房:东京 / 大阪 / 洛杉矶 / 法兰克福 / 伦敦 … 支持 PayPal(部分情况),但更常用信用卡/PayPal+卡价格参考$...

在 iPhone 上下载国外App

地区/国家限制App Store 会根据 Apple ID 的国家或地区限制应用下载。如果你的 Apple ID 绑定的是中国大陆,就可能无法下载 OpenAI 官方的 ChatGPT 应用,因为它在大陆 App Store 不上架。解决办法:换成美国、加拿大、香港等地区的 Apple ID。或者在现有 Apple ID 上更改地区。注册一个国外 Apple ID(推荐)比如注册 美国区 Appl...

Node.js 中的异步编程:回调与 Promise

Node.js 是一个基于 JavaScript 构建的单线程、非阻塞运行环境,它通过异步编程机制来高效处理多个操作。在执行如文件读取、API 请求或数据库查询等任务时,Node.js 不会等待这些操作完成,而是使用回调函数和 Promise 来避免阻塞主线程。 回调方式实现异步 那么当异步操作完成后,Node.js 如何知道接下来要做什么呢?这就要用到 回调函数(callback)。 回调本质上...

Selenium自动化测试入门指南

Selenium自动化测试入门指南

什么是自动化测试? 自动化测试是指利用软件工具自动执行测试用例,模拟用户操作,如打开网页、点击链接、输入文本等,并验证结果是否符合预期。 其主要优点包括: 大幅减少人工成本 测试速度快 可以在非工作时间运行 支持持续集成和交付 然而,它也存在一些局限性,例如开发成本较高、不适合快速变化的项目、依赖稳定的UI界面等。 自动化测试的应用条件 适合引入自动化测试的情况包括: 手动测试耗时且需要大量...

MariaDB Galera集群故障快速恢复指南

OpenStack控制节点采用三节点MariaDB Galera集群架构。当数据库集群因故障重启时,有时会出现Galera集群无法正常启动的问题。虽然有多种方法可以恢复数据库服务,但如何实现快速启动同时确保数据完整性呢? 通过分析日志发现,MariaDB Galera集群节点宕机时会在日志中输出以下信息: [Note] WSREP: 新集群视图:全局状态: 874d8e7e-5980-11e8-8...

Android 中 EventBus 的通信机制与实现原理深度解析

EventBus 核心设计思想 EventBus 是一个基于观察者模式的事件总线框架,广泛应用于 Android 平台以实现组件解耦。它通过中心化的消息分发机制,使不同层级、不同线程的对象能够以"发布-订阅"方式通信,避免了传统接口回调或广播带来的强依赖问题。 核心角色说明 事件(Event):任意 Java 对象,作为数据载体,如网络状态变更通知、用户登录信息等。 发布者(Publi...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。