SQL综合实战:从基础约束到高级应用的完整指南

引言

在数据库管理和应用开发中,SQL是不可或缺的核心技能。无论是简单的数据查询还是复杂的业务逻辑处理,都需要扎实的SQL功底。本文通过两个综合性的SQL练习题,带你系统学习SQL的各项重要功能。

第一题:数据库基础操作全解析

1.1 数据表创建与约束管理

需求分析:创建学生表,要求包含学号、姓名、性别、年龄、所在系字段,并设置相应的约束条件。

复制代码
-- 创建学生表,包含多种约束类型
CREATE TABLE Student (
    Sno VARCHAR(20) PRIMARY KEY,           -- 学号,主键
    Sname VARCHAR(50) UNIQUE NOT NULL,     -- 姓名,唯一且非空
    Ssex ENUM('男', '女') NOT NULL,        -- 性别,枚举约束
    Sage INT NOT NULL,                              -- 年龄
    Sdept VARCHAR(50) DEFAULT '计算机'     -- 所在系,默认值
);

技术要点解析

  • 主键约束 (PRIMARY KEY):确保学号的唯一性,每个学生有唯一标识

  • 唯一约束 (UNIQUE):防止姓名重复,保证数据唯一性

  • 枚举约束 (ENUM):限制性别只能输入'男'或'女',保证数据规范性

  • 默认值 (DEFAULT):简化数据插入,提高开发效率

1.2 表结构修改技巧

业务场景:随着系统演进,需要调整字段数据类型以优化存储空间。

复制代码
-- 修改年龄字段的数据类型
ALTER TABLE Student MODIFY Sage SMALLINT;

优化效果

  • INT 类型占用4字节,存储范围:-2,147,483,648 到 2,147,483,647

  • SMALLINT 类型占用2字节,存储范围:-32,768 到 32,768

  • 对于年龄字段,使用SMALLINT完全足够且节省存储空间

1.3 索引设计与性能优化

业务需求:为选课表创建复合主键索引,提升查询性能。

复制代码
-- 创建复合主键索引
CREATE UNIQUE INDEX SC_INDEX ON SC (Sno, Cno);

索引设计原则

  1. 复合索引顺序:先学号后课程号,符合查询模式

  2. 唯一性保证:防止同一学生重复选同一门课程

  3. 查询优化:加速基于学号和课程号的联合查询

应用场景

复制代码
-- 以下查询将利用索引
SELECT * FROM SC WHERE Sno = '2023001';
SELECT * FROM SC WHERE Sno = '2023001' AND Cno = 'C001';

1.4 视图创建与数据抽象

业务需求:创建视图方便查询学生选课信息。

复制代码
-- 创建学生选课信息视图
CREATE VIEW stu_info AS
SELECT s.Sname, s.Ssex, c.Cname, sc.Score
FROM Student s
JOIN SC sc ON s.Sno = sc.Sno
JOIN Course c ON sc.Cno = c.Cno;

视图的优势

  • 简化复杂查询:隐藏多表连接的复杂性

  • 数据安全性:只暴露必要的字段信息

  • 逻辑独立性:底层表结构变化不影响上层应用

使用示例

复制代码
-- 简单查询所有学生选课信息
SELECT * FROM stu_info;

-- 查询特定性别的学生选课情况
SELECT * FROM stu_info WHERE Ssex = '男';

第二题:存储过程与业务逻辑封装

2.1 部门平均工资统计存储过程

业务需求:创建存储过程统计指定部门的平均工资。

复制代码
DELIMITER //

CREATE PROCEDURE avg_sal_a(
    IN dept_name VARCHAR(50),      -- 输入参数:部门名称
    OUT avg_salary DECIMAL(10,2)   -- 输出参数:平均工资
)
BEGIN
    -- 计算指定部门的平均工资
    SELECT AVG(salary) INTO avg_salary 
    FROM Employee 
    WHERE department = dept_name;
END//

DELIMITER ;

技术特点

  • 参数传递:使用IN参数接收输入,OUT参数返回结果

  • 业务逻辑封装:将复杂计算逻辑封装在数据库中

  • 代码复用:多个应用可以调用同一存储过程

调用示例

复制代码
-- 调用存储过程并获取结果
CALL avg_sal_a('上海中心', @a);
SELECT @a AS 上海中心平均工资;

2.2 部门最高工资查询存储过程

业务需求:根据员工姓名查询其所在部门的最高工资。

复制代码
DELIMITER //

CREATE PROCEDURE get_dept_max_salary(
    IN emp_name VARCHAR(50),       -- 输入参数:员工姓名
    OUT max_salary DECIMAL(10,2)   -- 输出参数:部门最高工资
)
BEGIN
    -- 子查询获取员工部门,再查询该部门最高工资
    SELECT MAX(e.salary) INTO max_salary
    FROM Employee e
    WHERE e.department = (
        SELECT department 
        FROM Employee 
        WHERE name = emp_name
    );
END//

DELIMITER ;

设计思路

  1. 子查询应用:先通过员工姓名查询所在部门

  2. 聚合函数:使用MAX函数计算部门最高工资

  3. 结果返回:通过OUT参数返回计算结果

调用测试

复制代码
-- 测试存储过程功能
CALL get_dept_max_salary('张三', @a);
SELECT @a AS 部门最高工资;

实战技巧与最佳实践

3.1 约束设计的思考

为什么需要约束?

  1. 数据完整性:防止无效数据进入系统

  2. 业务规则:在数据库层面保证业务规则执行

  3. 应用简化:减少应用层的校验逻辑

3.2 索引使用建议

创建索引的时机

  • 频繁作为查询条件的字段

  • 经常需要排序的字段

  • 表数据量较大时

避免过度索引

  • 索引会占用存储空间

  • 影响数据插入、更新、删除性能

3.3 存储过程的优势

性能提升

  • 减少网络传输

  • 预编译执行计划

维护便利

  • 业务逻辑集中管理

  • 修改时不影响应用代码

相关推荐
pengdott5 小时前
Oracle RAC内存融合技术深度解析:集群性能的幕后引擎
数据库·oracle
csudata6 小时前
绿色便携版PostgreSQL发行版重磅发布
数据库·postgresql
阳光九叶草LXGZXJ6 小时前
达梦数据库-学习-48-DmDrs控制台命令(同步之Manager、CPT模块)
linux·运维·数据库·sql·学习
我科绝伦(Huanhuan Zhou)7 小时前
脚本再升级,兼容Oracle 26ai一键安装
数据库·oracle
野生绿箭侠7 小时前
Ncos 2.3.2 版本集成达梦数据库
数据库
仍然.8 小时前
MYSQL--约束
数据库·mysql
乡野码圣8 小时前
【RK3588 Android12】RCU机制
java·jvm·数据库
亓才孓8 小时前
[数据库]应该注意的细节
数据库·sql
m0_561359679 小时前
掌握Python魔法方法(Magic Methods)
jvm·数据库·python
xxxmine9 小时前
redis学习
数据库·redis·学习