深度探索:SQL Server 技术学习之旅

引言

在数字化时代,数据库管理系统作为企业信息系统的核心组件,承载着海量数据的存储、管理和分析重任。其中,Microsoft SQL Server作为一款久经市场考验的企业级关系型数据库平台,凭借其强大的功能、卓越的性能以及与微软生态系统的深度集成,赢得了全球众多企业的青睐。本文旨在引导读者踏上深入学习SQL Server的旅程,全方位领略其核心技术要点,为构建高效、稳定且安全的数据库系统奠定坚实基础。

一、SQL基础与SQL Server特定语法

SQL Server的基础SQL语言与特定的T-SQL语法涵盖了数据定义、数据操纵、数据查询以及数据控制等多个方面。以下是一些关键语法示例及详细讲解:

1. 数据定义语言 (DDL)

创建表

CREATE TABLE Customers (
    CustomerID int NOT NULL,
    Name varchar(50) NOT NULL,
    Email varchar(100),
    Phone varchar(20),
    Address varchar(200),
    PRIMARY KEY (CustomerID)
);

讲解:

  • CREATE TABLE 语句用于创建名为 Customers 的新表。
  • 定义了五列:CustomerID(整数类型,不允许为空),Name(最多50个字符的字符串,不允许为空),Email(最多100个字符的字符串),Phone(最多20个字符的字符串),和 Address(最多200个字符的字符串)。
  • PRIMARY KEY 指定 CustomerID 列为主键,用于唯一标识每条记录,并自动添加唯一性约束。

修改表结构

ALTER TABLE Customers
ADD City varchar(50) DEFAULT 'Unknown',
ADD CONSTRAINT CHK_PhoneFormat CHECK (Phone LIKE '[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]');

ALTER TABLE Customers
DROP COLUMN Address;

讲解:

  • ALTER TABLE 用于修改已存在的表结构。
  • 第一条语句向 Customers 表中添加了一列 City,默认值为 'Unknown',同时添加了一个名为 CHK_PhoneFormat 的检查约束,确保 Phone 列的值符合特定电话号码格式。
  • 第二条语句删除了 Customers 表中的 Address 列。

删除表

DROP TABLE Customers;

讲解:

  • DROP TABLE 命令用于彻底删除名为 Customers 的表及其所有数据。

2. 数据操纵语言 (DML)

插入数据

INSERT INTO Customers (CustomerID, Name, Email, Phone)
VALUES (1, 'John Doe', 'john.doe@example.com', '123-456-7890');

讲解:

  • INSERT INTO 语句用于向 Customers 表中插入一条新记录。
  • 指定了要插入的列名及其对应的值。

更新数据

UPDATE Customers
SET Email = 'jane.doe@example.com', Phone = '555-1212'
WHERE CustomerID = 1;

讲解:

  • UPDATE 语句用于修改 Customers 表中已存在的记录。
  • 使用 SET 语句更新 Email 和 Phone 列的值。
  • WHERE 子句指定更新哪些记录,这里选择了 CustomerID 为 1 的记录。

删除数据

DELETE FROM Customers
WHERE CustomerID = 1;

讲解:

  • DELETE FROM 语句用于删除 Customers 表中满足条件的记录。
  • WHERE 子句指定要删除的记录,这里选择了 CustomerID 为 1 的记录。

3. 数据查询语言 (DQL)

简单查询

SELECT CustomerID, Name, Email
FROM Customers
WHERE City = 'New York';

讲解:

  • SELECT 语句用于从 Customers 表中检索数据。
  • 指定了要返回的列:CustomerID, Name, 和 Email。
  • FROM 子句指定了数据源表。
  • WHERE 子句过滤出 City 列值为 'New York' 的记录。

联接查询

SELECT c.CustomerID, c.Name, o.OrderDate
FROM Customers c
INNER JOIN Orders o ON c.CustomerID = o.CustomerID;

讲解:

  • INNER JOIN 用于连接 Customers 表(别名 c)和 Orders 表(别名 o),基于两个表中 CustomerID 列的相等值。
  • 返回的结果集包含两个表中匹配的行的组合,显示 CustomerID, Name(来自 Customers 表)和 OrderDate(来自 Orders 表)。

4. 数据控制语言 (DCL)

授予权限

GRANT SELECT ON Customers TO User1;

讲解:

  • GRANT 语句用于授予用户或角色特定的权限。
  • 这里将 SELECT 权限赋予了用户名为 User1 的用户,允许其对 Customers 表进行查询操作。

撤销权限

REVOKE DELETE ON Customers FROM User1;

讲解:

  • REVOKE 语句用于撤销用户或角色已有的权限。
  • 这里撤销了 User1 对 Customers 表的 DELETE 权限,使其无法删除表中的记录。

5. T-SQL 特定语法

变量声明与使用

DECLARE @CustomerName varchar(50) = 'John Doe';

SELECT * FROM Customers WHERE Name = @CustomerName;

讲解:

  • DECLARE 语句用于声明一个局部变量 @CustomerName,类型为 varchar(50),并初始化为 'John Doe'。
  • 在后续的 SELECT 查询中,使用该变量作为 WHERE 子句的条件,动态指定要查找的客户名称。

IF...ELSE 语句

IF EXISTS (SELECT 1 FROM Customers WHERE Email = 'john.doe@example.com')
BEGIN
    PRINT 'Customer with email john.doe@example.com already exists.';
END
ELSE
BEGIN
    INSERT INTO Customers (Name, Email) VALUES ('John Doe', 'john.doe@example.com');
    PRINT 'New customer added successfully.';
END;

讲解:

  • IF...ELSE 语句用于实现条件分支逻辑。
  • 检查 Customers 表中是否存在指定邮箱的记录,如果存在则打印消息,否则插入新记录并打印成功消息。

TRY...CATCH 错误处理

BEGIN TRY
    INSERT INTO Customers (CustomerID, Name) VALUES (1, 'John Doe');
END TRY
BEGIN CATCH
    DECLARE @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int;
    SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE();

    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH;

讲解:

  • TRY...CATCH 语句用于捕获并处理执行过程中可能出现的错误。
  • 在 TRY 块中尝试执行可能引发错误的操作(如插入重复主键)。
  • 如果发生错误,控制权转移到 CATCH 块,其中捕获错误信息(如错误消息、严重性、状态),并通过 RAISERROR 重新抛出这些信息,以便进一步处理或记录。


二、数据库设计理论与实践

数据库设计理论包括概念设计、逻辑设计和物理设计三个阶段,而实践则涉及具体的SQL Server对象创建、数据模型优化以及数据完整性、安全性等方面的实现。以下是一些SQL Server数据库设计理论与实践的代码示例及详细讲解:

