SQL Server 2019入门学习教程,从入门到精通,SQL Server 2019 新增功能 — 语法知识点及使用方法详解(20)

SQL Server 2019 新增功能 --- 语法知识点及使用方法详解


📅 当前环境 :SQL Server 2019 (15.x) 或兼容版本

📌 适用对象:数据库管理员、开发人员、数据工程师、架构师


一、数据虚拟化与大数据群集(Big Data Clusters, BDC)

SQL Server 2019 引入大数据群集,允许通过 T-SQL 查询 HDFS、Spark、外部关系数据库等异构数据源,实现"数据虚拟化"。

核心组件:

  • PolyBase:增强版,支持更多数据源(Oracle, Teradata, MongoDB, ODBC 等)。
  • 外部表(External Tables):映射外部数据源的虚拟表。
  • 数据池(Data Pool):缓存外部数据,提升性能。
  • 存储池(Storage Pool):HDFS 存储层。

1.1 配置 PolyBase(启用)

sql 复制代码
-- 启用 PolyBase 功能(需重启服务)
EXEC sp_configure @configname = 'polybase enabled', @configvalue = 1;
RECONFIGURE;
GO

-- 验证是否启用
SELECT value_in_use FROM sys.configurations WHERE name = 'polybase enabled';
-- 返回 1 表示已启用

⚠️ 前提

  • SQL Server 2019 企业版或开发版。
  • 安装 PolyBase 组件(安装时勾选)。
  • 重启 SQL Server 服务。

1.2 创建外部数据源(以 Oracle 为例)

sql 复制代码
-- 1. 创建数据库作用域凭据(用于连接外部数据库)
CREATE DATABASE SCOPED CREDENTIAL OracleCredential
WITH IDENTITY = 'oracle_user', -- Oracle 用户名
     SECRET = 'oracle_password'; -- Oracle 密码
GO

-- 2. 创建外部数据源
CREATE EXTERNAL DATA SOURCE OracleDataSource
WITH (
    LOCATION = 'oracle://192.168.1.100:1521', -- Oracle 服务器地址
    CREDENTIAL = OracleCredential,
    PUSHDOWN = ON -- 允许下推计算到 Oracle
);
GO

-- 3. 创建外部表(映射 Oracle 表)
CREATE EXTERNAL TABLE dbo.ExternalCustomers (
    CustomerID INT,
    FirstName NVARCHAR(50),
    LastName NVARCHAR(50),
    Email NVARCHAR(100)
)
WITH (
    LOCATION = '[ORCL].[SALES].[CUSTOMERS]', -- Oracle 中的表名(数据库.模式.表)
    DATA_SOURCE = OracleDataSource
);
GO

-- 4. 查询外部表(透明查询)
SELECT TOP 10 * FROM dbo.ExternalCustomers;
-- ✅ 执行计划会下推 WHERE、JOIN 到 Oracle(如果支持)

💡 注释

  • PUSHDOWN = ON:允许 SQL Server 将过滤、聚合等操作推送到外部数据源执行,减少数据传输。
  • 外部表不存储数据,仅是元数据映射。
  • 支持的数据源:Oracle, Teradata, MongoDB, ODBC, HDFS, Spark 等。

1.3 查询 HDFS 数据(CSV 文件)

sql 复制代码
-- 1. 创建 HDFS 数据源凭据
CREATE DATABASE SCOPED CREDENTIAL HdfsCredential
WITH IDENTITY = 'HadoopUser', SECRET = 'hadoop_password';
GO

-- 2. 创建 HDFS 外部数据源
CREATE EXTERNAL DATA SOURCE HdfsDataSource
WITH (
    TYPE = HADOOP,
    LOCATION = 'hdfs://namenode:8020',
    CREDENTIAL = HdfsCredential
);
GO

-- 3. 创建外部文件格式(CSV)
CREATE EXTERNAL FILE FORMAT CsvFormat
WITH (
    FORMAT_TYPE = DELIMITEDTEXT,
    FORMAT_OPTIONS (
        FIELD_TERMINATOR = ',',
        STRING_DELIMITER = '"',
        FIRST_ROW = 2, -- 跳过标题行
        USE_TYPE_DEFAULT = TRUE
    )
);
GO

-- 4. 创建外部表映射 HDFS 文件
CREATE EXTERNAL TABLE dbo.HdfsSalesData (
    SaleID INT,
    ProductName NVARCHAR(100),
    Quantity INT,
    SaleDate DATE
)
WITH (
    LOCATION = '/data/sales/sales_2025.csv', -- HDFS 路径
    DATA_SOURCE = HdfsDataSource,
    FILE_FORMAT = CsvFormat
);
GO

-- 5. 查询 HDFS 数据
SELECT 
    ProductName,
    SUM(Quantity) AS TotalQuantity
