外观
SQLServer 开发架构
逻辑架构
数据库引擎架构
SQLServer 数据库引擎是 SQLServer 的核心组件,负责处理数据的存储、检索和管理。它包含以下主要组件:
1. 协议层 (Protocol Layer)
功能:处理客户端连接和通信协议。
支持的协议:
- TCP/IP:最常用的协议,支持远程连接
- Named Pipes:适用于同一台服务器或局域网内的连接
- Shared Memory:适用于本地连接,性能最好
- VIA (Virtual Interface Adapter):用于高性能网络,已被弃用
2. 查询处理器 (Query Processor)
功能:处理 SQL 查询,包括解析、优化和执行。
主要组件:
查询解析器 (Query Parser)
- 检查 SQL 语法是否正确
- 将 SQL 语句转换为内部数据结构(查询树)
查询优化器 (Query Optimizer)
- 基于成本的优化器,生成最优执行计划
- 考虑多种执行路径,选择成本最低的路径
- 使用统计信息估计查询成本
查询执行器 (Query Executor)
- 按照执行计划执行查询
- 管理锁和事务
- 调用存储引擎执行数据操作
3. 存储引擎 (Storage Engine)
功能:管理数据的存储和检索,处理数据页、索引和事务日志。
主要组件:
访问方法 (Access Methods)
- 处理表和索引的访问
- 实现扫描、查找、插入、更新和删除操作
缓冲区管理器 (Buffer Manager)
- 管理内存中的数据页缓存(缓冲池)
- 处理数据页的读取和写入
- 实现预读和延迟写入
事务管理器 (Transaction Manager)
- 管理事务的开始、提交和回滚
- 实现 ACID 特性
- 管理锁和隔离级别
日志管理器 (Log Manager)
- 管理事务日志的写入和恢复
- 实现 Write-Ahead Logging (WAL) 机制
- 支持事务日志备份和恢复
物理架构
数据库文件
SQLServer 数据库由以下类型的文件组成:
1. 数据文件
主要数据文件 (.mdf):
- 每个数据库必须有一个主要数据文件
- 包含数据库的系统表和用户表
- 扩展名通常为 .mdf
次要数据文件 (.ndf):
- 可选,一个数据库可以有多个次要数据文件
- 用于分散数据存储,提高 I/O 性能
- 扩展名通常为 .ndf
2. 事务日志文件
- 事务日志文件 (.ldf):
- 记录所有数据更改操作
- 用于恢复数据库
- 每个数据库至少有一个事务日志文件
- 扩展名通常为 .ldf
数据存储结构
1. 数据页 (Data Page)
- 数据存储的基本单位
- 大小为 8 KB
- 包含页眉、数据行和行偏移数组
2. 扩展盘区 (Extent)
- 由 8 个连续的数据页组成(64 KB)
- 用于分配存储空间
- 分为统一扩展盘区和混合扩展盘区
3. 分配单元 (Allocation Unit)
- 用于管理不同类型的数据存储
- 包括:
- 堆分配单元:用于堆表
- 聚集索引分配单元:用于聚集索引
- 非聚集索引分配单元:用于非聚集索引
系统数据库
SQLServer 包含以下系统数据库:
master:
- 存储系统级信息
- 包含实例配置、数据库信息、登录账户等
model:
- 所有新数据库的模板
- 新数据库继承 model 数据库的设置
msdb:
- 用于 SQL Server Agent 作业调度
- 存储备份和恢复历史记录
- 包含维护计划和数据库邮件配置
tempdb:
- 临时数据库
- 存储临时表、临时结果集和排序工作区
- 每次 SQLServer 重启时重建
resource:
- 只读数据库
- 包含系统对象
- 隐藏的系统数据库
开发架构
客户端-服务器架构
SQLServer 采用客户端-服务器架构,包括:
客户端:
- 应用程序或工具,如 SSMS、Azure Data Studio
- 发送 SQL 查询到服务器
- 处理查询结果
服务器:
- SQLServer 实例
- 处理客户端请求
- 执行 SQL 查询
- 返回查询结果
应用程序开发架构
1. 三层架构
- 表示层:用户界面,如 Web 页面或桌面应用
- 业务逻辑层:处理业务逻辑,如验证、计算和业务规则
- 数据访问层:与数据库交互,执行 CRUD 操作
2. 微服务架构
- 应用程序拆分为多个独立的微服务
- 每个微服务有自己的数据库或共享数据库
- 使用 API 网关进行服务调用
3. 云原生架构
- 基于云服务构建应用程序
- 使用 Azure SQL Database 或 Azure SQL Managed Instance
- 利用云服务的弹性伸缩和高可用性
数据访问技术
1. ADO.NET
- .NET 框架的核心数据访问技术
- 提供连接池、命令执行和数据读取功能
- 支持断开连接的数据集 (DataSet) 和连接的数据流 (DataReader)
2. Entity Framework
- ORM (Object-Relational Mapping) 框架
- 支持 LINQ 查询
- 自动生成 SQL 语句
- 支持 Code-First 和 Database-First 开发
3. Dapper
- 轻量级 ORM 框架
- 高性能,接近原生 ADO.NET
- 支持参数化查询和结果映射
4. ODBC 和 OLE DB
- 传统的数据访问接口
- 支持多种编程语言
- ODBC 是开放标准,OLE DB 是 Microsoft 专有技术
开发模式
1. 数据库优先开发 (Database-First)
- 先设计数据库架构
- 然后生成应用程序代码
- 适合现有数据库或复杂数据模型
2. 代码优先开发 (Code-First)
- 先编写应用程序代码
- 然后生成数据库架构
- 适合新应用程序或简单数据模型
3. 模型优先开发 (Model-First)
- 先设计数据模型
- 然后生成数据库架构和应用程序代码
- 适合复杂数据模型
内存管理
缓冲池 (Buffer Pool)
- 内存中的数据页缓存
- 提高数据访问性能
- 大小由
max server memory和min server memory参数控制
计划缓存 (Plan Cache)
- 存储查询执行计划
- 避免重复编译查询
- 提高查询性能
其他内存组件
- 查询工作区:用于排序、哈希连接等操作
- CLR 内存:用于 CLR 集成
- 锁管理器内存:用于管理锁
- 事务管理器内存:用于管理事务
事务管理
ACID 特性
- 原子性:事务中的所有操作要么全部成功,要么全部失败
- 一致性:事务执行前后,数据库状态保持一致
- 隔离性:多个事务并发执行时,彼此之间互不影响
- 持久性:事务提交后,数据更改永久保存
事务日志
- 记录所有数据更改操作
- 用于恢复数据库
- 实现 Write-Ahead Logging (WAL) 机制
隔离级别
- READ UNCOMMITTED:允许读取未提交的数据(脏读)
- READ COMMITTED:只能读取已提交的数据(默认隔离级别)
- REPEATABLE READ:确保在事务期间多次读取同一行时,结果一致
- SNAPSHOT:使用行版本控制,读取事务开始时的数据版本
- SERIALIZABLE:最高隔离级别,确保事务串行执行
并发控制
锁机制
- 共享锁 (S):用于读取操作
- 排他锁 (X):用于修改操作
- 更新锁 (U):用于更新操作的初始阶段
- 意向锁:表示事务对某个资源的锁定意图
行版本控制
- 用于 SNAPSHOT 隔离级别
- 存储行的多个版本
- 允许读取旧版本的数据,避免锁冲突
死锁处理
- 自动检测死锁
- 选择一个事务作为牺牲品进行回滚
- 可以通过设置
DEADLOCK_PRIORITY控制哪个事务被回滚
高可用性架构
1. Always On 可用性组
- 支持多个数据库的高可用性
- 提供自动故障转移
- 支持读写分离
- 最多支持 8 个辅助副本
2. 故障转移集群实例 (FCI)
- 基于 Windows Server 故障转移集群
- 提供实例级别的高可用性
- 共享存储或 Storage Spaces Direct
3. 日志传送
- 异步复制事务日志
- 支持多个辅助服务器
- 手动故障转移
4. 数据库镜像
- 异步或同步复制数据库
- 支持自动故障转移
- 已被 Always On 可用性组取代
云架构
1. Azure SQL Database
- 完全托管的云数据库服务
- 自动缩放和高可用性
- 智能性能优化
- 多种服务层级:Basic、Standard、Premium、Business Critical、Hyperscale
2. Azure SQL Managed Instance
- 完全托管的实例级服务
- 与本地 SQLServer 高度兼容
- 支持 CLR 集成和 SQL Server Agent
- 适合迁移现有应用程序
3. SQLServer 大数据集群
- 集成 SQLServer、Spark 和 HDFS
- 支持大数据分析
- 支持 PolyBase 查询外部数据
开发架构最佳实践
1. 数据库设计
- 遵循规范化原则,减少数据冗余
- 设计合适的索引策略
- 使用适当的数据类型
- 考虑分区表和分区索引
2. 应用程序设计
- 使用分层架构,分离关注点
- 实现数据访问层,统一数据库访问
- 使用参数化查询,防止 SQL 注入
- 实现连接池,提高性能
3. 性能优化
- 优化查询语句,避免全表扫描
- 使用适当的隔离级别
- 监控和调优数据库性能
- 定期更新统计信息
4. 高可用性和灾难恢复
- 选择合适的高可用性方案
- 定期备份数据库
- 测试恢复过程
- 实现异地灾备
5. 安全性
- 遵循最小权限原则
- 加密敏感数据
- 实现审计和监控
- 定期更新和修补数据库
常见问题 (FAQ)
Q: SQLServer 的逻辑架构和物理架构有什么区别?
A: 逻辑架构描述了 SQLServer 的功能组件和它们之间的关系,如查询处理器和存储引擎;物理架构描述了数据在磁盘上的存储方式,如数据文件、事务日志文件和数据页。
Q: 什么是缓冲池?它有什么作用?
A: 缓冲池是 SQLServer 内存中的数据页缓存,用于存储经常访问的数据页,减少磁盘 I/O,提高查询性能。
Q: 什么是事务日志?它有什么作用?
A: 事务日志记录所有数据更改操作,用于恢复数据库,确保事务的 ACID 特性。
Q: 什么是锁?SQLServer 支持哪些类型的锁?
A: 锁是 SQLServer 用于控制并发访问的机制,防止多个事务同时修改同一数据导致数据不一致。SQLServer 支持共享锁、排他锁、更新锁和意向锁等。
Q: 什么是 Always On 可用性组?它有什么优势?
A: Always On 可用性组是 SQLServer 2012 引入的高可用性功能,支持多个数据库的高可用性,提供自动故障转移和读写分离,最多支持 8 个辅助副本。
Q: 什么是 Azure SQL Database?它与本地 SQLServer 有什么区别?
A: Azure SQL Database 是完全托管的云数据库服务,与本地 SQLServer 相比,无需管理基础设施,自动缩放和高可用性,智能性能优化,但有一些功能差异和限制。
总结
SQLServer 开发架构包括逻辑架构、物理架构和应用程序开发架构。逻辑架构描述了 SQLServer 的核心组件,如查询处理器和存储引擎;物理架构描述了数据在磁盘上的存储方式;应用程序开发架构包括客户端-服务器架构、三层架构、微服务架构和云原生架构。
了解 SQLServer 开发架构有助于设计合理的数据库架构、优化查询性能、确保数据安全和高可用性。在开发 SQLServer 应用程序时,需要根据实际需求选择合适的数据访问技术和开发模式,并遵循最佳实践,以确保应用程序的性能、可靠性和安全性。
