第1课数据库_基本知识
热度🔥:55 免费课程
授课语音
数据库基础知识
1. 介绍
数据库是一个长期存储在计算机内的、有组织的数据集合,它按照特定的数据模型组织存储数据,以便管理和使用数据。
数据 是数据库存储的基本对象。在实际开发中,主要有两种类型的数据:
- 结构化数据:具有固定的数据类型,比如整数、日期、布尔值和字符串。
- 半结构化数据:没有固定数据类型,通常以文本形式存在,比如 JSON 和 XML。
此外,图片、音频和视频数据一般存储在文件系统或云对象存储服务上。
数据库管理员(DBA) 是管理和维护数据库系统的专业人员,其主要职责包括:
- 数据库的安装和配置
- 性能监控
- 安全管理
- 故障排除
- 备份和恢复
- 文档编写等
数据库管理系统(DBMS) 是用于管理和操作数据库的软件系统,如 MySQL、Oracle、Microsoft SQL Server 和 MongoDB 等。
数据库系统(DBS) 是一个完整的系统,包括数据库、DBMS、应用系统和数据库管理员(DBA)。
数据模型 用于定义数据的结构、关系和操作规则,主要包括:
- 关系模型
- 文档模型
- 键值模型
- 图模型
数据模型类型
文档模型数据库:一种 NoSQL 数据库(如 MongoDB),用于存储和管理半结构化数据。基础数据单元是文档(如 JSON、XML),这些文档以不同的层次结构放在一个集合中,支持嵌套数据结构、查询性能和水平扩展性,但在数据库冗余和事务支持方面存在一定限制。
键值模型数据库:一种 NoSQL 数据库(如 Redis),以键值对形式存储和管理数据。key 一般是字符串类型,value 结构灵活,可以是大对象,适合缓存和配置系统等场景,但不支持复杂查询。
图模型数据库:一种 NoSQL 数据库(如 Neo4j),用于存储和查询复杂关系的图结构的数据。图由节点(实体)和边(关系)组成,适合表示节点之间的复杂网络结构。
关系模型数据库:一种 SQL 数据库(如 MySQL、Oracle),通过表(行+列)组织数据,提供强大的数据一致性、标准化查询和事务支持能力。
关系模型基本概念
- 表:关系模型数据库的基本结构,由行和列组成。
- 行:表示实体或记录,每一行包含该实体的所有属性。
- 列:是实体的属性。
- 主键:唯一标识每个表中的记录,通常自动创建索引以提升查询性能。
- 外键:在一个表中引用另一个表的主键,用于维护表之间的关系。
- 索引:提升数据检索性能的结构,包括单列索引、复合索引、唯一索引和全文索引。
- 事务:保证数据库的 ACID 属性,即原子性、一致性、隔离性和持久性。
数据库范式
范式通过规范化过程设计数据库结构,以消除数据冗余,提高数据一致性。在实际开发中,一般遵循到第三范式(3NF),但有时为了提高查询性能,会引入部分数据冗余。
- 第一范式(1NF):确保每列都是原子的,不可再分。
- 第二范式(2NF):在 1NF 基础上,消除部分依赖,即非主键完全依赖主键。
- 第三范式(3NF):在 2NF 基础上,消除传递依赖,即非主键不依赖其他非主键。
- BCNF(博茨-科得范式),修正3NF部分缺陷
- 第四范式(4NF),消除多值依赖(多值依赖指一个属性可以决定另一个属性组的多个值,比如Projects项目表,projectId主键,employeeId和skillId非主键,如果一个projectId对应多个employeeId和skillId,那么employeeId和skillId对projectId存在多值依赖)
- 第五范式(5NF),消除连接依赖(连接依赖指一个关系可以通过多个子关系连接重建,比如一个表R,属性包含{A,B,C},如果R可以通过两个子关系R1{A,B}和R2{B,C}的连接来重建,那么R存在连接依赖)
2. 实践案例-反范式设计
反范式设计(Denormalization)是在数据库设计中故意引入一些数据冗余,以优化查询性能。我们将使用一个示例数据库模式,在规范化和反规范化之间进行平衡,以提高查询效率。
1. 数据库结构设计
1.1 需求分析
假设我们有一个电子商务系统,主要功能包括:
- 存储产品信息
- 存储订单信息,包括订单的详细信息和客户信息
- 提供高效的查询来检索订单及其详细信息
在规范化设计中,订单和产品信息会分布在不同的表中,订单表与产品表通过外键关联。为了提高查询性能,我们可以进行适度的反规范化,将一些数据冗余到订单表中,以减少复杂的联接操作。
1.2 反范式设计
1.2.1 规范化设计(参考)
在规范化设计中,我们会有以下表:
products
表(存储产品信息):
CREATE TABLE products (
product_id INT PRIMARY KEY,
product_name VARCHAR(100),
product_price DECIMAL(10, 2)
);
orders
表(存储订单信息):
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE
);
order_items
表(存储每个订单中的产品信息):
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)
);
1.2.2 反范式设计
为了提高查询性能,我们将产品名称和价格冗余到 order_items
表中,避免在查询订单详细信息时进行联接。
order_items
表(经过反范式设计):
CREATE TABLE order_items (
order_id INT,
product_id INT,
product_name VARCHAR(100), -- 反范式:冗余存储产品名称
product_price DECIMAL(10, 2), -- 反范式:冗余存储产品价格
quantity INT,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(order_id)
);
2. 示例数据
我们将插入一些示例数据到 products
和 orders
表中,并展示如何在 order_items
表中进行数据冗余。
插入示例数据:
-- 插入产品信息
INSERT INTO products (product_id, product_name, product_price) VALUES
(1, 'Laptop', 999.99),
(2, 'Mouse', 25.50),
(3, 'Keyboard', 45.00);
-- 插入订单信息
INSERT INTO orders (order_id, customer_id, order_date) VALUES
(101, 1, '2024-08-01'),
(102, 2, '2024-08-02');
-- 插入订单项信息(经过反范式设计)
INSERT INTO order_items (order_id, product_id, product_name, product_price, quantity) VALUES
(101, 1, 'Laptop', 999.99, 1),
(101, 2, 'Mouse', 25.50, 2),
(102, 3, 'Keyboard', 45.00, 1);
3. 查询示例
3.1 查询订单及其详细信息(反范式设计)
使用反范式设计后的 order_items
表,可以直接查询订单及其详细信息,而无需联接 products
表。
-- 查询订单及其详细信息
SELECT
o.order_id,
o.order_date,
i.product_name,
i.product_price,
i.quantity,
(i.product_price * i.quantity) AS total_price -- 计算总价格
FROM
orders o
JOIN
order_items i ON o.order_id = i.order_id
WHERE
o.order_id = 101;
查询结果:
+----------+------------+-------------+---------------+----------+-------------+
| order_id | order_date | product_name | product_price | quantity | total_price |
+----------+------------+-------------+---------------+----------+-------------+
| 101 | 2024-08-01 | Laptop | 999.99 | 1 | 999.99 |
| 101 | 2024-08-01 | Mouse | 25.50 | 2 | 51.00 |
+----------+------------+-------------+---------------+----------+-------------+
4. 总结
反范式的目的:通过在
order_items
表中冗余存储产品名称和价格,减少在查询订单详细信息时的联接操作,从而提升查询性能。这种设计适合查询频繁的场景,但会增加数据冗余和数据一致性维护的复杂性。数据一致性:在进行反范式设计时,需要确保冗余数据的一致性。例如,当产品价格发生变化时,需在
order_items
表中更新所有相关记录。
可以通过触发器或应用程序逻辑来处理这种更新。
- 查询性能:反范式设计通过减少联接操作来提升查询性能,但也可能导致数据冗余。应根据实际需求,在规范化和反规范化之间做出权衡,以优化性能和维护成本。