FROM dbo.HdfsSalesData
WHERE SaleDate >= '2025-01-01'
GROUP BY ProductName
ORDER BY TotalQuantity DESC;
-- ✅ 可与本地表 JOIN!

🌟 优势

  • 无需 ETL,直接查询原始数据。
  • 支持结构化(Parquet, ORC)和非结构化(CSV, JSON)。
  • 可结合数据池缓存热数据提升性能。

二、智能数据库(Intelligent Database)

SQL Server 2019 引入多项"智能"查询优化功能,自动提升性能。


2.1 批处理模式内存授予反馈(Batch Mode Memory Grant Feedback)

自动调整批处理模式查询的内存授予,避免内存不足或浪费。

自动启用,无需语法,适用于批处理模式操作(如 Columnstore Index 查询)。

案例:观察内存授予反馈
sql 复制代码
-- 创建测试表(含列存储索引)
CREATE TABLE dbo.SalesData (
    SaleID INT IDENTITY(1,1),
    ProductID INT,
    Quantity INT,
    SaleAmount DECIMAL(10,2),
    SaleDate DATE
);
GO

-- 插入100万行测试数据
INSERT INTO dbo.SalesData (ProductID, Quantity, SaleAmount, SaleDate)
SELECT 
    ABS(CHECKSUM(NEWID())) % 1000,
    ABS(CHECKSUM(NEWID())) % 100,
    ABS(CHECKSUM(NEWID())) % 10000 / 100.0,
    DATEADD(DAY, ABS(CHECKSUM(NEWID())) % 365, '2024-01-01')
FROM sys.objects a, sys.objects b, sys.objects c
WHERE (SELECT COUNT(*) FROM sys.objects) < 1000000; -- 控制行数
GO

-- 创建聚集列存储索引(触发批处理模式)
CREATE CLUSTERED COLUMNSTORE INDEX CCI_SalesData ON dbo.SalesData;
GO

-- 执行查询(首次可能内存授予不足)
SELECT 
    ProductID,
    SUM(SaleAmount) AS TotalSales
FROM dbo.SalesData
WHERE SaleDate >= '2024-06-01'
GROUP BY ProductID
ORDER BY TotalSales DESC
OPTION (RECOMPILE); -- 强制重新编译,观察反馈
GO

-- 查看执行计划:
-- 1. 在 SSMS 中执行,查看"实际执行计划"
-- 2. 查找"聚集索引扫描"或"哈希匹配"操作符
-- 3. 检查"内存授予"和"警告"信息
-- 4. 如果首次授予不足,第二次执行会自动调整!

-- 查询 DMV 查看内存授予反馈历史
SELECT 
    qs.query_hash,
    qs.query_plan_hash,
    qs.last_grant_kb,
    qs.last_used_grant_kb,
    qs.last_ideal_grant_kb,
    qs.is_last_grant_feedback_adjusted -- 1=已调整
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE st.text LIKE '%SalesData%SaleDate%';
GO

💡 原理

  • 首次执行:根据统计信息预估内存。
  • 执行后:对比实际使用内存 vs 授予内存。
  • 下次执行:自动调整授予量(增大或减小)。
  • 适用于:哈希连接、排序、窗口函数等内存密集操作。

2.2 行模式内存授予反馈(Row Mode Memory Grant Feedback)

将内存授予反馈扩展到行模式查询(传统 B 树索引查询)。

自动启用,SQL Server 2019 CU8+ 默认开启。

案例:行模式内存反馈
sql 复制代码
-- 创建行存储表(B树索引)
CREATE TABLE dbo.CustomerOrders (
    OrderID INT IDENTITY(1,1) PRIMARY KEY,
    CustomerID INT NOT NULL,
    OrderDate DATE NOT NULL,
    TotalAmount DECIMAL(10,2)
);
GO

-- 创建索引
CREATE INDEX IX_CustomerOrders_CustomerID ON dbo.CustomerOrders(CustomerID);
CREATE INDEX IX_CustomerOrders_OrderDate ON dbo.CustomerOrders(OrderDate);
GO

-- 插入测试数据
INSERT INTO dbo.CustomerOrders (CustomerID, OrderDate, TotalAmount)
SELECT 
    ABS(CHECKSUM(NEWID())) % 50000,
    DATEADD(DAY, ABS(CHECKSUM(NEWID())) % 1000, '2023-01-01'),
    ABS(CHECKSUM(NEWID())) % 10000 / 100.0
FROM sys.objects a, sys.objects b;
GO

-- 执行行模式查询(涉及排序)
SELECT 
    CustomerID,
    COUNT(*) AS OrderCount,
    AVG(TotalAmount) AS AvgAmount
FROM dbo.CustomerOrders
WHERE OrderDate >= '2024-01-01'
GROUP BY CustomerID
HAVING COUNT(*) > 5
ORDER BY AvgAmount DESC
OPTION (RECOMPILE);
GO