1. 概念设计:实体关系图(ERD)
示例说明: 实体关系图(ERD)是一种图形化工具,用于可视化表示数据实体、属性以及它们之间的关系。在实践中,通常使用专门的数据库设计工具(如Visio、ER/Studio、PowerDesigner等)绘制ERD,而不是直接编写SQL代码。然而,ERD的设计原则直接影响到后续的逻辑和物理设计。

关键原则:

  • 实体:代表现实世界中的对象,如“顾客”、“订单”、“产品”等。
  • 属性:描述实体特征的数据项,如“顾客ID”、“姓名”、“电子邮件”等。
  • 关系:表示实体间的关联,如“顾客”与“订单”的“购买”关系,可以是一对一、一对多、多对多。
  • 键:实体的唯一标识符,如“顾客ID”是“顾客”实体的主键。
  • 外键:在一个实体中引用另一个实体主键的属性,如“订单”表中的“顾客ID”是“顾客”表主键的外键。

2. 逻辑设计:从ERD到关系模式

示例代码:

CREATE TABLE Customers (
    CustomerID int NOT NULL,
    FirstName varchar(50) NOT NULL,
    LastName varchar(50) NOT NULL,
    Email varchar(100) UNIQUE,
    PhoneNumber varchar(20),
    Address varchar(200),
    City varchar(50),
    State char(2),
    ZipCode varchar(10),
    CONSTRAINT PK_Customers PRIMARY KEY (CustomerID)
);

CREATE TABLE Products (
    ProductID int NOT NULL,
    ProductName varchar(100) NOT NULL,
    CategoryID int NOT NULL,
    Price decimal(10, 2) NOT NULL,
    CONSTRAINT PK_Products PRIMARY KEY (ProductID),
    CONSTRAINT FK_Products_Categories FOREIGN KEY (CategoryID) REFERENCES Categories(CategoryID)
);

CREATE TABLE Orders (
    OrderID int NOT NULL,
    CustomerID int NOT NULL,
    OrderDate datetime NOT NULL,
    TotalAmount decimal(10, 2) NOT NULL,
    CONSTRAINT PK_Orders PRIMARY KEY (OrderID),
    CONSTRAINT FK_Orders_Customers FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);

CREATE TABLE OrderDetails (
    OrderDetailID int NOT NULL,
    OrderID int NOT NULL,
    ProductID int NOT NULL,
    Quantity int NOT NULL,
    UnitPrice decimal(10, 2) NOT NULL,
    CONSTRAINT PK_OrderDetails PRIMARY KEY (OrderDetailID),
    CONSTRAINT FK_OrderDetails_Orders FOREIGN KEY (OrderID) REFERENCES Orders(OrderID),
    CONSTRAINT FK_OrderDetails_Products FOREIGN KEY (ProductID) REFERENCES Products(ProductID)
);

讲解:

  • 逻辑设计阶段将ERD转换为关系模式,即创建相应的表结构。
  • 上述代码展示了四个表的创建:Customers、Products、Orders 和 OrderDetails,分别对应于“顾客”、“产品”、“订单”和“订单详情”实体。
  • 每个表都有定义明确的列(属性)、数据类型、约束(如主键、外键、唯一键、非空等)。
  • 主键(PRIMARY KEY)用于唯一标识表中的每一行。
  • 外键(FOREIGN KEY)约束确保引用的值存在于被引用表的主键中,维护数据的一致性。

3. 物理设计:考虑存储、索引与性能

示例代码:

-- 创建聚集索引
CREATE CLUSTERED INDEX IX_Customers_CustomerID ON Customers (CustomerID);

-- 创建非聚集索引
CREATE NONCLUSTERED INDEX IX_Products_Name ON Products (ProductName);

-- 创建复合索引
CREATE NONCLUSTERED INDEX IX_Orders_CustomerID_OrderDate ON Orders (CustomerID, OrderDate);

-- 数据分区
CREATE PARTITION FUNCTION OrderDateRangePF (datetime)
AS RANGE RIGHT FOR VALUES ('2022-01-01', '2023-01-01', '2024-01-01');

CREATE PARTITION SCHEME OrderDateRangePS AS PARTITION OrderDateRangePF
TO (FG2022, FG2023, FG2024);

ALTER TABLE Orders
ADD CONSTRAINT PK_Orders_Partitioned PRIMARY KEY (OrderID) ON OrderDateRangePS(OrderDate);

讲解:

  • 物理设计阶段关注数据库在物理存储层面上的优化,如选择合适的索引、数据分区等。
  • 聚集索引(如 IX_Customers_CustomerID)决定了表中数据的物理存储顺序,通常基于频繁用于查询和排序的列创建。
  • 非聚集索引(如 IX_Products_Name 和 IX_Orders_CustomerID_OrderDate)在独立的索引结构中存储键值和行指针,加快特定查询条件下的数据检索。
  • 复合索引(如 IX_Orders_CustomerID_OrderDate)包含多个列,对于包含这些列组合的查询尤其高效。
  • 数据分区(如 Orders 表的分区)将大表按一定规则(如按时间范围)划分为多个较小的部分,有利于管理和维护大型数据集,提高查询性能。这里创建了一个基于OrderDate的分区函数,并将其应用于Orders表的主键上,将数据分布到不同的文件组(FG2022、FG2023、FG2024)。

4. 数据完整性
示例代码:

-- 添加检查约束
ALTER TABLE Customers
ADD CONSTRAINT CHK_EmailFormat CHECK (Email LIKE '%@%.%');

-- 添加默认值
ALTER TABLE Orders
ADD DEFAULT GETDATE() FOR OrderDate;

-- 添加触发器确保订单总额正确
CREATE TRIGGER trg_UpdateTotalAmount ON OrderDetails
AFTER INSERT, UPDATE
AS
BEGIN
    UPDATE o
    SET TotalAmount = SUM(od.Quantity * od.UnitPrice)
    FROM Orders o
    INNER JOIN inserted i ON o.OrderID = i.OrderID
    INNER JOIN OrderDetails od ON i.OrderID = od.OrderID
    GROUP BY o.OrderID;
END;

讲解:

  • 数据完整性确保数据库中的数据准确、一致且符合业务规则。
  • 检查约束(如 CHK_EmailFormat)限制了Customers表中Email列的格式,确保输入有效的电子邮件地址。
  • 默认值(如 Orders 表的OrderDate列)在插入新记录时自动填充当前日期,省去手动输入。
  • 触发器(如 trg_UpdateTotalAmount)在OrderDetails表发生插入或更新时自动更新关联Orders表的TotalAmount列,确保订单总额始终准确。

5. 安全性与权限管理

示例代码:

-- 创建登录名
CREATE LOGIN AppUser WITH PASSWORD = 'StrongPassword123!';

