[数据库] SQL Server 入门学习笔记:从建库建表到复杂查询实战

29 0
Honkers 3 小时前 来自手机 | 显示全部楼层 |阅读模式

前言

数据库是应用程序的“数据心脏”,没有数据库,程序只能处理临时数据。这一周我们从“什么是数据库”开始,逐步深入到表的创建、约束的定义、数据的增删改查,再到多表关联查询和事务处理,帮助零基础读者快速上手。

一、数据库基础概念

1.1 什么是数据库

数据库(DB,DataBase):按照数据结构来组织、存储和管理数据的仓库。

简单说,就像 Excel 文件,但数据库能处理更大规模的数据,并且提供强大的查询和管理能力。

1.2 关键术语

术语全称含义
DBDataBase数据库
DBMSDataBase Management System数据库管理系统(如 SQL Server、MySQL)
DBADataBase Administrator数据库管理员
SASuper Administrator超级管理员(SQL Server 中的最高权限账户)

1.3 主流关系型数据库

数据库厂商特点
Oracle甲骨文功能强大,收费,大型企业
MySQL甲骨文开源免费,中小型项目
SQL Server微软与 .NET 集成好,中小企业
DB2IBM稳定性高,大型企业

💡 我们学习的是 SQL Server 2014,它是微软推出的关系型数据库管理系统,非常适合与 C#/.NET 配合开发。


二、SQL Server 环境与数据库操作

2.1 启动服务

可通过两种方式启动 SQL Server 服务:

  • 服务管理:我的电脑 → 管理 → 服务 → SQL Server (MSSQLSERVER) → 启动/停止

  • 命令行

    1. net start mssqlserver / net stop mssqlserver
    复制代码

2.2 连接服务器(SSMS)

打开 SQL Server Management Studio(SSMS):

  • 服务器类型:数据库引擎

  • 服务器名称:. 或 127.0.0.1 或本机名称(代表本机)

  • 身份验证

    • Windows 身份验证(无需账户)

    • SQL Server 身份验证(用户名 sa,密码自己设置)

2.3 系统数据库

SQL Server 安装后自带四个系统数据库:

  • master:记录所有系统信息

  • model:新数据库的模板

  • msdb:代理服务(计划任务、备份等)

  • tempdb:临时数据存储(重启后清空)

2.4 创建用户数据库

  1. -- 也可以使用图形界面:右键“数据库” → 新建数据库
  2. CREATE DATABASE MySchool
  3. ON PRIMARY
  4. (
  5. NAME = MySchool_data,
  6. FILENAME = 'C:\Program Files\MySchool.mdf',
  7. SIZE = 5MB,
  8. MAXSIZE = 100MB,
  9. FILEGROWTH = 10%
  10. )
  11. LOG ON
  12. (
  13. NAME = MySchool_log,
  14. FILENAME = 'C:\Program Files\MySchool.ldf',
  15. SIZE = 2MB,
  16. MAXSIZE = 50MB,
  17. FILEGROWTH = 1MB
  18. );
复制代码
  • mdf:主数据文件(只能有一个)

  • .ndf:次要数据文件(可有多个)

  • .ldf:事务日志文件(至少一个)


三、数据类型详解

创建表时必须为每列指定数据类型,这是域完整性的第一道防线。

3.1 字符类型

类型说明存储方式
char(n)固定长度非 Unicode长度固定 n,不足补空格,效率高
varchar(n)可变长度非 Unicode长度可变,节省空间,效率略低
nchar(n)固定长度 Unicode支持多语言,长度固定
nvarchar(n)可变长度 Unicode支持多语言,节省空间

选择建议:如果确定长度且不需要多语言,用 char;不确定长度用 varchar;需要存储中文等多字节字符,用 nchar/nvarchar。

3.2 数值类型

类型说明
int整数(-21亿 ~ 21亿)
smallint小整数
float / real浮点数
money货币类型,默认4位小数
bit布尔值(0 或 1)

⚠️ 身份证号不能存为 int(因为有 X,且长度可能超过 int 范围),应用 varchar(18)。

