关系型数据库基本概念
想象一下,你正在经营一家小型咖啡店。每天,你需要记录订单、管理库存、跟踪常客的喜好。起初,你用纸笔记录一切,但随着业务增长,这变得越来越复杂。
这就是数据库的用武之处!
数据管理的演进
最初,数据管理很简单:
纸质账本 → 电子表格 → 专用软件 → 数据库系统
随着数据量增长,简单方法逐渐不够用:
- 纸质账本难以查找和统计
- 电子表格难以处理复杂关系
- 专用软件缺乏灵活性
关系模型的诞生
1970年,IBM研究员E.F.Codd提出了关系模型的概念。在此之前,数据存储主要是层次模型和网络模型。
层次模型
在层次模型中,数据组织如下:
markdown
咖啡店
├── 员工
│ ├── 张三
│ └── 李四
└── 商品
├── 咖啡
└── 点心
数据以树状结构组织,每个记录只能有一个父节点。要查找"李四销售的所有咖啡",必须遵循固定路径:咖啡店→员工→李四→销售记录→咖啡,非常不灵活。
网络模型
网络模型是层次模型的扩展,允许记录有多个父节点,形成网状结构:
markdown
┌───────┐
│ 咖啡店 │
└───┬───┘
│
┌──────┴──────┐
▼ ▼
┌───────┐ ┌───────┐
│ 员工 │◄────►│ 商品 │
└───┬───┘ └───┬───┘
│ │
┌───┴───┐ ┌───┴───┐
│ 张三 │◄────►│ 咖啡 │
└───────┘ └───────┘
▲ ▲
└──────┬───────┘
│
┌───┴───┐
│ 销售 │
└───────┘
网络模型通过"集合"连接不同记录,允许更复杂的关系。例如,员工可以销售商品,商品可以被多个员工销售。但数据访问仍需按特定路径导航,编程复杂且不直观。
关系模型
关系模型将数据组织为独立表格,通过共同值关联:
【员工表】 【商品表】 【销售表】
┌────┬─────────┐ ┌────┬─────────┐ ┌────┬────────┬────────┐
│ ID │ 姓名 │ │ ID │ 名称 │ │ ID │ 员工ID │ 商品ID │
├────┼─────────┤ ├────┼─────────┤ ├────┼────────┼────────┤
│ 1 │ 张三 │ │ 1 │ 咖啡 │ │ 1 │ 1 │ 1 │
│ 2 │ 李四 │ │ 2 │ 点心 │ │ 2 │ 2 │ 1 │
└────┴─────────┘ └────┴─────────┘ └────┴────────┴────────┘
查询"李四销售的所有咖啡"只需一个简单的SQL语句,无需按特定路径导航:
sql
SELECT 商品.名称
FROM 员工, 销售, 商品
WHERE 员工.姓名 = '李四'
AND 员工.ID = 销售.员工ID
AND 销售.商品ID = 商品.ID;
核心概念:表与关系
表是关系型数据库的基本存储单元。以咖啡店为例:
【商品表】
┌────┬───────────┬──────┬────────┬────────┐
│ ID │ 名称 │ 类别 │ 价格 │ 库存 │
├────┼───────────┼──────┼────────┼────────┤
│ 1 │ 美式咖啡 │ 饮品 │ 25.00 │ 无限 │
│ 2 │ 拿铁 │ 饮品 │ 32.00 │ 无限 │
│ 3 │ 牛角面包 │ 食品 │ 15.00 │ 20 │
└────┴───────────┴──────┴────────┴────────┘
每张表由以下元素组成:
- 表名:描述表示什么实体(如"商品表")
- 列:描述实体的属性(如ID、名称、价格)
- 行:表示实体的具体实例(如"美式咖啡")
- 单元格:包含特定实例的特定属性值(如"美式咖啡"的价格是25元)
数据关系:通过键连接
在关系模型中,表通过键连接。例如,我们可以有三张表:顾客、商品和订单,它们通过主键和外键相关联。
键的类型
- 主键(PK):唯一标识表中的行,如商品表的ID列
- 外键(FK):引用其他表主键的列,如订单表中的顾客ID
- 候选键:能唯一标识行的任何列组合
- 超键:包含候选键的任何列组合
把键想象成连接表的"桥梁":顾客表中的ID=1(张三)关联到订单表中顾客ID=1的所有记录。
数据完整性:通过约束保证
约束确保数据库中的数据符合业务规则:
- 非空约束:值不能为NULL
- 唯一约束:值不能重复
- 检查约束:值必须满足条件
- 引用完整性:外键必须引用有效值
例如,我们可以定义:
sql
-- 价格必须为正数
ALTER TABLE 商品表 ADD CONSTRAINT 价格检查 CHECK (价格 > 0);
-- 订单中的商品ID必须存在于商品表
ALTER TABLE 订单表 ADD CONSTRAINT 商品存在
FOREIGN KEY (商品ID) REFERENCES 商品表(ID);
基本操作:CRUD
所有数据库操作都可以归结为四种基本类型:
- Create (创建)
- Read (读取)
- Update (更新)
- Delete (删除)
以咖啡店为例:
sql
-- 创建:咖啡店新增一款饮品
INSERT INTO 商品表(ID, 名称, 类别, 价格, 库存)
VALUES (4, '摩卡', '饮品', 30.00, '无限');
-- 读取:查看所有饮品
SELECT * FROM 商品表 WHERE 类别 = '饮品';
-- 更新:调整拿铁价格
UPDATE 商品表 SET 价格 = 35.00 WHERE ID = 2;
-- 删除:下架牛角面包
DELETE FROM 商品表 WHERE ID = 3;
SQL与关系代数
SQL语句直接对应关系代数操作:
- WHERE 子句 对应 选择(σ) 操作
- SELECT 子句 对应 投影(π) 操作
- JOIN 操作 对应 连接(⋈) 操作
- UNION/INTERSECT/EXCEPT 对应 集合运算
例如:
SELECT 名称, 价格 FROM 商品表 WHERE 类别 = '饮品'
- 相当于关系代数:π(名称,价格)(σ(类别='饮品')(商品表))
但是这并不是本教程的重点,所以咱们只要简单了解一下即可。
数据库系统架构
随着我们的学习深入,我们将逐层构建数据库系统:
markdown
客户端接口层
↓
查询处理层
↓
事务管理层
↓
缓冲管理层
↓
存储引擎层
↓
文件系统
这种分层架构让我们能够逐步构建数据库系统,先实现基础功能,再添加高级特性。这里简单说说,后面这块我们将进行详细阐述。
小结与展望
在这一节中,我们了解了关系型数据库的核心概念:
- 表和关系的基本结构
- 键的类型和作用
- 约束的重要性
- 基本CRUD操作
- 关系代数与SQL的对应关系
在下一节中,我们将探索SQL标准及其在不同数据库系统中的实现差异,为我们自己的数据库引擎奠定更坚实的理论基础。
我们的学习路径将是循序渐进的,从简单概念开始,逐步构建完整的数据库系统。不久后,我们就会开始编写代码,实现这些概念!