-- 创建数据库用户映射到登录名
USE YourDatabase;
CREATE USER AppUser FOR LOGIN AppUser;

-- 授予权限
GRANT SELECT, INSERT, UPDATE, DELETE ON dbo.Customers TO AppUser;
DENY UPDATE ON dbo.Orders TO AppUser;

-- 创建角色并分配权限
CREATE ROLE SalesTeam;
GRANT SELECT ON dbo.Products TO SalesTeam;
EXEC sp_addrolemember 'SalesTeam', 'AppUser';

讲解:

  • 安全性管理确保只有经过授权的用户才能访问或操作数据库资源。
  • 登录名(如 AppUser)用于用户连接到SQL Server实例。
  • 数据库用户(也叫用户)与登录名关联,限定在特定数据库内的权限。
  • GRANT 语句授予用户对特定对象(如 Customers 表)的特定权限


三、数据库对象管理

SQL Server的数据库对象管理涉及对各种数据库对象(如表、视图、存储过程、函数、触发器、索引、约束等)的创建、修改、删除以及权限分配等操作。以下是关于SQL Server数据库对象管理的一些代码示例及详细讲解:

1. 表管理

a. 创建表

CREATE TABLE Customers (
    CustomerID int NOT NULL,
    Name varchar(50) NOT NULL,
    Email varchar(100) UNIQUE,
    PhoneNumber varchar(20),
    Address varchar(200),
    City varchar(50),
    State char(2),
    ZipCode varchar(10),
    CONSTRAINT PK_Customers PRIMARY KEY (CustomerID)
);

讲解:

  • CREATE TABLE 语句用于创建名为 Customers 的新表。
  • 定义了表的列名、数据类型、是否允许为空以及约束(如主键、唯一键)。

b. 修改表结构

ALTER TABLE Customers
ADD BirthDate date;

ALTER TABLE Customers
DROP COLUMN Address;

讲解:

  • ALTER TABLE 语句用于修改已存在的表结构。
  • 第一条语句向 Customers 表中添加了一个名为 BirthDate 的新列,数据类型为 date。
  • 第二条语句删除了 Customers 表中的 Address 列。

c. 删除表

DROP TABLE Customers;

讲解:

  • DROP TABLE 命令用于彻底删除名为 Customers 的表及其所有数据。

2. 视图管理

a. 创建视图

CREATE VIEW ActiveCustomers AS
SELECT CustomerID, Name, Email
FROM Customers
WHERE IsActive = 1;

讲解:

  • CREATE VIEW 语句创建了一个名为 ActiveCustomers 的视图,它基于 Customers 表筛选出 IsActive 标记为 1 的记录。
  • 视图提供了对数据的一种逻辑抽象,简化查询复杂度,隐藏底层细节。

b. 修改视图

ALTER VIEW ActiveCustomers
AS
SELECT CustomerID, Name, Email, LastPurchaseDate
FROM Customers
WHERE IsActive = 1 AND LastPurchaseDate >= DATEADD(year, -1, GETDATE());

讲解:

  • ALTER VIEW 语句用于更改现有视图的定义。
  • 更新后的 ActiveCustomers 视图除了包含原有列外,还加入了 LastPurchaseDate 列,并增加了只显示过去一年内有购买记录的活跃客户的条件。

c. 删除视图

DROP VIEW ActiveCustomers;

讲解:

  • DROP VIEW 命令用于删除名为 ActiveCustomers 的视图。

3. 存储过程管理

a. 创建存储过程

CREATE PROCEDURE GetCustomerOrders
    @CustomerID int
AS
BEGIN
    SELECT o.OrderID, o.OrderDate, o.TotalAmount
    FROM Orders o
    JOIN Customers c ON o.CustomerID = c.CustomerID
    WHERE c.CustomerID = @CustomerID;
END;

讲解:

  • CREATE PROCEDURE 语句创建了一个名为 GetCustomerOrders 的存储过程。
  • 存储过程封装了特定的SQL语句序列,接受参数(如 @CustomerID),并返回指定客户的所有订单信息。

b. 修改存储过程

ALTER PROCEDURE GetCustomerOrders
    @CustomerID int,
    @StartDate datetime,
    @EndDate datetime
AS
BEGIN
    SELECT o.OrderID, o.OrderDate, o.TotalAmount
    FROM Orders o
    JOIN Customers c ON o.CustomerID = c.CustomerID
    WHERE c.CustomerID = @CustomerID
      AND o.OrderDate BETWEEN @StartDate AND @EndDate;
END;

讲解:

  • ALTER PROCEDURE 语句用于修改已存在的存储过程。
  • 更新后的 GetCustomerOrders 存储过程新增了 @StartDate 和 @EndDate 参数,允许根据指定日期范围筛选订单。

c. 删除存储过程

DROP PROCEDURE GetCustomerOrders;

 讲解:

  • DROP PROCEDURE 命令用于删除名为 GetCustomerOrders 的存储过程。

4. 函数管理

a. 创建标量函数

CREATE FUNCTION GetCustomerCountByCity (@City varchar(50))
RETURNS int
AS
BEGIN
    RETURN (SELECT COUNT(*) FROM Customers WHERE City = @City);
END;

讲解:

  • CREATE FUNCTION 语句创建了一个名为 GetCustomerCountByCity 的标量函数。
  • 函数接收一个城市名参数 @City,返回该城市客户数量。
  • 标量函数返回单一值(这里是整数类型)。

b. 修改函数

ALTER FUNCTION GetCustomerCountByCity (@City varchar(50))
RETURNS int
AS
BEGIN
    RETURN (SELECT COUNT(*) FROM Customers WHERE City = @City AND IsActive = 1);
END;

讲解:

  • ALTER FUNCTION 语句用于更改现有函数的定义。
  • 更新后的函数在计算客户数量时,额外过滤了只统计 IsActive 为 1 的活跃客户。

c. 删除函数

DROP FUNCTION GetCustomerCountByCity;

讲解:

  • DROP FUNCTION 命令用于删除名为 GetCustomerCountByCity 的函数。

5. 触发器管理

a. 创建触发器

CREATE TRIGGER trg_AuditCustomerUpdate
ON Customers
AFTER UPDATE
AS
BEGIN
    INSERT INTO CustomerAuditLog (CustomerID, OldValue, NewValue, ChangedOn)
    SELECT d.CustomerID, c.Name, i.Name, GETDATE()
    FROM deleted d
    JOIN inserted i ON d.CustomerID = i.CustomerID
    JOIN Customers c ON d.CustomerID = c.CustomerID;
END;

讲解:

  • CREATE TRIGGER 语句创建了一个名为 trg_AuditCustomerUpdate 的触发器。
  • 该触发器在 Customers 表发生 UPDATE 操作后触发,将更新前后的客户名称记录到 CustomerAuditLog 表中,用于审计跟踪。