3.3 日期时间

  • datetime:存储日期和时间(如 '2026-08-07 14:30:00')

3.4 其他

  • image:存储二进制数据(图片等,但建议用文件路径代替)


四、表的创建与约束(数据完整性)

(在SQL中并不区分大小写,所以不必特意大写。)

数据完整性指的是数据的准确性可靠性,它是数据库设计的核心。完整性分为四类:

4.1 实体完整性(行级)

保证每一行数据是唯一的、可识别的。

  • 主键约束(Primary Key):唯一且非空。一张表只能有一个主键。

  • 唯一约束(Unique):值唯一,但允许有一个 NULL。

  • 标识列(Identity):自动生成数字,无需手动输入。如 identity(1,1) 表示从1开始,每次增1。

    1. -- 创建学生表
    2. CREATE TABLE Student
    3. (
    4. Id INT PRIMARY KEY IDENTITY(1,1), -- 主键+标识列
    5. StuNo VARCHAR(20) UNIQUE, -- 学号唯一
    6. Name NVARCHAR(20) NOT NULL -- 非空
    7. );
    复制代码

4.2 域完整性(列级)

保证列的数据符合预期格式和范围。

  • 数据类型(上面已讲)

  • 非空约束(NOT NULL)

  • 默认值约束(DEFAULT)

  • 检查约束(CHECK):自定义表达式验证数据。

    1. CREATE TABLE Employee
    2. (
    3. Id INT PRIMARY KEY IDENTITY,
    4. Name NVARCHAR(20) NOT NULL,
    5. Gender CHAR(2) CHECK (Gender IN ('男', '女')), -- 性别只能男或女
    6. Age INT CHECK (Age BETWEEN 18 AND 60), -- 年龄18~60
    7. IDCard CHAR(18) CHECK (LEN(IDCard) = 18) -- 身份证18位
    8. );
    复制代码

4.3 引用完整性(表间)

通过外键(Foreign Key) 保证两个表之间的数据一致性。

  • 外键引用的列必须是主键或唯一键(通常为主键)。

  • 数据类型必须一致。

  • 先有主键值,才能添加外键值。

  • 删除主键值时,必须先删除所有引用的外键值。

    1. -- 部门表(主键表)
    2. CREATE TABLE Dept
    3. (
    4. Id INT PRIMARY KEY IDENTITY,
    5. Name NVARCHAR(20)
    6. );
    7. -- 员工表(外键表)
    8. CREATE TABLE Emp
    9. (
    10. Id INT PRIMARY KEY IDENTITY,
    11. Name NVARCHAR(20),
    12. DeptId INT FOREIGN KEY REFERENCES Dept(Id) -- 外键
    13. );
    复制代码

4.4 自定义完整性

通常由业务逻辑保证(如触发器、存储过程等),此阶段暂不深入。

五、T-SQL 数据操作语言(DML)

T-SQL 是 SQL Server 对标准 SQL 的扩展,主要包括 DDL(数据定义)、DML(数据操作)、DCL(数据控制)。这里重点学习 DML。

5.1 插入数据(INSERT)

  1. -- 指定列插入(推荐)
  2. INSERT INTO Student (Name, Gender, Age) VALUES ('张三', '男', 20);
  3. -- 不指定列(需按表定义顺序)
  4. INSERT INTO Student VALUES ('李四', '女', 22); -- 若表有标识列,则忽略
  5. -- 批量插入
  6. INSERT INTO Student (Name, Gender, Age) VALUES
  7. ('王五', '男', 21),
  8. ('赵六', '女', 23);
复制代码

注意

  • 字符串用单引号包裹。

  • 标识列不能手动插入。

  • 默认值可用 DEFAULT 关键字。

5.2 更新数据(UPDATE)

  1. -- 没有加上 WHERE 条件,会更新整张表(危险!)
  2. UPDATE Student SET Age = Age + 1;
  3. -- 带条件的更新(推荐)
  4. UPDATE Student SET Age = Age + 1 WHERE Name = '张三';
  5. -- 多列更新
  6. UPDATE Student SET Gender = '女', Age = 25 WHERE Id = 1;
