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 存储过程的优势

性能提升

  • 减少网络传输

  • 预编译执行计划

维护便利

  • 业务逻辑集中管理

  • 修改时不影响应用代码

相关推荐
T***742544 分钟前
redis连接服务
数据库·redis·bootstrap
蜡笔小炘1 小时前
Mysql 结课项目报告
数据库·adb
合作小小程序员小小店1 小时前
桌面开发,点餐管理系统开发,基于C#,winform,sql server数据库
开发语言·数据库·sql·microsoft·c#
一 乐1 小时前
购物|明星周边商城|基于springboot的明星周边商城系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·spring
科普瑞传感仪器1 小时前
从轴孔装配到屏幕贴合:六维力感知的机器人柔性对位应用详解
前端·javascript·数据库·人工智能·机器人·自动化·无人机
m***92381 小时前
Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)
数据库·redis·缓存
e***0962 小时前
MySQL-递归查询
数据库·windows·mysql
('-')2 小时前
《从根上理解MySQL是怎样运行的》第十三章笔记
数据库·笔记·mysql
r***18642 小时前
如何使用C#与SQL Server数据库进行交互
数据库·c#·交互