-- 查看是否应用行模式反馈
SELECT 
    qs.query_hash,
    qs.is_row_mode_memory_grant_feedback_used -- 1=已使用行模式反馈
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE st.text LIKE '%CustomerOrders%OrderDate%';
GO

📌 注意

  • 行模式反馈在 SQL Server 2019 CU8+ 默认开启。
  • 适用于:ORDER BY, GROUP BY, DISTINCT, 窗口函数 等。
  • 减少 RESOURCE_SEMAPHORE 等待和内存溢出错误。

2.3 适用于 MSTVF 的交错执行(Interleaved Execution for MSTVF)

改进多语句表值函数(MSTVF)的基数估计,避免因错误估计导致性能问题。

自动启用,无需语法。

案例:MSTVF 交错执行
sql 复制代码
-- 创建多语句表值函数(MSTVF)
CREATE FUNCTION dbo.GetCustomerOrders(@CustomerID INT)
RETURNS @Orders TABLE (
    OrderID INT,
    OrderDate DATE,
    TotalAmount DECIMAL(10,2)
)
AS
BEGIN
    INSERT INTO @Orders
    SELECT OrderID, OrderDate, TotalAmount
    FROM dbo.CustomerOrders
    WHERE CustomerID = @CustomerID;
    RETURN;
END;
GO

-- 旧版本问题:MSTVF 始终估计返回 1 行,导致执行计划错误
-- SQL Server 2019:交错执行 --- 先执行函数获取实际行数,再优化外层查询

-- 查询使用 MSTVF
SELECT 
    c.CustomerID,
    o.OrderDate,
    o.TotalAmount
FROM dbo.Customers c
CROSS APPLY dbo.GetCustomerOrders(c.CustomerID) o -- 假设有 Customers 表
WHERE c.CustomerID BETWEEN 1 AND 100
ORDER BY o.OrderDate;

-- 查看执行计划:
-- 1. 在 SSMS 中执行,查看"实际执行计划"
-- 2. 查找"Table Valued Function"操作符
-- 3. 检查"估计行数" vs "实际行数" --- 应接近!
-- 4. 操作符属性中查看"IsInterleavedExecuted" = True

-- 查询 DMV 验证
SELECT 
    qs.query_hash,
    qs.is_interleaved_executed -- 1=已使用交错执行
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE st.text LIKE '%GetCustomerOrders%';
GO

💡 优势

  • 消除 MSTVF 的"1行估计"问题。
  • 生成更优的 JOIN 和索引策略。
  • 显著提升复杂查询性能。

2.4 表变量延迟编译(Table Variable Deferred Compilation)

改进表变量的基数估计,避免因估计为 1 行导致的性能问题。

自动启用,适用于数据库兼容级别 150(SQL Server 2019)。

案例:表变量延迟编译
sql 复制代码
-- 设置数据库兼容级别为 150(SQL Server 2019)
ALTER DATABASE YourDatabase SET COMPATIBILITY_LEVEL = 150;
GO

-- 创建测试存储过程
CREATE OR ALTER PROCEDURE dbo.TestTableVariable
AS
BEGIN
    -- 声明表变量
    DECLARE @TempOrders TABLE (
        OrderID INT,
        CustomerID INT,
        TotalAmount DECIMAL(10,2)
    );

    -- 插入大量数据
    INSERT INTO @TempOrders (OrderID, CustomerID, TotalAmount)
    SELECT TOP 10000 OrderID, CustomerID, TotalAmount
    FROM dbo.CustomerOrders
    ORDER BY OrderID;

    -- 使用表变量进行 JOIN(旧版估计1行,新版估计实际行数)
    SELECT 
        c.CustomerName,
        t.TotalAmount
    FROM @TempOrders t
    INNER JOIN dbo.Customers c ON t.CustomerID = c.CustomerID -- 假设有 Customers 表
    WHERE t.TotalAmount > 100
    ORDER BY t.TotalAmount DESC;
END;
GO

-- 执行存储过程
EXEC dbo.TestTableVariable;
GO

-- 查看执行计划:
-- 1. 在 SSMS 中执行,查看"实际执行计划"
-- 2. 查找"Table Variable"扫描操作符
-- 3. 检查"估计行数" --- 应接近 10000(而非1)
-- 4. 操作符属性中查看"CardinalityEstimationModelVersion" = 150

-- 对比:设置兼容级别为 140(SQL Server 2017)
ALTER DATABASE YourDatabase SET COMPATIBILITY_LEVEL = 140;
GO
EXEC dbo.TestTableVariable; -- 此时估计行数为1,性能差
GO

📌 关键点

  • 仅在兼容级别 150 下生效。
  • 编译时根据表变量实际数据量估算行数。
  • 解决表变量导致的性能瓶颈。