复制代码

5.3 删除数据(DELETE / TRUNCATE)

  1. -- 删除指定行
  2. DELETE FROM Student WHERE Id = 5;
  3. -- 删除所有行(保留表结构,日志记录每条删除)
  4. DELETE FROM Student;
  5. -- 快速清空表(释放空间,重置标识列,不可恢复)
  6. TRUNCATE TABLE Student;
  7. -- 删除表(表结构也被删除)
  8. DROP TABLE Student;
复制代码
操作速度日志标识列可恢复
DELETE逐行记录不重置可以
TRUNCATE页释放记录重置不可以
DROP最快删表不可以

5.4 查询数据(SELECT)

基础查询

  1. -- 查询所有列
  2. SELECT * FROM Student;
  3. -- 查询指定列
  4. SELECT Name, Age FROM Student;
  5. -- 使用别名(AS可省略)
  6. SELECT Name AS 姓名, Age 年龄 FROM Student;
  7. -- 带条件查询(WHERE)
  8. SELECT * FROM Student WHERE Age > 20 AND Gender = '男';
  9. -- 范围查询(BETWEEN)
  10. SELECT * FROM Student WHERE Age BETWEEN 18 AND 25;
  11. -- 模糊查询(LIKE)
  12. -- % 代表任意个字符,_ 代表一个字符
  13. SELECT * FROM Student WHERE Name LIKE '张%'; -- 姓张的
  14. SELECT * FROM Student WHERE Name LIKE '李_'; -- 两个字姓李的
  15. -- 排序(ORDER BY)
  16. SELECT * FROM Student ORDER BY Age DESC; -- 降序
  17. -- 空值判断(IS NULL / IS NOT NULL)
  18. SELECT * FROM Student WHERE Bonus IS NULL;
  19. -- 前N条(TOP)
  20. SELECT TOP 5 * FROM Student ORDER BY Age DESC; -- 年龄最大的5个
  21. SELECT TOP 50 PERCENT * FROM Student; -- 前50%
复制代码

六、多表查询(核心难点)

实际开发中,数据往往分布在多张表中,需要通过连接查询将它们组合起来。

6.1 内连接(INNER JOIN)

只返回两个表中匹配的行。

  1. -- 隐式内连接(使用 WHERE)
  2. SELECT e.Name, d.Name
  3. FROM Emp e, Dept d
  4. WHERE e.DeptId = d.Id;
  5. -- 显式内连接(推荐)
  6. SELECT e.Name, d.Name
  7. FROM Emp e
  8. INNER JOIN Dept d ON e.DeptId = d.Id;
复制代码

6.2 外连接(LEFT / RIGHT JOIN)

返回左表(或右表)的所有行,即使匹配不上。

  1. -- 左外连接:返回左表全部,右表匹配的字段,没匹配则为 NULL
  2. SELECT e.Name, d.Name
  3. FROM Emp e
  4. LEFT JOIN Dept d ON e.DeptId = d.Id;
  5. -- 右外连接同理
复制代码

6.3 子查询(嵌套查询)

将一个查询结果作为另一个查询的条件或临时表。

单行单列(作为条件)

  1. -- 查询工资最高的员工
  2. SELECT * FROM Emp
  3. WHERE Salary = (SELECT MAX(Salary) FROM Emp);
复制代码

多行多列(作为虚拟表)

  1. -- 查询入职日期在2011-11-11之后的员工及部门信息
  2. SELECT *
  3. FROM Dept d
  4. JOIN (SELECT * FROM Emp WHERE JoinDate > '2011-11-11') e
  5. ON d.Id = e.DeptId;
复制代码

6.4 综合案例:多表连接练习