b. 修改触发器

ALTER TRIGGER trg_AuditCustomerUpdate
ON Customers
AFTER UPDATE
AS
BEGIN
    -- 新的触发器逻辑
END;

讲解:

  • ALTER TRIGGER 语句用于更改现有触发器的定义。
  • 实际修改触发器的逻辑需替换 -- 新的触发器逻辑 部分。

c. 删除触发器

DROP TRIGGER trg_AuditCustomerUpdate;

讲解:

  • DROP TRIGGER 命令用于删除名为 trg_AuditCustomerUpdate 的触发器。

6. 索引管理

a. 创建索引 

CREATE NONCLUSTERED INDEX IX_Customers_Name_Email
ON Customers (Name, Email);

讲解:

  • CREATE INDEX 语句创建了一个名为 IX_Customers_Name_Email 的非聚集索引。
  • 索引基于 Customers 表的 Name 和 Email 列构建,有助于加速相关查询。

b. 修改索引(例如重建或重新组织)

ALTER INDEX IX_Customers_Name_Email
ON Customers
REBUILD;

ALTER INDEX IX_Customers_Name_Email
ON Customers
REORGANIZE;

讲解:

  • ALTER INDEX 语句用于更改现有索引的状态。
  • REBUILD 操作会重新构建索引,释放空间并优化数据分布,适合在索引碎片严重或数据大量变更后使用。
  • REORGANIZE 操作对索引进行在线整理,减少碎片,但相比重建操作更为轻量级。

c. 删除索引

DROP INDEX IX_Customers_Name_Email
ON Customers;

 讲解:

  • DROP INDEX 命令用于删除名为 IX_Customers_Name_Email 的索引。


四、查询优化与性能调优

SQL Server的查询优化与性能调优是确保数据库系统高效响应查询请求、降低响应时间、减少资源消耗的关键工作。以下是一些SQL Server查询优化与性能调优的代码示例及详细讲解:

1. 查询优化

a. 简洁高效的查询语句

示例代码:

-- 不佳查询
SELECT *
FROM Customers
WHERE City = 'New York'
ORDER BY Name;

-- 优化查询
SELECT CustomerID, Name, Email
FROM Customers
WHERE City = 'New York'
ORDER BY Name;

 讲解:

  • 避免使用 SELECT *,明确列出所需列名可减少网络传输的数据量,提升查询效率。
  • 对于大数据量表,仅选择必要的列能显著降低查询成本。

b. 使用有效连接条件

示例代码:

-- 不佳查询(嵌套循环)
SELECT o.OrderID, c.Name
FROM Orders o, Customers c
WHERE o.CustomerID = c.CustomerID;

-- 优化查询(使用显式JOIN)
SELECT o.OrderID, c.Name
FROM Orders o
INNER JOIN Customers c ON o.CustomerID = c.CustomerID;

讲解:

  • 显式使用 JOIN 语句明确表间关联关系,便于阅读和维护。
  • SQL Server优化器更倾向于为显式JOIN生成高效的执行计划。

c. 避免全表扫描

示例代码:

-- 不佳查询(可能导致全表扫描)
SELECT * FROM Customers WHERE IsActive IS NOT NULL;

-- 优化查询(添加索引来支持快速查找)
CREATE INDEX IX_Customers_IsActive ON Customers (IsActive);
SELECT * FROM Customers WHERE IsActive = 1;

讲解:

  • 为经常用于过滤条件的列创建索引(如 IsActive),可避免全表扫描,提高查询速度。
  • 使用具有索引的列进行精确查询(如 IsActive = 1),而非模糊条件(如 IS NOT NULL)。

2. 性能调优

a. 使用执行计划分析

示例代码:

-- 获取查询的执行计划
SET SHOWPLAN_ALL ON;
GO

SELECT * FROM Customers WHERE City = 'New York';
GO

SET SHOWPLAN_ALL OFF;
GO

讲解:

  • SET SHOWPLAN_ALL ON 启用执行计划输出,代替实际查询结果。
  • 分析执行计划以识别潜在性能瓶颈,如全表扫描、排序、临时表等。

b. 优化索引

示例代码:

-- 创建复合索引
CREATE INDEX IX_Customers_City_Name ON Customers (City, Name);

-- 根据查询需求调整索引列顺序
CREATE INDEX IX_Customers_Name_City ON Customers (Name, City);

讲解:

  • 为常用于联合查询条件的列创建复合索引,如 City 和 Name。
  • 根据实际查询模式调整索引列顺序,使查询能够充分利用索引覆盖或索引跳跃扫描。

c. 使用统计信息

示例代码:

-- 更新特定表的统计信息
UPDATE STATISTICS Customers;

-- 自动更新统计信息
ALTER DATABASE CURRENT
SET AUTO_UPDATE_STATISTICS ON;

讲解:

  • 统计信息有助于优化器做出更准确的成本估算,生成高效执行计划。
  • 手动更新特定表(如 Customers)的统计信息,或设置数据库选项 AUTO_UPDATE_STATISTICS 为 ON,让系统自动定期更新统计信息。

d. 避免不必要的排序

示例代码:

-- 不佳查询(可能导致额外排序)
SELECT TOP 10 * FROM Customers ORDER BY Name DESC;

-- 优化查询(使用窗口函数避免排序)
SELECT TOP 10 *, ROW_NUMBER() OVER (ORDER BY Name DESC) AS RowNum
FROM Customers
WHERE RowNum <= 10;

讲解:

  • 使用窗口函数(如 ROW_NUMBER())结合 TOP 子句,在不进行全表排序的情况下获取前N条记录。
  • 避免在大数据量查询中进行不必要的全表排序,降低资源消耗。

e. 调整查询并发度

示例代码:

-- 设置查询的最大并行度
OPTION (MAXDOP 1);  -- 单线程执行
OPTION (MAXDOP 4);  -- 最多使用4个CPU核心

讲解:

  • 在查询末尾添加 OPTION (MAXDOP) 子句,控制查询的最大并行度。
  • 根据服务器资源状况和查询特性调整 MAXDOP 值,平衡并发执行带来的资源竞争与并行加速效果。

f. 分区表与并行查询

示例代码:

-- 创建分区函数与分区方案
CREATE PARTITION FUNCTION pf_orders_by_date (datetime)
AS RANGE RIGHT FOR VALUES ('2022-01-01', '2023-01-01');
CREATE PARTITION SCHEME ps_orders_by_date
AS PARTITION pf_orders_by_date ALL TO ([PRIMARY]);