三、新增近似查询功能(Approximate Query Processing)

用于大数据场景,牺牲少量精度换取查询速度提升。

3.1 APPROX_COUNT_DISTINCT()

近似计算唯一值数量,比 COUNT(DISTINCT) 快 10-100 倍。

语法:
sql 复制代码
SELECT APPROX_COUNT_DISTINCT(column_name) FROM table_name;
案例:
sql 复制代码
-- 计算销售数据中不同客户的近似数量
SELECT 
    APPROX_COUNT_DISTINCT(CustomerID) AS ApproxUniqueCustomers,
    COUNT(DISTINCT CustomerID) AS ExactUniqueCustomers -- 对比精确值
FROM dbo.CustomerOrders;

-- 在大型表上测试性能差异
SET STATISTICS TIME ON;
GO

-- 精确计算(可能很慢)
SELECT COUNT(DISTINCT CustomerID) FROM dbo.CustomerOrders; -- 假设1亿行

-- 近似计算(极快)
SELECT APPROX_COUNT_DISTINCT(CustomerID) FROM dbo.CustomerOrders;
GO

SET STATISTICS TIME OFF;

💡 误差范围:通常 < 2%,适用于仪表盘、趋势分析等场景。


四、开发人员新体验

4.1 新增边约束功能(Graph Edge Constraints)

在图数据库中,约束边只能连接指定的节点对。

语法:
sql 复制代码
-- 创建图节点表
CREATE TABLE dbo.Person (
    ID INT PRIMARY KEY,
    Name NVARCHAR(50)
) AS NODE;

CREATE TABLE dbo.Company (
    ID INT PRIMARY KEY,
    Name NVARCHAR(50)
) AS NODE;

-- 创建边表(无约束)
CREATE TABLE dbo.WorksFor AS EDGE;

-- 添加边约束:仅允许 Person -> Company
ALTER TABLE dbo.WorksFor
ADD CONSTRAINT EC_WorksFor CONNECTION (dbo.Person TO dbo.Company);
案例:
sql 复制代码
-- 插入节点
INSERT INTO dbo.Person (ID, Name) VALUES (1, 'Alice'), (2, 'Bob');
INSERT INTO dbo.Company (ID, Name) VALUES (100, 'Microsoft'), (200, 'Google');

-- 插入合法边(Person -> Company)
INSERT INTO dbo.WorksFor ($from_id, $to_id)
SELECT 
    p.$node_id, 
    c.$node_id
FROM dbo.Person p, dbo.Company c
WHERE p.Name = 'Alice' AND c.Name = 'Microsoft';

-- 尝试插入非法边(Company -> Person)--- 将失败!
INSERT INTO dbo.WorksFor ($from_id, $to_id)
SELECT 
    c.$node_id, 
    p.$node_id
FROM dbo.Company c, dbo.Person p
WHERE c.Name = 'Google' AND p.Name = 'Bob';
-- ❌ 错误:The edge constraint 'EC_WorksFor' does not allow this connection.

-- 查询约束信息
SELECT 
    ec.name AS ConstraintName,
    object_name(ec.from_obj_id) AS FromTable,
    object_name(ec.to_obj_id) AS ToTable
FROM sys.edge_constraints ec
WHERE ec.object_id = OBJECT_ID('dbo.WorksFor');
GO

优势

  • 强制数据模型完整性。
  • 避免错误连接(如 Company -> Person)。
  • 提升图查询的可靠性。

4.2 新增图匹配查询(SHORTEST_PATH, Arbitrary Length Patterns)

支持更复杂的图遍历查询。

语法:
sql 复制代码
-- 最短路径
SELECT ... 
FROM node1, edge, node2
WHERE MATCH(SHORTEST_PATH(node1(-(edge)->node2)+))

-- 任意长度模式
MATCH(node1-(edge)->{1,5}node2) -- 1到5跳
案例:
sql 复制代码
-- 创建社交网络图
CREATE TABLE dbo.Friend (FriendID INT IDENTITY PRIMARY KEY, Since DATE) AS EDGE;
CREATE TABLE dbo.User (UserID INT PRIMARY KEY, Name NVARCHAR(50)) AS NODE;

-- 插入用户
INSERT INTO dbo.User (UserID, Name) VALUES 
(1, 'Alice'), (2, 'Bob'), (3, 'Charlie'), (4, 'David'), (5, 'Eve');

-- 插入朋友关系
INSERT INTO dbo.Friend ($from_id, $to_id, Since)
SELECT u1.$node_id, u2.$node_id, '2025-01-01'
FROM dbo.User u1, dbo.User u2
WHERE (u1.Name = 'Alice' AND u2.Name = 'Bob')
   OR (u1.Name = 'Bob' AND u2.Name = 'Charlie')
   OR (u1.Name = 'Charlie' AND u2.Name = 'David')
   OR (u1.Name = 'David' AND u2.Name = 'Eve');