我们建立了一张完整的员工-部门-职务-工资等级表,以下是几个典型查询:

  1. -- 1. 查询员工编号、姓名、工资、职务名称、职务描述
  2. SELECT e.Id, e.Ename, e.Salary, j.Jname, j.Description
  3. FROM Emp e
  4. JOIN Job j ON e.JobId = j.Id;
  5. -- 2. 查询员工姓名、工资、工资等级(使用 BETWEEN)
  6. SELECT e.Ename, e.Salary, g.Grade
  7. FROM Emp e
  8. JOIN SalaryGrade g ON e.Salary BETWEEN g.Losalary AND g.Hisalary;
  9. -- 3. 查询每个部门的编号、名称、位置及员工人数
  10. SELECT d.Id, d.Dname, d.Loc, COUNT(e.Id) AS EmpCount
  11. FROM Dept d
  12. LEFT JOIN Emp e ON d.Id = e.DeptId
  13. GROUP BY d.Id, d.Dname, d.Loc;
  14. -- 4. 查询所有员工及其直接上级(自连接 + 左外连接)
  15. SELECT e1.Ename AS 员工, e2.Ename AS 上级
  16. FROM Emp e1
  17. LEFT JOIN Emp e2 ON e1.Mgr = e2.Id;
复制代码

七、事务处理(Transaction)

事务用于保证一组操作要么全部成功,要么全部回滚。经典的转账案例:

  1. -- 创建账户表
  2. CREATE TABLE Bank
  3. (
  4. UName VARCHAR(20),
  5. UMoney MONEY CHECK (UMoney >= 1)
  6. );
  7. INSERT INTO Bank VALUES ('班长', 10000), ('学委', 100);
  8. -- 模拟转账(班长转5000给学委)
  9. BEGIN TRANSACTION
  10. UPDATE Bank SET UMoney = UMoney - 5000 WHERE UName = '班长';
  11. UPDATE Bank SET UMoney = UMoney + 5000 WHERE UName = '学委';
  12. COMMIT TRANSACTION
复制代码

但如果在转账过程中发生断电或错误,会导致数据不一致。使用事务回滚:

  1. DECLARE @ErrorCount INT = 0;
  2. BEGIN TRANSACTION
  3. UPDATE Bank SET UMoney = UMoney - 5000 WHERE UName = '班长';
  4. SET @ErrorCount = @ErrorCount + @@ERROR; -- @@ERROR 记录错误号
  5. UPDATE Bank SET UMoney = UMoney + 5000 WHERE UName = '学委';
  6. SET @ErrorCount = @ErrorCount + @@ERROR;
  7. IF @ErrorCount > 0
  8. BEGIN
  9. ROLLBACK TRANSACTION; -- 回滚
  10. PRINT '转账失败';
  11. END
  12. ELSE
  13. BEGIN
  14. COMMIT TRANSACTION; -- 提交
  15. PRINT '转账成功';
  16. END
复制代码

事务四特性(ACID)

  • 原子性(Atomicity):要么全部完成,要么全部不完成。

  • 一致性(Consistency):事务前后数据状态一致。

  • 隔离性(Isolation):并发事务互不干扰。

  • 持久性(Durability):提交后数据永久保存。

八、学习心得与总结

这一周我们从零开始迈入了数据库世界,核心感悟如下:

  1. 约束是数据的守护神:没有约束的表就像没有门锁的房子,数据随时可能“被入侵”。一定要为每个表设计好主键、外键、检查约束等。

  2. T-SQL 是 C# 开发者的必备技能:无论使用 ADO.NET 还是 Entity Framework,底层都是 SQL 语句。写一手高效的 SQL 能极大提升程序性能。

  3. 多表查询是进阶关键:内连接、外连接、子查询三种方式各有适用场景。实际项目中,80% 的查询都涉及多张表,熟练使用连接是区分初级和中级开发者的重要标志。

  4. 事务是数据一致性的保障:在涉及金额、库存等敏感数据时,一定要使用事务,避免半途而废导致数据错乱。

  5. 善用图形界面,也要懂 SQL 脚本:虽然 SSMS 提供了友好的可视化界面,但学会写 SQL 脚本可以更高效地管理数据库,也更容易迁移和备份。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行