SQL Server 基础架构与安装配置
1.1 SQL Server 整体架构概述
SQL Server 是微软出品的企业级关系型数据库管理系统(RDBMS),自 1989 年发布以来,已演进为集 OLTP、数据仓库、分析服务、报表服务于一体的完整数据平台。与 MySQL 的插件式存储引擎不同,SQL Server 采用单一存储引擎设计,通过协议层、关系引擎层、存储引擎层三层协作提供数据服务。
1.1.1 逻辑架构层次
┌─────────────────────────────────────────┐
│ 客户端应用程序 │
│ (SSMS / ADS / .NET / ODBC / JDBC) │
└────────────────┬────────────────────────┘
│ TDS 协议 (TCP 1433)
┌────────────────▼────────────────────────┐
│ SQL Server 实例(Instance) │
│ ┌──────────────────────────────────┐ │
│ │ 协议层(SNI) │ │
│ │ TCP/IP · Named Pipes · VIA │ │
│ └──────────────┬───────────────────┘ │
│ ┌──────────────▼───────────────────┐ │
│ │ 关系引擎(Relational Engine)│ │
│ │ 解析器→代数化→优化器→执行器 │ │
│ └──────────────┬───────────────────┘ │
│ ┌──────────────▼───────────────────┐ │
│ │ 存储引擎(Storage Engine) │ │
│ │ Buffer Pool · Lock Manager │ │
│ │ Transaction Manager · Log Mgr │ │
│ └──────────────┬───────────────────┘ │
└─────────────────┼───────────────────────┘
│ Win32 / Linux I/O
┌───────▼────────┐
│ 物理文件 │
│ .mdf .ndf .ldf │
└────────────────┘
1.1.2 实例与数据库的关系
一台主机可安装多个 SQL Server 实例(Instance),每个实例相互隔离,独立管理自己的数据库集合。
| 概念 | 说明 | 示例 |
|---|---|---|
| 实例 | SQL Server 服务进程,拥有独立端口和配置 | MSSQLSERVER(默认)、SQLEXPRESS |
| 数据库 | 实例内的数据容器,包含对象和数据 | master、AdventureWorks |
| 文件组 | 数据库内的文件组织单元,用于 IO 分离 | PRIMARY、FG_History |
| 数据文件 | 存储数据页的物理文件(.mdf / .ndf) | AdventureWorks.mdf |
| 日志文件 | 存储事务日志的物理文件(.ldf) | AdventureWorks_log.ldf |
-- 查询当前实例名称
SELECT @@SERVERNAME AS InstanceName,
@@VERSION AS SQLServerVersion;
-- 查看实例下所有数据库
SELECT name,
state_desc,
recovery_model_desc,
compatibility_level
FROM sys.databases
ORDER BY name;
1.1.3 物理存储结构:页与区
SQL Server 所有数据的最小存储单位是页(Page),大小固定为 8 KB。8 个连续的页组成一个区(Extent)(64 KB)。
┌──────────── 区(Extent = 64KB)────────────┐
│ Page1(8KB) Page2(8KB) Page3(8KB) Page4(8KB) │
│ Page5(8KB) Page6(8KB) Page7(8KB) Page8(8KB) │
└─────────────────────────────────────────────┘
页头(96字节)
├── PageID
├── LSN(日志序列号)
├── CheckSum
└── 行偏移数组
├── 行数据区(可变长度行)
└── 空闲空间
页类型: - 数据页(Data Page):存储用户表的实际行数据 - 索引页(Index Page):存储 B+Tree 索引节点 - IAM 页:追踪区分配情况 - PFS 页:追踪页的空间使用率
1.2 安装部署与环境配置
1.2.1 Windows Server 安装(推荐生产环境)
前置准备:
# 检查 .NET Framework 版本(需 4.6+)
[System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()
# 调整 Windows 电源计划为高性能
powercfg -setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
# 禁用 Windows 自动更新(生产数据库机器)
Set-Service -Name wuauserv -StartupType Disabled
# 格式化数据盘(建议 64KB 分配单元大小)
# 在磁盘管理中或使用 diskpart 完成
静默安装参数示例(SQL Server 2022):
setup.exe /Q ^
/ACTION=Install ^
/FEATURES=SQLENGINE,REPLICATION,FULLTEXT ^
/INSTANCENAME=MSSQLSERVER ^
/SQLSYSADMINACCOUNTS="DOMAIN\SQLAdmins" ^
/SQLCOLLATION=Chinese_PRC_CI_AS ^
/SQLBACKUPDIR="E:\SQLBackup" ^
/SQLUSERDBDIR="D:\SQLData" ^
/SQLUSERDBLOGDIR="F:\SQLLog" ^
/SQLTEMPDBDIR="G:\TempDB" ^
/SQLTEMPDBLOGDIR="G:\TempDB" ^
/SQLTEMPDBFILECOUNT=8 ^
/SQLTEMPDBFILESIZE=512 ^
/SQLTEMPDBFILEGROWTH=512 ^
/SQLTEMPDBLOGFILESIZE=128 ^
/IACCEPTSQLSERVERLICENSETERMS ^
/UPDATEENABLED=FALSE
最佳实践:将数据文件、日志文件、TempDB 分别放在不同物理磁盘,避免 IO 竞争。
1.2.2 Linux(Ubuntu 22.04)安装
# 1. 导入 Microsoft GPG 密钥
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
# 2. 添加 SQL Server 2022 存储库
sudo add-apt-repository "$(curl https://packages.microsoft.com/config/ubuntu/22.04/mssql-server-2022.list)"
# 3. 安装 SQL Server
sudo apt-get update
sudo apt-get install -y mssql-server
# 4. 运行初始配置向导
sudo /opt/mssql/bin/mssql-conf setup
# 选择 Edition(建议选 Developer 用于学习)
# 输入 SA 密码(复杂度要求:大小写+数字+特殊字符,最少8位)
# 5. 验证服务状态
systemctl status mssql-server
# 6. 安装命令行工具 sqlcmd
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list | sudo tee /etc/apt/sources.list.d/msprod.list
sudo apt-get update
sudo apt-get install -y mssql-tools unixodbc-dev
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# 7. 连接验证
sqlcmd -S localhost -U SA -P 'YourStrong@Passw0rd' -Q "SELECT @@VERSION"
1.2.3 关键配置参数(mssql-conf / 注册表)
# Linux mssql-conf 常用配置
sudo /opt/mssql/bin/mssql-conf set memory.memorylimitmb 8192 # 限制最大内存 8GB
sudo /opt/mssql/bin/mssql-conf set network.tcpport 1433 # TCP 端口
sudo /opt/mssql/bin/mssql-conf set sqlagent.enabled true # 启用 SQL Agent
sudo /opt/mssql/bin/mssql-conf set hadr.hadrenabled 1 # 启用 Always On
sudo /opt/mssql/bin/mssql-conf traceflag 1118 1117 on # TempDB 优化标志
-- Windows 端:通过 sp_configure 修改服务器配置
-- 开启高级选项
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
-- 最大服务器内存(MB),留 10-15% 给 OS
EXEC sp_configure 'max server memory (MB)', 24576; -- 24GB
-- 最小服务器内存(MB)
EXEC sp_configure 'min server memory (MB)', 4096;
-- 最大并行度(MAXDOP),通常设置为物理核心数的一半
EXEC sp_configure 'max degree of parallelism', 8;
-- 并行查询代价阈值(Cost Threshold for Parallelism)
EXEC sp_configure 'cost threshold for parallelism', 50;
-- 优化 Ad-hoc 查询缓存
EXEC sp_configure 'optimize for ad hoc workloads', 1;
RECONFIGURE WITH OVERRIDE;
-- 验证当前配置
SELECT name, value, value_in_use, description
FROM sys.configurations
ORDER BY name;
1.2.4 排序规则(Collation)选择
排序规则决定了字符的存储、排序和比较规则,安装后极难更改,需提前规划。
-- 查看所有支持的排序规则(含中文)
SELECT *
FROM fn_helpcollations()
WHERE name LIKE 'Chinese%';
-- 常用中文排序规则说明
-- Chinese_PRC_CI_AS : 简体中文,不区分大小写,区分重音(最常用)
-- Chinese_PRC_CS_AS : 简体中文,区分大小写,区分重音
-- Chinese_PRC_CI_AI : 简体中文,不区分大小写,不区分重音
-- 在数据库级别修改排序规则(仅影响新创建的列)
ALTER DATABASE [YourDB] COLLATE Chinese_PRC_CI_AS;
-- 检查数据库和列的排序规则
SELECT DB_NAME() AS DatabaseName,
DATABASEPROPERTYEX(DB_NAME(), 'Collation') AS DBCollation;
SELECT t.name AS TableName,
c.name AS ColumnName,
c.collation_name
FROM sys.tables t
JOIN sys.columns c ON t.object_id = c.object_id
WHERE c.collation_name IS NOT NULL;
1.3 系统数据库详解与 TempDB 优化
1.3.1 五大系统数据库职责
| 数据库 | 职责 | 重要文件 | 注意事项 |
|---|---|---|---|
| master | 实例级元数据:登录名、端点、链接服务器、配置 | master.mdf | 损坏则实例无法启动,必须定期备份 |
| model | 用户数据库的模板,新建库时复制 model | model.mdf | 在此创建的对象会出现在所有新数据库中 |
| msdb | SQL Server Agent 历史、备份历史、作业、警报 | msdb.mdf | 定期备份;支持数据库邮件配置 |
| tempdb | 临时表、表变量、中间结果、版本存储 | tempdb.mdf×N | 每次重启重建;是最大争用热点 |
| resource | 隐藏的只读库,存储系统对象 | mssqlsystemresource.mdf | 不可直接访问;SP 升级时替换此文件 |
-- 查看 master 库中的登录名
SELECT name, type_desc, create_date, is_disabled
FROM master.sys.server_principals
WHERE type IN ('S', 'U', 'G')
ORDER BY name;
-- 查看 msdb 中最近 7 天的备份记录
SELECT bs.database_name,
bs.backup_start_date,
bs.backup_finish_date,
bs.type,
CAST(bs.backup_size / 1048576.0 AS DECIMAL(10,2)) AS SizeMB,
bmf.physical_device_name
FROM msdb.dbo.backupset bs
JOIN msdb.dbo.backupmediafamily bmf
ON bs.media_set_id = bmf.media_set_id
WHERE bs.backup_start_date >= DATEADD(DAY, -7, GETDATE())
ORDER BY bs.backup_start_date DESC;
1.3.2 TempDB 深度优化
TempDB 是 SQL Server 中竞争最激烈的系统资源,所有用户共享,常见瓶颈包括: - SGAM/GAM/PFS 页闩锁争用:大量并发分配临时对象 - 版本存储增长:快照隔离(RCSI)产生大量行版本
核心优化策略:多文件并行分配
-- 查看当前 TempDB 文件数和大小
SELECT name,
physical_name,
CAST(size * 8.0 / 1024 AS DECIMAL(10,2)) AS SizeMB,
CAST(max_size * 8.0 / 1024 AS DECIMAL(10,2)) AS MaxSizeMB,
growth,
is_percent_growth
FROM tempdb.sys.database_files;
-- 最佳实践:数据文件数 = min(逻辑CPU核心数, 8)
-- 所有数据文件大小相等(消除不均匀分配)
-- 关闭自动增长或设置固定增量
-- 示例:添加 TempDB 数据文件(共 8 个,每个 512MB)
USE tempdb;
ALTER DATABASE tempdb
ADD FILE (NAME = 'tempdev2', FILENAME = 'G:\TempDB\tempdev2.ndf', SIZE = 512MB, FILEGROWTH = 256MB),
ADD FILE (NAME = 'tempdev3', FILENAME = 'G:\TempDB\tempdev3.ndf', SIZE = 512MB, FILEGROWTH = 256MB),
ADD FILE (NAME = 'tempdev4', FILENAME = 'G:\TempDB\tempdev4.ndf', SIZE = 512MB, FILEGROWTH = 256MB),
ADD FILE (NAME = 'tempdev5', FILENAME = 'G:\TempDB\tempdev5.ndf', SIZE = 512MB, FILEGROWTH = 256MB),
ADD FILE (NAME = 'tempdev6', FILENAME = 'G:\TempDB\tempdev6.ndf', SIZE = 512MB, FILEGROWTH = 256MB),
ADD FILE (NAME = 'tempdev7', FILENAME = 'G:\TempDB\tempdev7.ndf', SIZE = 512MB, FILEGROWTH = 256MB),
ADD FILE (NAME = 'tempdev8', FILENAME = 'G:\TempDB\tempdev8.ndf', SIZE = 512MB, FILEGROWTH = 256MB);
-- 修改现有 tempdev 文件大小保持一致
ALTER DATABASE tempdb MODIFY FILE (NAME = 'tempdev', SIZE = 512MB, FILEGROWTH = 256MB);
-- 监控 TempDB 空间使用
SELECT SUM(unallocated_extent_page_count) * 8.0 / 1024 AS FreeSpaceMB,
SUM(version_store_reserved_page_count) * 8.0 / 1024 AS VersionStoreMB,
SUM(user_object_reserved_page_count) * 8.0 / 1024 AS UserObjectsMB,
SUM(internal_object_reserved_page_count) * 8.0 / 1024 AS InternalObjectsMB
FROM sys.dm_db_file_space_usage;
-- 找出占用 TempDB 最多的会话
SELECT s.session_id,
s.login_name,
t.user_objects_alloc_page_count * 8 AS UserObjKB,
t.internal_objects_alloc_page_count * 8 AS InternalObjKB,
r.text AS QueryText
FROM sys.dm_db_session_space_usage t
JOIN sys.dm_exec_sessions s ON t.session_id = s.session_id
OUTER APPLY sys.dm_exec_sql_text(
(SELECT TOP 1 sql_handle FROM sys.dm_exec_requests r2
WHERE r2.session_id = t.session_id)) r
WHERE t.user_objects_alloc_page_count + t.internal_objects_alloc_page_count > 0
ORDER BY (t.user_objects_alloc_page_count + t.internal_objects_alloc_page_count) DESC;
1.4 管理工具实战
1.4.1 SSMS 核心功能
SQL Server Management Studio(SSMS) 是 SQL Server 最主要的图形化管理工具。
常用快捷键:
| 快捷键 | 功能 |
|---|---|
F5 |
执行选中 SQL |
Ctrl+L |
显示估计执行计划 |
Ctrl+M |
包含实际执行计划 |
Ctrl+K, Ctrl+C |
注释选中代码 |
Ctrl+K, Ctrl+U |
取消注释 |
Shift+Alt+↑/↓ |
多行编辑 |
Ctrl+Shift+R |
刷新 IntelliSense 缓存 |
注册服务器(管理多实例):
-- 通过 SSMS 的"注册服务器"功能,可以集中管理多个实例
-- 在中央管理服务器(CMS)上注册所有子服务器后,可以跨服务器批量执行查询
-- 示例:查询所有注册服务器的版本(在 CMS 中执行)
SELECT @@SERVERNAME, @@VERSION;
1.4.2 sqlcmd 命令行客户端
# 基本连接
sqlcmd -S <server>\<instance> -U <user> -P <password> -d <database>
# 使用 Windows 身份验证
sqlcmd -S MyServer -E
# 执行 SQL 文件
sqlcmd -S MyServer -E -i "C:\Scripts\deploy.sql" -o "C:\Scripts\deploy.log"
# 执行内联查询
sqlcmd -S MyServer -E -Q "SELECT @@VERSION" -W -s ","
# 在脚本中使用变量
sqlcmd -S MyServer -E -v DBName="AdventureWorks" -Q "USE $(DBName); SELECT COUNT(*) FROM Sales.Orders"
# 批量导出数据(bcp 工具)
bcp "SELECT TOP 1000 * FROM AdventureWorks.Sales.SalesOrderHeader" queryout "C:\Export\orders.txt" -S MyServer -T -c -t"," -r"\n"
# 批量导入数据
bcp AdventureWorks.dbo.ImportTable IN "C:\Data\import.txt" -S MyServer -T -c -t"," -r"\n" -F2
1.4.3 PowerShell DBA 脚本
# 安装 SqlServer PowerShell 模块
Install-Module -Name SqlServer -Force -AllowClobber
# 导入模块
Import-Module SqlServer
# 查询数据库列表
Get-SqlDatabase -ServerInstance "MyServer" |
Select-Object Name, Status, Size, RecoveryModel |
Format-Table -AutoSize
# 执行 T-SQL 查询
Invoke-Sqlcmd -ServerInstance "MyServer" -Database "master" -Query "
SELECT TOP 10
DB_NAME(database_id) AS DBName,
COUNT(*) AS OpenTransactions
FROM sys.dm_tran_active_transactions
GROUP BY database_id
"
# 批量备份所有用户数据库
$server = "MyServer"
$backupPath = "E:\SQLBackup"
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
Get-SqlDatabase -ServerInstance $server |
Where-Object { $_.Name -notin @('master','model','msdb','tempdb') -and $_.Status -eq 'Normal' } |
ForEach-Object {
$dbName = $_.Name
$backupFile = "$backupPath\$dbName`_$timestamp.bak"
Write-Host "备份 $dbName → $backupFile"
Backup-SqlDatabase -ServerInstance $server -Database $dbName -BackupFile $backupFile -CompressionOption On
}
# 检查磁盘空间(对所有注册实例)
$instances = @("Server01", "Server02", "Server03")
foreach ($inst in $instances) {
Invoke-Sqlcmd -ServerInstance $inst -Query "
SELECT SERVERPROPERTY('MachineName') AS Host,
volume_mount_point,
CAST(available_bytes/1073741824.0 AS DECIMAL(10,2)) AS FreeGB,
CAST(total_bytes/1073741824.0 AS DECIMAL(10,2)) AS TotalGB
FROM sys.dm_os_volume_stats(1, 1)
"
}
1.4.4 系统健康检查脚本
-- ============================================================
-- SQL Server 实例健康检查(每日运维必备)
-- ============================================================
-- 1. 实例基本信息
SELECT SERVERPROPERTY('ServerName') AS InstanceName,
SERVERPROPERTY('ProductVersion') AS Version,
SERVERPROPERTY('Edition') AS Edition,
SERVERPROPERTY('Collation') AS Collation,
SERVERPROPERTY('IsClustered') AS IsClustered,
SERVERPROPERTY('IsHadrEnabled') AS IsAlwaysOnEnabled;
-- 2. 查看等待统计(识别瓶颈)
SELECT TOP 20
wait_type,
waiting_tasks_count,
CAST(wait_time_ms / 1000.0 AS DECIMAL(10,2)) AS WaitTimeSec,
CAST(signal_wait_time_ms / 1000.0 AS DECIMAL(10,2)) AS SignalWaitSec,
CAST(wait_time_ms * 100.0 / SUM(wait_time_ms) OVER() AS DECIMAL(5,2)) AS PctTotal
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN (
'SLEEP_TASK','BROKER_TO_FLUSH','BROKER_TASK_STOP','CLR_AUTO_EVENT',
'DISPATCHER_QUEUE_SEMAPHORE','FT_IFTS_SCHEDULER_IDLE_WAIT',
'HADR_FILESTREAM_IOMGR_IOCOMPLETION','HADR_WORK_QUEUE',
'LAZYWRITER_SLEEP','LOGMGR_QUEUE','ONDEMAND_TASK_QUEUE',
'REQUEST_FOR_DEADLOCK_MONITOR','RESOURCE_QUEUE','SERVER_IDLE_CHECK',
'SLEEP_DBSTARTUP','SLEEP_DCOMSTARTUP','SLEEP_MASTERDBREADY',
'SLEEP_MASTERMDREADY','SLEEP_MASTERUPGRADED','SLEEP_MSDBSTARTUP',
'SLEEP_SYSTEMTASK','SLEEP_TEMPDBSTARTUP','SNI_HTTP_ACCEPT',
'SP_SERVER_DIAGNOSTICS_SLEEP','SQLAGENT_ALERT_SET',
'SQLAGENT_LOCK_MONITOR','SQLAGENT_NOTIFY','SQLAGENT_WAIT_ON_OPER',
'WAIT_XTP_OFFLINE_CKPT_NEW_LOG','WAITFOR','XE_DISPATCHER_WAIT',
'XE_TIMER_EVENT','BROKER_EVENTHANDLER','CHECKPOINT_QUEUE',
'DBMIRROR_EVENTS_QUEUE','SQLAGENT_STEPS_THREAD','TRACEWRITE',
'XE_DISPATCHER_JOIN')
ORDER BY wait_time_ms DESC;
-- 3. 检查数据库文件空间
SELECT DB_NAME(vfs.database_id) AS DatabaseName,
mf.name AS LogicalName,
mf.physical_name,
mf.type_desc,
CAST(vfs.size_on_disk_bytes / 1048576.0 AS DECIMAL(10,2)) AS FileSizeMB,
CAST(FILEPROPERTY(mf.name,'SpaceUsed') * 8.0 / 1024 AS DECIMAL(10,2)) AS UsedMB
FROM sys.dm_io_virtual_file_stats(NULL, NULL) vfs
JOIN sys.master_files mf ON vfs.database_id = mf.database_id
AND vfs.file_id = mf.file_id
ORDER BY vfs.database_id, mf.file_id;
-- 4. 当前阻塞链
SELECT r.session_id,
r.blocking_session_id,
r.wait_type,
r.wait_time / 1000 AS WaitSec,
SUBSTRING(t.text, (r.statement_start_offset/2)+1,
((CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(t.text)
ELSE r.statement_end_offset END - r.statement_start_offset)/2)+1) AS CurrentSQL,
s.login_name,
s.host_name,
s.program_name
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.blocking_session_id > 0
ORDER BY r.wait_time DESC;
1.5 小结
| 知识点 | 要点 |
|---|---|
| 架构层次 | 协议层 → 关系引擎 → 存储引擎 → 物理文件 |
| 页/区 | 最小 IO 单位 8KB(页),64KB(区) |
| 安装要点 | 数据/日志/TempDB 分离磁盘;规划好排序规则 |
| TempDB 优化 | 文件数 = min(CPU核, 8);文件大小均等 |
| 系统库 | master 备份优先级最高;tempdb 每次重建 |
| 工具链 | SSMS(日常操作)+ sqlcmd(自动化)+ PowerShell(批量管理) |
下一章:T-SQL 查询基础
文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有