-- 查询 Alice 到 Eve 的最短路径(朋友链)
SELECT 
    u1.Name AS StartUser,
    u2.Name AS EndUser,
    STRING_AGG(u.Name, ' -> ') WITHIN GROUP (GRAPH PATH) AS FriendPath,
    COUNT(u.UserID) WITHIN GROUP (GRAPH PATH) AS PathLength
FROM dbo.User u1, dbo.User u2, dbo.User u, dbo.Friend f
WHERE MATCH(SHORTEST_PATH(u1(-(f)->u)+))
AND u1.Name = 'Alice'
AND u2.Name = 'Eve'
GROUP BY u1.Name, u2.Name;

-- 查询最多3跳的朋友的朋友
SELECT 
    u1.Name AS StartUser,
    u2.Name AS ConnectedUser,
    COUNT(f.FriendID) WITHIN GROUP (GRAPH PATH) AS Hops
FROM dbo.User u1, dbo.User u2, dbo.Friend f
WHERE MATCH(u1(-(f)->{1,3}u2)) -- 1到3跳
AND u1.Name = 'Alice'
AND u2.Name <> 'Alice';

🌟 强大功能

  • SHORTEST_PATH:自动找到最短路径。
  • {min, max}:指定跳数范围。
  • STRING_AGG ... WITHIN GROUP (GRAPH PATH):聚合路径节点。

五、其他常用新增功能

5.1 UTF-8 排序规则支持

支持 UTF-8 编码,节省存储空间(尤其对英文/ASCII 数据)。

语法:
sql 复制代码
-- 创建使用 UTF-8 的数据库
CREATE DATABASE MyUTF8DB
COLLATE Latin1_General_100_CI_AS_SC_UTF8; -- 关键:_UTF8 后缀

-- 或修改现有数据库
ALTER DATABASE MyDB COLLATE Latin1_General_100_CI_AS_SC_UTF8;
案例:
sql 复制代码
-- 创建 UTF-8 表
CREATE TABLE dbo.Utf8Data (
    ID INT IDENTITY,
    EnglishText NVARCHAR(100) COLLATE Latin1_General_100_CI_AS_SC_UTF8, -- UTF-8 列
    ChineseText NVARCHAR(100) -- 默认排序规则(通常是 UCS-2/UTF-16)
);

-- 插入数据
INSERT INTO dbo.Utf8Data (EnglishText, ChineseText)
VALUES 
    (N'Hello World! 😊', N'你好世界!😊'),
    (N'This is ASCII-heavy text.', N'这是中文文本。');

-- 查看存储大小(UTF-8 对英文更省空间)
SELECT 
    EnglishText,
    ChineseText,
    DATALENGTH(EnglishText) AS EnglishBytes, -- UTF-8: ASCII字符占1字节
    DATALENGTH(ChineseText) AS ChineseBytes   -- UTF-16: 中文字符占2字节
FROM dbo.Utf8Data;

💡 节省空间

  • 英文/ASCII:UTF-8 比 UTF-16 节省 50% 空间。
  • 中文/日文:UTF-8 占 3 字节,UTF-16 占 2 字节 → UTF-16 更省。
  • 混合文本:根据比例决定。

5.2 RESUMABLE INDEX 操作

创建或重建索引时可暂停和恢复,避免长时间阻塞。

语法:
sql 复制代码
-- 创建可恢复索引
CREATE INDEX IX_Resume ON table(column) 
WITH (ONLINE = ON, RESUMABLE = ON, MAX_DURATION = 60); -- 60分钟超时暂停

-- 暂停索引操作
ALTER INDEX IX_Resume ON table PAUSE;

-- 恢复索引操作
ALTER INDEX IX_Resume ON table RESUME;

-- 中止索引操作
ALTER INDEX IX_Resume ON table ABORT;
案例:
sql 复制代码
-- 在大型表上创建可恢复索引
CREATE INDEX IX_CustomerOrders_Resumable 
ON dbo.CustomerOrders (CustomerID, OrderDate)
WITH (
    ONLINE = ON,      -- 在线操作,不阻塞查询
    RESUMABLE = ON,   -- 启用可恢复
    MAX_DURATION = 10 -- 10分钟超时自动暂停(单位:分钟)
);
GO

-- 如果被暂停(或超时),可恢复
ALTER INDEX IX_CustomerOrders_Resumable ON dbo.CustomerOrders RESUME;
GO

-- 查看可恢复索引状态
SELECT 
    object_name(i.object_id) AS TableName,
    i.name AS IndexName,
    i.is_resumable,
    i.percent_complete,
    i.state_desc
FROM sys.indexes i
WHERE i.is_resumable = 1;
GO