-- 将表分区
ALTER TABLE Orders
ADD CONSTRAINT PK_PartitionedOrders PRIMARY KEY (OrderID) ON ps_orders_by_date(OrderDate);

-- 并行查询
SELECT * FROM Orders
WITH (NOLOCK, MAXDOP 4)
WHERE OrderDate BETWEEN '2022-08-01' AND '2022-08-31';

讲解:

  • 创建分区函数与分区方案,将大表(如 Orders)按时间范围划分为多个较小部分。
  • 使用分区表可以针对性地对数据子集进行查询、维护,提高处理效率。
  • 结合并行查询(如 MAXDOP 4),利用多核处理器优势进一步加速查询。


五、高可用与灾难恢复

SQL Server 提供了一系列高可用性和灾难恢复(HA/DR)解决方案,包括但不限于:数据库镜像、日志传送、备份与还原、Always On 可用性组(Availability Groups, AGs)、分布式事务协调器(DTC)等。下面重点介绍 Always On 可用性组,这是 SQL Server 中一种先进的 HA/DR 技术,提供几乎实时的数据复制和故障切换功能。

1. Always On 可用性组(Availability Groups)

a. 创建可用性组

示例代码:

CREATE AVAILABILITY GROUP [MyAG]
WITH (AUTOMATED_BACKUP_PREFERENCE = SECONDARY,
      FAILURE_CONDITION_LEVEL = 3,
      HEALTH_CHECK_TIMEOUT = 30000)
FOR DATABASE MyDatabase
REPLICA ON
   'PrimaryServerInstance' WITH
      (
         ENDPOINT_URL = N'TCP://PrimaryServerInstance:5022',
         FAILOVER_MODE = AUTOMATIC,
         AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
         BACKUP_PRIORITY = 50,
         SECONDARY_ROLE(ALLOW_CONNECTIONS = NO)
      ),
   'SecondaryServerInstance' WITH
      (
         ENDPOINT_URL = N'TCP://SecondaryServerInstance:5022',
         FAILOVER_MODE = AUTOMATIC,
         AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
         BACKUP_PRIORITY = 50,
         SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY)
      );
GO

讲解:

  • CREATE AVAILABILITY GROUP 语句创建一个名为 MyAG 的可用性组。
  • 指定 AUTOMATED_BACKUP_PREFERENCE、FAILURE_CONDITION_LEVEL 和 HEALTH_CHECK_TIMEOUT 等组级别设置。
  • FOR DATABASE MyDatabase 指定参与可用性组的数据库。
  • 在 REPLICA ON 子句中,定义主副本(PrimaryServerInstance)和辅助副本(SecondaryServerInstance)的配置,包括:
    • ENDPOINT_URL:指定数据库镜像端点地址。
    • FAILOVER_MODE:设置故障转移模式(自动或手动)。
    • AVAILABILITY_MODE:选择同步提交或异步提交复制模式。
    • BACKUP_PRIORITY:设定备份优先级。
    • SECONDARY_ROLE:定义辅助副本在故障转移后允许的连接模式(无连接或只读)。

b. 添加数据库到可用性组

示例代码:

ALTER DATABASE MyDatabase SET HADR AVAILABILITY GROUP = [MyAG];

讲解:

  • ALTER DATABASE 语句将数据库 MyDatabase 添加到已创建的可用性组 MyAG。

c. 监控可用性组状态

示例代码:

SELECT ag.name AS AGName,
       ar.replica_server_name,
       drs.database_name,
       drs.group_id,
       drs.replica_id,
       drs.synchronization_state_desc,
       drs.is_local
FROM sys.availability_groups AS ag
JOIN sys.dm_hadr_availability_replica_states AS ar
ON ag.group_id = ar.group_id
JOIN sys.dm_hadr_database_replica_states AS drs
ON ar.replica_id = drs.replica_id
AND ar.group_id = drs.group_id;

讲解:

  • 查询 sys.availability_groups、sys.dm_hadr_availability_replica_states 和 sys.dm_hadr_database_replica_states DMV,获取可用性组、副本服务器及数据库复制状态信息。

d. 故障转移操作

示例代码:

-- 手动故障转移
ALTER AVAILABILITY GROUP [MyAG] FAILOVER;

-- 强制故障转移(仅在紧急情况下使用,可能造成数据丢失)
ALTER AVAILABILITY GROUP [MyAG] FORCE_FAILOVER_ALLOW_DATA_LOSS;

讲解:

  • 使用 ALTER AVAILABILITY GROUP 语句执行手动故障转移或强制故障转移。
  • 手动故障转移适用于正常情况下的主备切换,保持数据一致性。
  • 强制故障转移在主副本不可用且无法通过常规方法转移时使用,可能会导致数据丢失。

2. 备份与还原

a. 完整数据库备份

示例代码:

BACKUP DATABASE MyDatabase
TO DISK = N'C:\Backups\MyDatabase_FULL.bak'
WITH COMPRESSION, STATS = 10;

讲解:

  • 使用 BACKUP DATABASE 语句对 MyDatabase 进行完整备份。
  • 指定备份文件路径和文件名。
  • 使用 COMPRESSION 选项压缩备份文件,减少存储空间占用。
  • STATS = 10 显示每完成10%备份进度的统计信息。

b. 差异备份

示例代码:

BACKUP DATABASE MyDatabase
TO DISK = N'C:\Backups\MyDatabase_DIFF.bak'
WITH DIFFERENTIAL, STATS = 10;

讲解:

  • 使用 BACKUP DATABASE 语句对 MyDatabase 进行差异备份。
  • 差异备份仅捕获自上次完整备份以来变化的数据,减少备份时间和存储空间。

c. 文件组备份

示例代码:

BACKUP DATABASE MyDatabase FILEGROUP = 'MyFilegroup'
TO DISK = N'C:\Backups\MyDatabase_FILEGROUP.bak'
WITH COMPRESSION, STATS = 10;

讲解:

  • 对特定文件组(如 MyFilegroup)进行备份,适用于分区分区的数据库。

d. 数据库还原

示例代码:

RESTORE DATABASE MyDatabase
FROM DISK = N'C:\Backups\MyDatabase_FULL.bak'
WITH RECOVERY, REPLACE;

讲解:

  • 使用 RESTORE DATABASE 语句从备份文件恢复 MyDatabase。
  • RECOVERY 选项指明恢复数据库至一致状态并结束还原过程。
  • REPLACE 选项允许覆盖现有同名数据库。

3. 日志传送(Log Shipping)
尽管 Always On 可用性组已成为首选的 HA/DR 解决方案,但日志传送仍可用于某些场景。日志传送涉及以下几个步骤:

  • 主服务器:定期执行数据库日志备份。
  • 辅助服务器:定期从主服务器复制日志备份文件,并应用到辅助数据库。
  • 监控服务器(可选):监控日志传送作业状态。

