范式
范式化是数据库设计中的重要概念,它帮助我们避免数据冗余和不一致性。
数据库设计原则
数据完整性
- 实体完整性
- 参照完整性
- 域完整性
- 用户定义完整性
性能考虑
- 查询效率
- 存储效率
- 维护成本
可扩展性
- 支持未来需求变化
- 便于系统升级
- 适应业务增长
数据库范式
第一范式(1NF)
- 每个字段都是原子性的,不可再分
- 没有重复的列
- 每个表有主键
sql
-- 不符合1NF的表
CREATE TABLE orders (
order_id INT PRIMARY KEY,
items VARCHAR(255) -- 存储多个商品,用逗号分隔
);
-- 符合1NF的表
CREATE TABLE orders (
order_id INT PRIMARY KEY
);
CREATE TABLE order_items (
order_id INT,
item_id INT,
quantity INT,
PRIMARY KEY (order_id, item_id),
FOREIGN KEY (order_id) REFERENCES orders(order_id)
);
第二范式(2NF)
- 满足1NF
- 非主键字段完全依赖于主键
- 消除部分依赖
sql
-- 不符合2NF的表
CREATE TABLE orders (
order_id INT,
product_id INT,
product_name VARCHAR(100),
quantity INT,
PRIMARY KEY (order_id, product_id)
);
-- 符合2NF的表
CREATE TABLE orders (
order_id INT PRIMARY KEY
);
CREATE TABLE products (
product_id INT PRIMARY KEY,
product_name VARCHAR(100)
);
CREATE TABLE order_items (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(order_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
第三范式(3NF)
- 满足2NF
- 非主键字段不依赖于其他非主键字段
- 消除传递依赖
sql
-- 不符合3NF的表
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
department_id INT,
department_name VARCHAR(100),
manager_id INT,
manager_name VARCHAR(100)
);
-- 符合3NF的表
CREATE TABLE departments (
department_id INT PRIMARY KEY,
department_name VARCHAR(100)
);
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
department_id INT,
manager_id INT,
FOREIGN KEY (department_id) REFERENCES departments(department_id)
);
反范式化
虽然范式化可以减少数据冗余,但有时为了提高查询性能,我们需要进行适当的反范式化。
反范式化的场景
- 频繁的关联查询
- 历史数据统计
- 实时性要求高的场景
反范式化的方法
- 增加冗余字段
- 使用汇总表
- 使用缓存表
sql
-- 反范式化示例:增加冗余字段
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
customer_name VARCHAR(100), -- 冗余字段
order_date DATE,
total_amount DECIMAL(10,2)
);
数据库设计步骤
需求分析
- 确定数据需求
- 识别实体和关系
- 定义业务规则
概念设计
- 创建实体关系图(ER图)
- 定义实体属性
- 确定实体关系
逻辑设计
- 将ER图转换为关系模型
- 应用范式化规则
- 定义完整性约束
物理设计
- 选择存储结构
- 设计索引
- 优化查询性能
设计工具
ER图工具
- MySQL Workbench
- draw.io
- Lucidchart
数据库建模工具
- PowerDesigner
- ERwin
- Navicat Data Modeler
最佳实践
命名规范
- 使用有意义的表名和字段名
- 保持命名一致性
- 使用下划线命名法
字段设计
- 选择合适的数据类型
- 设置适当的字段长度
- 添加必要的约束
索引设计
- 为常用查询字段创建索引
- 避免过度索引
- 定期维护索引
文档维护
- 记录数据库结构
- 说明业务规则
- 更新变更记录