优势

  • 避免维护窗口不足导致失败。
  • 减少对业务的影响。
  • 支持 CREATE INDEXALTER INDEX ... REBUILD

六、关键任务的安全性

6.1 Always Encrypted with Secure Enclaves

支持在服务器端安全飞地(Intel SGX)内进行加密数据的计算,突破传统 AE 的限制。

⚠️ 要求

  • SQL Server 2019 企业版。
  • 支持 Intel SGX 的硬件。
  • 配置安全飞地。
语法(与传统 AE 类似,但支持更多操作):
sql 复制代码
-- 创建支持安全飞地的列加密密钥
CREATE COLUMN MASTER KEY CMK_Enclave
WITH (
    KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
    KEY_PATH = N'CurrentUser/My/...'
);

CREATE COLUMN ENCRYPTION KEY CEK_Enclave
WITH VALUES (
    COLUMN_MASTER_KEY = CMK_Enclave,
    ALGORITHM = 'RSA_OAEP',
    ENCRYPTED_VALUE = 0x...
);

-- 创建表(使用 ENCLAVE_COMPUTATIONS)
CREATE TABLE dbo.SecureSalary (
    EmployeeID INT PRIMARY KEY,
    Name NVARCHAR(50),
    Salary DECIMAL(10,2) 
        ENCRYPTED WITH (
            COLUMN_ENCRYPTION_KEY = CEK_Enclave,
            ENCRYPTION_TYPE = Randomized,
            ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
        ) 
        ENCLAVE_COMPUTATIONS (SIGNATURE = 0x...) -- 启用飞地计算
);

🌟 突破限制

  • 支持 BETWEEN, >, <, LIKE 等操作(传统 AE 仅支持 =)。
  • 数据在飞地内解密和计算,SQL Server 仍无法访问明文。

七、高可用性的数据库环境

7.1 Accelerated Database Recovery (ADR)

大幅缩短数据库恢复时间(尤其对长事务)。

默认启用(数据库级别)。

语法:
sql 复制代码
-- 启用 ADR(默认已启用)
ALTER DATABASE YourDB SET ACCELERATED_DATABASE_RECOVERY = ON;

-- 禁用 ADR
ALTER DATABASE YourDB SET ACCELERATED_DATABASE_RECOVERY = OFF;

💡 原理

  • 使用"持久版本存储"(PVS)记录事务版本。
  • 崩溃恢复时,无需回滚未提交事务(只需丢弃 PVS 中的版本)。
  • 恢复时间从小时级缩短到秒级。

八、更加灵活的平台选择

8.1 Linux 和容器支持增强

SQL Server 2019 完全支持 Linux 和 Docker 容器。

Docker 运行示例:
bash 复制代码
# 拉取 SQL Server 2019 Linux 容器镜像
docker pull mcr.microsoft.com/mssql/server:2019-latest

# 运行容器
docker run -e "ACCEPT_EULA=Y" \
           -e "SA_PASSWORD=YourStrong@Passw0rd" \
           -p 1433:1433 \
           --name sql2019 \
           -d mcr.microsoft.com/mssql/server:2019-latest

优势

  • 跨平台一致性。
  • 快速部署和测试。
  • 支持 Kubernetes。

九、SQL Server 机器学习服务(Machine Learning Services)

集成 Python 和 R,支持在数据库内执行机器学习。

⚠️ 安装时需选择"机器学习服务"

案例:使用 Python 执行聚类
sql 复制代码
-- 启用外部脚本
EXEC sp_configure 'external scripts enabled', 1;
RECONFIGURE;
GO

-- 重启 SQL Server 服务

-- 使用 Python 进行 K-Means 聚类
EXEC sp_execute_external_script
    @language = N'Python',
    @script = N'
import pandas as pd
from sklearn.cluster import KMeans

# Input Data
InputDataSet.columns = ["CustomerID", "TotalSpent", "OrderCount"]
X = InputDataSet[["TotalSpent", "OrderCount"]]

# K-Means
kmeans = KMeans(n_clusters=3, random_state=0)
InputDataSet["Cluster"] = kmeans.fit_predict(X)

# Output
OutputDataSet = InputDataSet[["CustomerID", "Cluster"]]
',
    @input_data_1 = N'
        SELECT 
            CustomerID,
            SUM(TotalAmount) AS TotalSpent,
            COUNT(*) AS OrderCount
        FROM dbo.CustomerOrders
        GROUP BY CustomerID
    ',
    @input_data_1_name = N'InputDataSet',
    @output_data_1_name = N'OutputDataSet'
WITH RESULT SETS ((CustomerID INT, Cluster INT));
GO

🌟 优势

  • 数据无需出库,安全高效。
  • 支持 Scikit-learn, TensorFlow, PyTorch 等库。
  • 结果可直接插入表或返回给应用。