创建日志传送通常涉及以下操作(代码略,需使用 SQL Server Management Studio 或 T-SQL 脚本):

  • 主服务器:
    • 配置数据库备份作业,定期备份事务日志。
    • 设置备份文件的目标位置,以便辅助服务器访问。
  • 辅助服务器:
    • 创建辅助数据库(通常是主数据库的一个初始备份恢复)。
    • 配置文件复制作业,将主服务器的日志备份文件复制到辅助服务器。
    • 配置日志还原作业,定期应用复制到辅助服务器的日志备份。
  • (可选)监控服务器:
    • 配置日志传送监视器,监控主服务器、辅助服务器和文件复制作业的状态。


六、安全管理

SQL Server 的安全管理涉及对数据库用户的访问控制、权限分配、登录账户管理等多个方面,以确保数据的机密性、完整性以及系统的可用性。以下是一些 SQL Server 安全管理相关的代码示例及详细讲解:

1. 登录账户管理

a. 创建登录账户

示例代码:

CREATE LOGIN [JohnDoe] WITH PASSWORD = 'p@ssw0rd!', DEFAULT_DATABASE = [AdventureWorks], CHECK_POLICY = ON;

讲解:

  • 使用 CREATE LOGIN 语句创建名为 JohnDoe 的登录账户。
  • 指定账户密码为 'p@ssw0rd!',遵循密码策略。
  • 设置默认连接的数据库为 [AdventureWorks]。
  • 启用密码策略检查(CHECK_POLICY = ON),确保密码符合复杂度要求。

b. 修改登录账户属性

示例代码:

ALTER LOGIN [JohnDoe] WITH PASSWORD = 'newP@ssw0rd!', DEFAULT_DATABASE = [WideWorldImporters];

讲解:

  • 使用 ALTER LOGIN 语句更新 JohnDoe 登录账户的属性。
  • 更改密码为 'newP@ssw0rd!'。
  • 改变默认连接的数据库为 [WideWorldImporters]。

c. 删除登录账户

示例代码:

DROP LOGIN [JohnDoe];

讲解:

  • 使用 DROP LOGIN 语句删除名为 JohnDoe 的登录账户。

d. 禁用或启用登录账户

示例代码:

ALTER LOGIN [JohnDoe] DISABLE;
ALTER LOGIN [JohnDoe] ENABLE;

讲解:

  • 使用 ALTER LOGIN 语句配合 DISABLE 或 ENABLE 选项,分别禁用或启用 JohnDoe 登录账户。

2. 数据库用户管理

a. 创建数据库用户

示例代码:

USE AdventureWorks;
CREATE USER [JohnDoe] FOR LOGIN [JohnDoe];

讲解:

  • 首先切换到目标数据库(这里为 AdventureWorks)。
  • 使用 CREATE USER 语句为已存在的登录账户 JohnDoe 创建对应的数据库用户。

b. 修改数据库用户属性

示例代码:

ALTER USER [JohnDoe] WITH DEFAULT_SCHEMA = [Sales];

讲解:

  • 使用 ALTER USER 语句更新 JohnDoe 数据库用户的属性。
  • 设置其默认架构为 [Sales],影响未指定架构的对象引用。

c. 删除数据库用户

示例代码:

USE AdventureWorks;
DROP USER [JohnDoe];

讲解:

  • 切换到目标数据库。
  • 使用 DROP USER 语句删除名为 JohnDoe 的数据库用户。

3. 权限管理

a. 授予权限

示例代码:

GRANT SELECT ON OBJECT::[dbo].[Customers] TO [JohnDoe];
GRANT EXECUTE ON [dbo].[usp_GetOrders] TO [JohnDoe];

讲解:

  • 使用 GRANT 语句为 JohnDoe 用户授予权限。
  • 第一条语句授予对 [dbo].[Customers] 表的 SELECT 权限。
  • 第二条语句授予对存储过程 [dbo].[usp_GetOrders] 的 EXECUTE 权限。

b. 撤销权限

示例代码:

REVOKE SELECT ON OBJECT::[dbo].[Customers] FROM [JohnDoe];
REVOKE EXECUTE ON [dbo].[usp_GetOrders] FROM [JohnDoe];

讲解:

  • 使用 REVOKE 语句撤销 JohnDoe 用户的特定权限。
  • 第一条语句撤销对 [dbo].[Customers] 表的 SELECT 权限。
  • 第二条语句撤销对存储过程 [dbo].[usp_GetOrders] 的 EXECUTE 权限。

c. 查看权限

示例代码:

SELECT 
    pr.principal_id, pr.name AS UserName, 
    p.class_desc, p.permission_name, 
    p.state_desc, OBJECT_NAME(p.major_id) AS ObjectName
FROM 
    sys.database_principals pr
JOIN 
    sys.database_permissions p ON pr.principal_id = p.grantee_principal_id
WHERE 
    pr.name = N'JohnDoe';

讲解:

  • 查询 sys.database_principals 和 sys.database_permissions 系统视图,获取 JohnDoe 用户在当前数据库中的所有权限信息。
  • 显示用户名、权限类型(如对象类、权限名称)、权限状态(如是否授予或拒绝)以及受影响的对象名。

4. 角色管理

a. 创建数据库角色

示例代码:

CREATE ROLE [MarketingUsers];

讲解:

  • 使用 CREATE ROLE 语句创建名为 MarketingUsers 的数据库角色。

b. 将用户添加到角色

示例代码:

ALTER ROLE [MarketingUsers] ADD MEMBER [JohnDoe];

讲解:

  • 使用 ALTER ROLE 语句将 JohnDoe 用户添加到 MarketingUsers 角色。

c. 授予角色权限

示例代码:

GRANT SELECT ON SCHEMA :: [Sales] TO [MarketingUsers];

讲解:

  • 使用 GRANT 语句为 MarketingUsers 角色授予权限。
  • 本例中,角色成员获得了对 Sales 架构下所有对象的 SELECT 权限。

d. 从角色中移除用户

示例代码:

ALTER ROLE [MarketingUsers] DROP MEMBER [JohnDoe];

讲解:

  • 使用 ALTER ROLE 语句将 JohnDoe 用户从 MarketingUsers 角色中移除。

5. 审计与安全性审核

示例代码:

CREATE SERVER AUDIT [Audit trail]
TO FILE (FILEPATH = 'C:\SQLAudit\audit.trl', MAXSIZE = 100 MB, MAX_ROLLOVER_FILES = 5, RESERVE_DISK_SPACE = OFF)
WITH (QUEUE_DELAY = 1000 MS, ON_FAILURE = CONTINUE);

ALTER SERVER AUDIT [Audit trail] WITH (STATE = ON);

