1.数据库系统
数据库系统DBS:是一个采用了数据库技术,有组织地、动态地存储大量相关
数据,方便多用户访问的计算机系统。其由下面四个部分组成:- 数据库(统一管理、长期存储在计算机内的,有组织的相关数据的集合)
- 硬件(构成计算机系统包括存储数据所需的外部设备)
- 软件(操作系统、数据库管理系统及应用程序)
- 人员(系统分析和数据库设计人员、应用程序员、最终用户、数据库管理员DBA)
数据库管理系统DBMS的功能
实现对共享数据有效的组织、管理和存取。包括数据定义、数据库操作、数据库运行管理、数据的存储管理、数据库的建立和维护等。
2.三级模式-两级映射
1.模式
内模式:管理如何存储物理的数据,对应具体物理存储文件。
模式:又称为概念模式,就是我们通常使用的基本表,根据应用、需求将物理数据划分成一张张表。
外模式:对应数据库中的视图这个级别,将表进行一定的处理后再提供给用户使用
2.映射
2.1 外模式一模式映像
外模式一模式映像:是表和视图之间的映射,存在于概念级和外部级之间,若表中数据发生了修改,只需要修改此映射,而无需修改应用程序。
当数据库的底层逻辑结构(模式)发生变化时,那些依赖于视图(外模式)的应用程序代码无需进行任何修改,就能继续正常工作。这是逻辑数据独立性带来的直接好处。
初始状态
- 模式(基本表):有一张员工信息表
Employees。CREATETABLEEmployees(EmpIDINTPRIMARYKEY,NameVARCHAR(100),SalaryDECIMAL(10,2),DeptIDINT); - 外模式(视图):为了方便财务部门只查看工资信息,DBA创建了一个视图
FinanceView。CREATEVIEWFinanceViewASSELECTEmpID,Name,SalaryFROMEmployees; - 应用程序:财务部门的薪资系统程序
FinanceApp,它的代码里只查询这个视图。-- FinanceApp 内部的查询语句是:SELECT*FROMFinanceViewWHERESalary>5000;FinanceApp完全不知道Employees表的存在,它只知道FinanceView。
场景:模式发生改变(数据库重构)
公司业务发展,需要将员工信息拆分到更专业的表中。模式(表结构)被修改了:
- 新建
EmployeeBasic表存储基本信息。 - 新建
EmployeeSalary表存储薪资信息。 - 删除原来的
Employees表。
新的模式如下:
CREATETABLEEmployeeBasic(EmpIDINTPRIMARYKEY,NameVARCHAR(100),DeptIDINT);CREATETABLEEmployeeSalary(EmpIDINTPRIMARYKEY,SalaryDECIMAL(10,2),FOREIGNKEY(EmpID)REFERENCESEmployeeBasic(EmpID));关键操作:更新“外模式-模式映像”
此时,数据库管理员(DBA)只需要修改FinanceView视图的定义(即更新外模式-模式映像),将视图的查询逻辑从指向旧的单表,改为关联新的两张表。
-- 旧的视图定义被替换-- CREATE VIEW FinanceView AS SELECT EmpID, Name, Salary FROM Employees;-- 新的视图定义(映像被更新了)CREATEORREPLACEVIEWFinanceViewASSELECTb.EmpID,b.Name,s.SalaryFROMEmployeeBasic bJOINEmployeeSalary sONb.EmpID=s.EmpID;结果:应用程序发生了什么?
- 应用程序
FinanceApp需要修改吗?—— 完全不需要! - 为什么?
- 应用程序的代码里访问的仍然是
FinanceView(外模式名称没变)。 - 视图
FinanceView返回的数据“形态”没有变:依然是包含EmpID, Name, Salary三列的记录集(外模式结构没变)。 - 虽然底层数据从一个表变成了两个表的连接,但这个复杂性被“外模式-模式映像”(即新的视图定义)完全屏蔽和消化了。
- 应用程序就像一个最终用户,它看到并使用的“界面”(外模式)没有发生任何变化。
- 应用程序的代码里访问的仍然是
“不变”的具体含义
| 需要改变的部分 | 负责方 | 无需改变的部分 | 受益方 |
|---|---|---|---|
| 物理存储(内模式) | 存储管理员、DBMS | 模式、外模式、应用程序 | 所有用户和程序 |
| 全局逻辑结构(模式) | 数据库管理员(DBA) | 外模式、应用程序 | 应用程序员、最终用户 |
| 外模式定义(视图) | 数据库管理员(DBA) | 应用程序 | 应用程序所有者 |
总结一下:
“与外模式相关的应用程序可以保持不变”指的就是程序的源代码、编译后的二进制文件、配置文件等都不需要因为数据库底层结构的调整而重新编写、编译或部署。程序的数据访问接口、SQL语句、业务逻辑代码都保持原样。
逻辑数据独立性魅力
这种机制极大地降低了软件维护成本,提高了系统的可维护性和可扩展性。当数据库为了优化性能或适应新需求而进行重构时,大量的现有业务程序可以安然无恙,这是数据库三级模式架构设计的巨大成功。
2.2 模式一内模式映像
模式一内模式映像:是表和数据的物理存储之间的映射存在于概念级和内部级之间,若修改了数据存储方式,只需要修改此映射,而不需要去修改应用程序。
假设books表原来是MyISAM引擎,现在要换成InnoDB引擎并分区:
修改前:
-- books表使用MyISAM,存储在单个文件CREATETABLEbooks(book_idINTPRIMARYKEY,titleVARCHAR(100),authorVARCHAR(50),categoryVARCHAR(30),publish_yearINT)ENGINE=MyISAM;-- 数据文件:/var/lib/mysql/library/books.MYD-- 索引文件:/var/lib/mysql/library/books.MYI修改内模式(物理存储):
-- 1. 修改存储引擎为InnoDB-- 2. 添加分区(按category分区存储)ALTERTABLEbooksENGINE=InnoDBPARTITIONBYLISTCOLUMNS(category)(PARTITIONp_computerVALUESIN('计算机'),PARTITIONp_literatureVALUESIN('文学'),PARTITIONp_scienceVALUESIN('科学'),PARTITIONp_othersVALUESIN(DEFAULT));-- 3. 将数据文件迁移到SSD存储-- 修改MySQL配置-- 原数据目录:/var/lib/mysql/library/-- 新数据目录:/ssd_storage/mysql/library/发生了什么变化?
| 变化项 | 修改前 | 修改后 |
|---|---|---|
| 存储设备 | 机械硬盘 | SSD固态硬盘 |
| 存储结构 | 单个数据文件 | 按类别分4个物理文件 |
| 索引方式 | B-tree索引 | B+tree索引 + 分区裁剪 |
| 文件位置 | /var/lib/mysql/ | /ssd_storage/mysql/ |
最重要的部分:用户和程序完全无感知!
用户角度:
-- 用户还是这样查询,完全不变SELECT*FROMcomputer_booksWHEREtitleLIKE'%数据库%';-- 应用程序代码完全不变-- Java/Python/PHP中的查询语句不需要修改Stringsql="SELECT * FROM new_books ORDER BY publish_year DESC";为什么用户感觉不到变化?
因为模式-内模式映像(DBMS内部的数据访问层)完成了所有适配:
用户查询 ↓ 视图层(外模式)←→ 没变! ↓ 基本表层(模式)←→ 没变!表名、列名、数据类型都没变 ↓ ╔═══════════════════════════════════╗ ║ 模式-内模式映像(DBMS内部) ║ ← 这里变了! ║ 负责将逻辑查询转换为物理操作 ║ ╚═══════════════════════════════════╝ ↓ 物理存储层(内模式)←→ 完全变了!DBMS内部适配的过程:
- 用户查询:
SELECT * FROM books WHERE category='计算机' - DBMS解析:这是一个计算机类书籍查询
- 新映射规则生效:
-- 旧规则:全表扫描books.MYD文件-- 新规则:只扫描p_computer分区文件-- 利用SSD快速随机读取-- 使用分区索引快速定位 - 物理操作:
- 访问
/ssd_storage/mysql/library/books#P#p_computer.ibd - 使用InnoDB的B+tree索引
- 返回结果给用户
- 访问
实际生产中的例子
案例:双十一前的数据库升级
阿里云某电商平台,订单表原来存储在:
- 存储设备:普通SAS硬盘RAID5
- 存储结构:单表,按订单ID哈希分片
- 索引:普通B-tree索引
问题:双十一期间查询太慢
升级方案:
- 存储设备:换成NVMe SSD
- 存储结构:改为按时间范围分区(每天一个分区)
- 索引:添加覆盖索引,使用列存储索引
实施后:
- 查询速度快了10倍
- 存储空间节省40%
- 但业务系统完全没改一行代码!
为什么?因为DBA只是修改了:
- 表的分区策略(
ALTER TABLE ... PARTITION BY RANGE ...) - 存储路径指向新的SSD阵列
- 添加了新类型的索引
所有的应用程序仍然访问原来的表名和视图,SQL语句完全不变。
这就是"物理数据独立性"的魅力!
就像你家的地址没变(模式),但:
- 从平房搬到了楼房(存储设备变了)
- 从普通门锁换成了指纹锁(索引方式变了)
- 房间从按大小排列改为按功能排列(存储结构变了)
但所有朋友寄信时:
- 还是写"XX市XX路XX号"(逻辑地址不变)
- 快递员还是能送到(DBMS内部处理了映射)
- 你不需要通知所有朋友"我搬家了,请用新地址"(应用程序不变)
这种机制让数据库可以:
- 无缝升级硬件:HDD → SSD → NVMe
- 优化存储结构:单表 → 分区 → 分片
- 改进索引算法:B-tree → B+tree → LSM-tree
- 迁移到云存储:本地磁盘 → 云盘 → 对象存储
而所有这些变化,对使用数据库的成百上千个应用程序来说,都是透明无感知的。这就是数据库系统设计的精妙之处!
3.数据库设计
- 需求分析:即分析数据存储的要求,产出物有数据流图、数据字典、需求说明书。
- 概念结构设计:就是设计E-R图,也即实体-属性图,与物理实现无关,说明有哪些实体,实体有哪些属性。
- 逻辑结构设计:将E-R图,转换成关系模式,也即转换成实际的表和表中的列属性,这里要考虑很多规范化的东西。
- 物理设计:根据生成的表等概念,生成物理数据库。