十、SQL Server 报表服务(SSRS)

10.1 移动报表和 KPI 支持

增强的 Web 门户支持移动设备和实时 KPI。

📌 无新 T-SQL 语法,主要是前端功能增强。


十一、综合性案例

综合案例1:构建智能数据湖查询平台

sql 复制代码
-- 目标:使用 SQL Server 2019 查询 HDFS + Oracle + 本地数据,结合智能优化

USE DataLakeDB;
GO

-- 1. 启用 PolyBase
EXEC sp_configure 'polybase enabled', 1;
RECONFIGURE;
GO

-- 2. 创建外部数据源(HDFS + Oracle)
CREATE DATABASE SCOPED CREDENTIAL HdfsCred WITH IDENTITY = 'user', SECRET = 'pwd';
CREATE DATABASE SCOPED CREDENTIAL OracleCred WITH IDENTITY = 'ora_user', SECRET = 'ora_pwd';

CREATE EXTERNAL DATA SOURCE HdfsSource WITH (TYPE = HADOOP, LOCATION = 'hdfs://namenode:8020', CREDENTIAL = HdfsCred);
CREATE EXTERNAL DATA SOURCE OracleSource WITH (LOCATION = 'oracle://dbserver:1521', CREDENTIAL = OracleCred);

-- 3. 创建外部文件格式
CREATE EXTERNAL FILE FORMAT ParquetFormat WITH (FORMAT_TYPE = PARQUET);
CREATE EXTERNAL FILE FORMAT CsvFormat WITH (FORMAT_TYPE = DELIMITEDTEXT, FORMAT_OPTIONS (FIELD_TERMINATOR = ','));

-- 4. 创建外部表
CREATE EXTERNAL TABLE dbo.HdfsSales (
    SaleID INT,
    ProductID INT,
    Amount DECIMAL(10,2),
    SaleDate DATE
) WITH (LOCATION = '/data/sales/', DATA_SOURCE = HdfsSource, FILE_FORMAT = ParquetFormat);

CREATE EXTERNAL TABLE dbo.OracleProducts (
    ProductID INT,
    ProductName NVARCHAR(100),
    Category NVARCHAR(50)
) WITH (LOCATION = '[ORCL].[PROD].[PRODUCTS]', DATA_SOURCE = OracleSource);

-- 5. 创建本地维度表
CREATE TABLE dbo.DateDimension (
    DateKey DATE PRIMARY KEY,
    Year INT,
    Quarter INT,
    Month INT
);

-- 6. 执行复杂查询(智能优化自动生效)
SELECT 
    p.Category,
    d.Year,
    d.Quarter,
    APPROX_COUNT_DISTINCT(hs.SaleID) AS ApproxSalesCount, -- 近似计数
    SUM(hs.Amount) AS TotalSales
FROM dbo.HdfsSales hs
INNER JOIN dbo.OracleProducts p ON hs.ProductID = p.ProductID
INNER JOIN dbo.DateDimension d ON hs.SaleDate = d.DateKey
WHERE d.Year = 2025
GROUP BY p.Category, d.Year, d.Quarter
ORDER BY TotalSales DESC
OPTION (RECOMPILE); -- 确保使用最新统计信息和智能反馈
GO

-- 7. 创建物化视图(加速查询)
CREATE MATERIALIZED VIEW dbo.SalesSummary
WITH (DISTRIBUTION = ROUND_ROBIN) -- 如果是大数据群集
AS
SELECT 
    p.Category,
    YEAR(hs.SaleDate) AS SaleYear,
    DATEPART(QUARTER, hs.SaleDate) AS SaleQuarter,
    COUNT_BIG(*) AS SalesCount,
    SUM(hs.Amount) AS TotalSales
FROM dbo.HdfsSales hs
INNER JOIN dbo.OracleProducts p ON hs.ProductID = p.ProductID
GROUP BY p.Category, YEAR(hs.SaleDate), DATEPART(QUARTER, hs.SaleDate);
GO

-- 8. 查询物化视图(极快)
SELECT * FROM dbo.SalesSummary WHERE SaleYear = 2025 ORDER BY TotalSales DESC;
GO

技术整合

  • PolyBase:虚拟化 HDFS 和 Oracle。
  • 智能优化:内存反馈、交错执行。
  • 近似查询:APPROX_COUNT_DISTINCT
  • 物化视图:预计算加速。

综合案例2:安全合规的图数据库应用

sql 复制代码
-- 目标:构建社交网络图,包含安全加密和边约束

USE SocialGraphDB;
GO

-- 1. 创建节点表(用户信息加密)
CREATE COLUMN MASTER KEY CMK_Social WITH (
    KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
    KEY_PATH = N'CurrentUser/My/...'
);