CREATE DATABASE AUDIT SPECIFICATION [Database Audit Spec]
FOR SERVER AUDIT [Audit trail]
ADD (SELECT ON OBJECT::[dbo].[SensitiveData] BY [public]),
ADD (INSERT ON OBJECT::[dbo].[SensitiveData] BY [public]),
ADD (UPDATE ON OBJECT::[dbo].[SensitiveData] BY [public])
WITH (STATE = ON);

讲解:

  • 使用 CREATE SERVER AUDIT 语句创建名为 Audit trail 的服务器审计,将审计记录写入指定文件,设置审计文件大小、滚动策略等参数。
  • 使用 ALTER SERVER AUDIT 语句启动审计。
  • 使用 CREATE DATABASE AUDIT SPECIFICATION 语句为当前数据库创建审计规范,关联到上述服务器审计,指定要审计的操作(如 SELECT, INSERT, UPDATE)和对象(如 [dbo].[SensitiveData]),以及执行这些操作的角色或用户(如 [public])。
  • 最后启用审计规范。


七、SQL Server 特性与高级功能

SQL Server 提供了许多高级特性和功能,以下列举其中一些关键特性,并给出相应的代码示例和详细讲解:

1. 内存优化表(In-Memory OLTP)
内存优化表将数据存储在内存中,大幅降低数据访问延迟,提高事务处理速度,特别适用于高并发、低延迟的OLTP工作负载。

示例代码:

CREATE DATABASE InMemoryDB;
GO

USE InMemoryDB;
GO

-- 创建内存优化文件组
ALTER DATABASE InMemoryDB
ADD FILEGROUP InMemoryFG
CONTAINS MEMORY_OPTIMIZED_DATA;

-- 添加文件到内存优化文件组
ALTER DATABASE InMemoryDB
ADD FILE (
    NAME = 'InMemoryData',
    FILENAME = 'C:\Data\InMemoryData.ndf'
)
TO FILEGROUP InMemoryFG;

-- 创建内存优化表
CREATE TABLE dbo.MemoryOptimizedTable
(
    ID int IDENTITY PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 10000),
    Data nvarchar(500) NOT NULL
) WITH (MEMORY_OPTIMIZED = ON);

讲解:

  • 创建一个名为 InMemoryDB 的数据库。
  • 为数据库添加一个内存优化文件组 InMemoryFG,用于存储内存优化表的数据。
  • 将物理文件 InMemoryData.ndf 添加到 InMemoryFG 文件组。
  • 使用 CREATE TABLE 语句创建内存优化表 dbo.MemoryOptimizedTable,并指定主键为非聚集哈希索引(HASH WITH BUCKET_COUNT),以及 MEMORY_OPTIMIZED = ON 表明该表为内存优化表。

2. 列存储索引(Columnstore Indexes)

  • 列存储索引将数据按列存储,极大地提高了大数据量分析查询的性能。

示例代码:

CREATE TABLE SalesData
(
    SaleID int,
    ProductID int,
    Quantity int,
    SaleDate datetime
);

-- 创建非聚集列存储索引
CREATE NONCLUSTERED COLUMNSTORE INDEX CSIX_SalesData
ON SalesData (SaleID, ProductID, Quantity, SaleDate);

讲解:

  • 创建一个名为 SalesData 的表,包含销售数据的字段。
  • 使用 CREATE NONCLUSTERED COLUMNSTORE INDEX 语句创建一个非聚集列存储索引 CSIX_SalesData,涵盖表中的所有列。列存储索引将大大提高针对这些列的大规模聚合查询和数据分析的性能。

3. 延迟更新统计信息(Delayed Durability)
延迟更新统计信息可以降低事务提交的开销,提高写入性能,但可能增加数据恢复期间的数据丢失风险。

示例代码:

BEGIN TRANSACTION;
INSERT INTO SomeTable (Col1, Col2) VALUES ('Value1', 'Value2');
COMMIT TRANSACTION WITH (DELAYED_DURABILITY = ON);

讲解:

  • 开始一个事务。
  • 插入数据到 SomeTable。
  • 使用 COMMIT TRANSACTION WITH (DELAYED_DURABILITY = ON) 提交事务,并指定延迟持久性。这样,事务的提交开销会降低,但直到数据被写入磁盘之前,存在一定的数据丢失风险。

4. 查询存储(Query Store)
查询存储记录查询执行计划、性能指标和资源使用情况,帮助诊断和优化查询性能。

示例代码:

-- 启用查询存储
ALTER DATABASE YourDatabase
SET QUERY_STORE = ON
WITH (OPERATION_MODE = READ_WRITE, INTERVAL_LENGTH_MINUTES = 60, SIZE_BASED_CLEANUP_MODE = AUTO);

-- 查询查询存储信息
SELECT 
    q.query_id, 
    qt.query_sql_text, 
    qs.total_execution_count, 
    qs.avg_duration, 
    qs.last_execution_time
FROM 
    sys.query_store_query AS q
JOIN 
    sys.query_store_query_text AS qt ON q.query_text_id = qt.query_text_id
JOIN 
    sys.query_store_runtime_stats AS rs ON q.query_id = rs.query_id
JOIN 
    sys.query_store_runtime_stats_interval AS rsi ON rs.runtime_stats_interval_id = rsi.runtime_stats_interval_id
WHERE 
    rsi.start_time >= DATEADD(hour, -24, GETUTCDATE())
ORDER BY 
    qs.total_execution_count DESC;

讲解:

  • 使用 ALTER DATABASE 语句启用查询存储,指定操作模式为 READ_WRITE,收集间隔为每60分钟,启用基于大小的清理模式。
  • 查询 sys.query_store_query、sys.query_store_query_text、sys.query_store_runtime_stats 和 sys.query_store_runtime_stats_interval 系统视图,获取过去24小时内执行次数最多的查询及其文本、总执行次数、平均执行时间、最近一次执行时间等信息。

5. 透明数据加密(Transparent Data Encryption, TDE)
TDE对数据库、相关备份和日志文件进行加密,保护静态数据的安全。

示例代码:

-- 创建证书
CREATE CERTIFICATE TDE_Certificate
WITH SUBJECT = 'TDE Certificate';

-- 创建数据库加密密钥
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_128
ENCRYPTION BY SERVER CERTIFICATE TDE_Certificate;

-- 启用数据库加密
ALTER DATABASE YourDatabase
SET ENCRYPTION ON;

讲解:

  • 使用 CREATE CERTIFICATE 语句创建一个名为 TDE_Certificate 的证书,用于加密数据库加密密钥。
  • 使用 CREATE DATABASE ENCRYPTION KEY 语句创建数据库加密密钥,指定使用AES-128算法,并使用上述证书进行加密。
  • 使用 ALTER DATABASE 语句启用数据库 YourDatabase 的透明数据加密,所有数据、备份和日志文件将被加密保护。

6. Stretch Database
Stretch Database 将冷数据透明地迁移到 Azure SQL Database,实现本地与云端的混合存储,降低本地存储成本,同时保留对所有数据的查询访问能力。

示例代码:

-- 启用 Stretch Database 功能
USE YourDatabase;
GO
ALTER DATABASE YourDatabase
SET REMOTE_DATA_ARCHIVE = ON
(
    SERVER = 'yourazureserver.database.windows.net',
    CREDENTIAL = YourAzureCredential,
    DATABASE_NAME = 'YourAzureDatabase'
);

-- 对表启用 Stretch Database
USE YourDatabase;
GO
ALTER TABLE YourLargeTable
SET (REMOTE_DATA_ARCHIVE = ON (MIGRATION_STATE = OUTBOUND));

讲解:

  • 使用 ALTER DATABASE 语句启用数据库 YourDatabase 的 Stretch Database 功能,指定 Azure SQL Server 地址、凭据和目标数据库名。
  • 对表 YourLargeTable 使用 ALTER TABLE 语句启用 Stretch Database,设置迁移状态为 OUTBOUND,开始将冷数据迁移到 Azure。


八、云环境下的SQL Server

在云环境下,SQL Server 的部署和管理通常依托于云服务提供商(如 Microsoft Azure、Amazon Web Services 等)提供的托管服务。虽然具体的代码示例会因云平台而异,但通常涉及以下几个方面:

1. 创建与管理云上 SQL Server 实例
云平台上通常提供图形化界面或API来创建、配置和管理SQL Server实例。以下是一个基于Azure CLI创建SQL Server实例的示例

# 使用Azure CLI登录
az login

# 创建资源组
az group create --name myResourceGroup --location eastus

# 创建SQL Server实例
az sql server create \
  --name mySqlServer \
  --resource-group myResourceGroup \
  --admin-user myAdminUser \
  --admin-password myAdminPassword \
  --version 12.0

# 查看SQL Server实例信息
az sql server show --name mySqlServer --resource-group myResourceGroup

讲解:

  • 使用 az login 命令登录Azure帐户。
  • 使用 az group create 创建一个资源组,用于组织相关资源。
  • 使用 az sql server create 创建SQL Server实例,指定实例名、资源组、管理员用户名、密码以及SQL Server版本。
  • 使用 az sql server show 查看创建的SQL Server实例详细信息。

2. 配置网络与防火墙规则
云环境下的SQL Server实例通常需要通过虚拟网络和网络安全组进行访问控制。

# 创建虚拟网络
az network vnet create \
  --resource-group myResourceGroup \
  --name myVnet \
  --address-prefixes 10.0.0.0/16

# 创建子网
az network vnet subnet create \
  --resource-group myResourceGroup \
  --vnet-name myVnet \
  --name mySubnet \
  --address-prefix 10.0.1.0/24

# 将子网关联到SQL Server实例
az sql server vnet-rule create \
  --resource-group myResourceGroup \
  --server mySqlServer \
  --name myVnetRule \
  --subnet mySubnet \
  --vnet-name myVnet

# 创建网络安全组并添加允许SQL端口的入站规则
az network nsg create \
  --resource-group myResourceGroup \
  --name mySqlNSG

az network nsg rule create \
  --resource-group myResourceGroup \
  --nsg-name mySqlNSG \
  --name AllowSqlPort \
  --priority 1000 \
  --direction Inbound \
  --protocol Tcp \
  --source-address-prefixes '*' \
  --source-port-ranges '*' \
  --destination-address-prefixes '*' \
  --destination-port-ranges 1433 \
  --access Allow

讲解:

  • 使用 az network vnet create 和 az network vnet subnet create 创建虚拟网络和子网。
  • 使用 az sql server vnet-rule create 将子网与SQL Server实例关联,实现私有网络访问。
  • 使用 az network nsg create 创建网络安全组。
  • 使用 az network nsg rule create 添加允许TCP 1433端口(SQL Server默认端口)入站访问的规则,确保外部客户端能够连接到SQL Server实例。

3. 创建与管理数据库
在云环境中,可以通过云服务提供的接口创建和管理SQL Server数据库。

# 在云SQL Server实例上创建数据库
az sql db create \
  --resource-group myResourceGroup \
  --server mySqlServer \
  --name myDatabase \
  --edition GeneralPurpose \
  --compute-model Serverless \
  --capacity 2 \
  --max-size 10GB \
  --sample-name AdventureWorksLT

# 查看数据库信息
az sql db show --resource-group myResourceGroup --server mySqlServer --name myDatabase

讲解:

  • 使用 az sql db create 创建一个名为 myDatabase 的数据库,指定实例名、资源组、数据库版型(如GeneralPurpose)、计算模型(如Serverless)、初始容量、最大尺寸以及选择预填充示例数据(如AdventureWorksLT)。
  • 使用 az sql db show 查看创建的数据库详细信息。

4. 备份与恢复
云服务通常提供自动备份和点-in-time恢复功能。恢复操作可通过云平台提供的控制台或API完成。

# 查看SQL Server实例的自动备份配置
az sql db show-backup-policy \
  --resource-group myResourceGroup \
  --server mySqlServer \
  --database myDatabase

# 执行手动备份
az sql db backup \
  --resource-group myResourceGroup \
  --server mySqlServer \
  --database myDatabase \
  --backup-type Full

# 执行时间点恢复
az sql db restore \
  --resource-group myResourceGroup \
  --server mySqlServer \
  --name restoredDatabase \
  --target-server myTargetServer \
  --target-resource-group myTargetResourceGroup \
  --restore-point-in-time "2024-04-10T14:30:00Z"

讲解:

  • 使用 az sql db show-backup-policy 查看数据库的自动备份配置。
  • 使用 az sql db backup 手动执行一次完整备份。
  • 使用 az sql db restore 将数据库恢复到指定的时间点(例如 "2024-04-10T14:30:00Z"),并指定恢复后的数据库名、目标SQL Server实例及资源组。

结语

SQL Server技术学习是一场融合理论与实践、涵盖多个技术领域的深度探索。从基础SQL语言到高级特性应用,从本地部署到云端管理,每一个环节都蕴含着提升数据库系统效能与可靠性的关键知识。通过系统性地学习与实践,数据库工程师和开发者能够从容应对复杂业务场景,为企业的数据资产保驾护航。在不断发展的技术浪潮中,持续关注SQL Server的最新版本更新与最佳实践,将使您的技术栈始终保持与时俱进,助力企业在数字化转型中立于不败之地。

  • 45
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码快撩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值