CREATE COLUMN ENCRYPTION KEY CEK_Social WITH VALUES (
    COLUMN_MASTER_KEY = CMK_Social,
    ALGORITHM = 'RSA_OAEP',
    ENCRYPTED_VALUE = 0x...
);

CREATE TABLE dbo.UserNode (
    UserID INT IDENTITY PRIMARY KEY,
    UserName NVARCHAR(50), -- 公开
    Email NVARCHAR(100) 
        ENCRYPTED WITH (
            COLUMN_ENCRYPTION_KEY = CEK_Social,
            ENCRYPTION_TYPE = Deterministic,
            ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
        ),
    Phone NVARCHAR(20) 
        ENCRYPTED WITH (
            COLUMN_ENCRYPTION_KEY = CEK_Social,
            ENCRYPTION_TYPE = Randomized,
            ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
        )
) AS NODE;

-- 2. 创建边表并添加约束
CREATE TABLE dbo.FriendEdge (Since DATE) AS EDGE;

-- 约束:仅允许 UserNode 到 UserNode
ALTER TABLE dbo.FriendEdge
ADD CONSTRAINT EC_Friend CONNECTION (dbo.UserNode TO dbo.UserNode);

-- 3. 插入数据(需在支持 AE 的客户端执行)
-- INSERT INTO dbo.UserNode (UserName, Email, Phone) VALUES (...);

-- 4. 查询最短路径(查找共同好友)
SELECT 
    u1.UserName AS StartUser,
    u2.UserName AS TargetUser,
    STRING_AGG(u.UserName, ' -> ') WITHIN GROUP (GRAPH PATH) AS FriendPath
FROM dbo.UserNode u1, dbo.UserNode u2, dbo.UserNode u, dbo.FriendEdge f
WHERE MATCH(SHORTEST_PATH(u1(-(f)->u)+))
AND u1.UserName = 'Alice'
AND u2.UserName = 'Eve'
AND COUNT(u.UserID) WITHIN GROUP (GRAPH PATH) <= 3; -- 限制3跳内

-- 5. 动态数据屏蔽(保护电话号码)
ALTER TABLE dbo.UserNode
ALTER COLUMN Phone ADD MASKED WITH (FUNCTION = 'partial(3, "XXXX", 2)');

-- 6. 创建普通用户(只能看到屏蔽数据)
CREATE USER analyst WITHOUT LOGIN;
GRANT SELECT ON dbo.UserNode TO analyst;
GRANT SELECT ON dbo.FriendEdge TO analyst;

-- 7. 以分析师身份查询
EXECUTE AS USER = 'analyst';
SELECT TOP 5 UserName, Email, Phone FROM dbo.UserNode; -- Phone 显示为 138XXXXXX00
REVERT;
GO

安全合规

  • Always Encrypted:保护敏感数据。
  • 边约束:确保数据模型正确。
  • 动态数据屏蔽:控制数据可见性。
  • 图查询:支持复杂关系分析。

总结

SQL Server 2019 是一次重大升级,核心亮点:

类别 关键功能
智能性能 内存授予反馈、MSTVF 交错执行、表变量延迟编译
数据虚拟化 PolyBase 增强,统一查询异构数据
开发体验 图数据库增强、UTF-8、近似查询
安全性 Always Encrypted with Secure Enclaves
高可用 Accelerated Database Recovery
AI/ML 内置 Python/R 机器学习

🚀 建议

  • 生产环境升级前充分测试。
  • 利用智能优化减少手动调优。
  • 结合 PolyBase 构建现代数据平台。
  • 使用图数据库处理复杂关系。

✅ 掌握这些功能,你将能构建更智能、更安全、更高性能的 SQL Server 应用!

相关推荐
禹凕1 小时前
MySQL ALTER 命令详解:灵活修改表结构的终极指南
数据库·mysql
Coder_Boy_2 小时前
技术交流总结:分布式、数据库、Spring及SpringBoot核心知识点梳理(实现参考)
数据库·spring boot·分布式·spring·架构
想不明白的过度思考者2 小时前
Spring Boot 实战:MyBatis 操作数据库(上)
java·数据库·spring boot·mysql·mybatis
此生只爱蛋2 小时前
【MySQL】存储过程
数据库·mysql
白太岁2 小时前
Redis:(6) 三级缓存+连接池与高性能 Redis 客户端封装
数据库·redis·缓存
2501_944934732 小时前
高职金融大数据应用专业,怎么学习金融数据建模基础?
大数据·学习·金融
nix.gnehc2 小时前
Go进阶攻坚+专家深耕级学习清单|聚焦高并发、高性能中间件/底层框架开发(Java开发者专属)
学习·中间件·golang
apcipot_rain2 小时前
python 多进程多线程 学习笔记
笔记·python·学习
学编程的闹钟2 小时前
E语言变量声明与使用全解析
学习