28、Azure SQL 数据库的 DevOps 实践

Azure SQL 数据库的 DevOps 实践

1. ORM 与数据库迁移工具

ORM 和数据库迁移工具几乎可用于任何平台,既可以作为独立对象,也可以嵌入框架中。无论你使用何种语言或平台进行编码,若倾向于采用 Code First 方法开发数据库,总能找到适用的工具。

在 CI/CD 管道中执行迁移操作相当简单,只需在管道工具中执行用于生成和应用迁移的同一工具即可。在此情况下,CI/CD 管道无需任何专门的 Azure SQL 操作或任务,因为无需执行任何 T-SQL 脚本,仅需能够调用迁移工具(通常是命令行应用程序)。在 GitHub Actions 或 Azure DevOps 中,可利用原生支持来运行任意命令(需注意,可能需要在 CI/CD 环境中安装所选工具)。

2. Database First 方法

2.1 ORM 上下文中的 Database First

Database First 意味着独立于使用数据库的应用程序对数据库进行建模和演进。该术语通常与 ORM 的使用相关。在 ORM 环境中,它表示借助某种工具,从现有的数据库表和对象创建应用程序中使用的部分类。这与 Code First 方法截然相反,Code First 是通过代码创建数据库及相关对象。

2.2 通用意义上的 Database First

若将 “Database First” 概念从 ORM 环境中抽离,以更通用和宽泛的视角来看,它意味着手动使用数据库自身的工具和语言来创建和演进数据库。以 Azure SQL 为例,即编写和使用 T-SQL,并负责将应用程序与数据库连接起来,可使用 ORM、Micro-ORM,也可完全手动操作。

这种方式给予了极大的自由度。对开发数据库进行所有更改后,需创建脚本,以便将这些更改应用到目标数据库,使其达到所需的架构。同样,这里也有很大的选择空间:可以选择使用工具自动生成脚本,也可以自行提供脚本。

3. DACPAC 与 SqlPackage 工具

3.1 SqlPackage 简介

若希望有工具能将开发数据库与目标数据库进行比较,计算差异,生成将目标数据库迁移到新架构所需的脚本(且不丢失任何数据),并最终应用这些脚本,那么 SqlPackage 就是这样一款免费的工具,它也是用于在 Azure SQL 中恢复数据库的工具。

3.2 使用 SqlPackage 提取架构

使用 SqlPackage 可将现有数据库的架构提取到 .dacpac 文件中,然后针对目标数据库使用该文件,让 SqlPackage 生成同步目标数据库架构与 .dacpac 中定义架构所需的所有命令脚本。以下代码可将托管在 Azure 中的名为 blogs 的数据库的架构和所有对象(不包含数据)提取到 blogs-v1.dacpac 文件中:

sqlpackage.exe
      /a:Extract
      /ssn:"<azure-sql-address>"
      /su:"<user>"
      /su:"<password>"
      /sdn:"blogs"
      /tf:"blogs-v1.dacpac"

3.3 使用 .dacpac 文件更新目标数据库

3.3.1 直接更新

获取 .dacpac 文件后,可通过 Publish 操作立即更新目标数据库:

sqlpackage.exe
      /a:Publish
      /sf:"blogs-v1.dacpac"
      /tsn:"<azure-sql-address>"
      /tu:"<user>"
      /tp:"<password>"
      /tdn:"blogs-prod"
3.3.2 生成脚本更新

也可通过同名操作创建脚本,后续使用该脚本更新数据库:

sqlpackage.exe
      /a:Scripts
      /sf:"blogs-v1.dacpac"
      /tsn:"<azure-sql-address>"
      /tu:"<user>"
      /tp:"<password>"
      /tdn:"blogs-prod"
      /op:"blogs-db-v1.sql"

生成脚本的功能很实用,可用于自定义添加初始化数据,或保存脚本到代码仓库,以便确切了解 CI/CD 管道中要执行的操作。此时,可使用 GitHub 或 DevOps 中的 Azure SQL 操作或任务来执行该脚本。

另一种选择是在 CI/CD 管道中直接执行 SqlPackage,使用专门的 Azure SQL 操作或任务应用更改,而无需生成脚本。这种方法虽更灵活,能自动确定使目标数据库达到所需状态的更改,但风险较大,因为无法完全控制操作过程,一般不建议采用。

4. 数据库比较工具

除了 SqlPackage,还有一些第三方工具可帮助找出两个现有数据库之间的差异,从而生成同步目标数据库与参考数据库的脚本。常见且知名的工具如下:
| 工具名称 | 性质 |
| ---- | ---- |
| SQL Server Data Tools(Visual Studio 工作负载扩展) | - |
| Redgate SQL Compare | 商业工具 |
| ApexSQL SQL Compare | 商业工具 |

5. DbUp 工具

5.1 DbUp 简介

DbUp(https://dbup.github.io/)是一个开源的 .NET 库,用于在数据库中部署脚本,确保同一脚本不会重复部署。若想完全控制部署到数据库的脚本,并按顺序执行一系列脚本,以正确的顺序应用更改,将数据库更新到最新状态,那么这个小工具非常有用。在复杂和关键的系统中,通常会采用这种方法。

5.2 使用 DbUp

使用 DbUp 极其简单。只需将 NuGet 包添加到项目中(建议为此创建一个专用项目),然后使用 DeployChanges 对象并指向要部署脚本的文件夹,例如项目结构中的 sql 文件夹:

var connectionString = "<connection-string>";
var upgrader = DeployChanges.To
      .SqlDatabase(connectionString)
      .JournalToSqlTable("dbo", "$__schema_journal")
      .WithScriptsFromFileSystem("./sql")
      .LogToConsole()
      .Build();
var result = upgrader.PerformUpgrade();

上述代码执行时会完成以下操作:
1. 连接到目标数据库。
2. 若不存在名为 $__schema_journal 的表,则创建该表,用于跟踪已部署的脚本。
3. 读取 sql 文件夹中的所有 T-SQL 脚本。
4. 将日志发送到控制台。
5. 运行脚本,并将已执行的脚本记录到日志表中。

若针对空数据库编译并运行此应用程序,会看到相应输出。若不向 sql 文件夹添加新脚本,再次运行该应用程序时,不会有任何操作,因为所有脚本都已执行过。由于这是一个常规的 .NET 应用程序,将其部署到 CI/CD 管道中,除了使管道中可用 .NET 框架所需的任务外,无需任何特殊任务或操作。

以下是使用 DbUp 部署脚本的流程图:

graph LR
    A[开始] --> B[添加 NuGet 包]
    B --> C[配置 DeployChanges 对象]
    C --> D[连接目标数据库]
    D --> E{是否存在日志表}
    E -- 否 --> F[创建日志表]
    E -- 是 --> G[读取脚本文件夹]
    F --> G
    G --> H[运行脚本]
    H --> I[记录已执行脚本]
    I --> J[结束]

6. 数据库测试

6.1 数据库测试的挑战

测试数据库是一项复杂的挑战,因为测试结果完全取决于数据库中存储的数据。此外,目前还没有被广泛采用的专注于数据库测试的框架。

6.2 可用的测试框架和方法

6.2.1 tSQLt

有一个社区支持的单元测试框架 tSQLt 支持 Azure SQL。使用 tSQLt,只需使用 T-SQL 代码即可定义测试。它支持对标量和表格的预期结果进行断言,还可以创建一些模拟对象来帮助隔离依赖项。

6.2.2 使用通用测试框架

作为开发者,更倾向于使用常见的测试框架(如 .NET 的 NUnit 或 XUnit、Python 的 pytest 或 Node 的 Mocha)创建测试类,利用这些工具的灵活性获得良好的测试体验。

众所周知,测试必须是自包含、独立且幂等的。上述测试框架都允许在运行测试前后执行自定义代码,以便准备和清理测试数据及环境。虽然纯粹的单元测试不应有外部依赖,但为了测试数据库,实际上引入了对数据库本身的依赖。不过,使用现有的单元测试框架是一个不错的折衷方案,以小幅度偏离完美方法为代价,换取了所需的灵活性。由于目前没有普遍接受的数据库单元测试框架,只能充分利用现有的工具。

以下是一个使用 .NET 和 NUnit 进行数据库单元测试的示例:

[Test]
public void CheckExpectedTotal()
{
    using(var conn = new SqlConnection(ConnectionString))
    {
        var result = conn.QuerySingle(
            "ConfirmOrder",
            new { OrderId = 38923 },
            commandType: CommandType.StoredProcedure);
        Assert.AreEqual("ConfirmedTotal", 10000);
    }
}

通常,为每个要创建的测试生成一组或多组数据,以涵盖要测试的查询或存储过程的可能使用场景。为了检查查询是否返回预期结果,可使用小数据样本,甚至可以使用完全模拟的值创建样本,这样就无需处理个人身份信息及相关的安全问题。在最复杂的场景中,运行测试前可能需要恢复参考数据集甚至整个数据库,以便为运行测试提供一个已知的起点,从而获得确定性的结果。

6.3 测试流程

测试数据库的流程可总结如下表:
| 步骤 | 操作 |
| ---- | ---- |
| 1 | 选择测试框架(tSQLt 或通用测试框架) |
| 2 | 准备测试数据和环境 |
| 3 | 编写测试代码 |
| 4 | 运行测试 |
| 5 | 检查测试结果 |
| 6 | 清理测试数据和环境 |

7. 整合所有环节

创建一个完整的端到端 CI/CD 管道首次操作时可能有点复杂。不过,可以找到一个端到端的示例,展示如何创建一个简单的 C# REST API,由 Azure SQL 数据库支持,并使用 Azure Web App 部署到 Azure。该 CI/CD 管道使用 GitHub 和 DbUp 创建,使用的测试框架是 NUnit。

以下是一个简化的 CI/CD 管道流程图:

graph LR
    A[代码提交] --> B[CI 触发]
    B --> C[运行单元测试]
    C --> D{测试是否通过}
    D -- 是 --> E[数据库迁移]
    D -- 否 --> F[失败通知]
    E --> G[部署到测试环境]
    G --> H[运行集成和性能测试]
    H --> I{测试是否通过}
    I -- 是 --> J[部署到生产环境]
    I -- 否 --> K[回滚更改]

8. 进一步学习资源

DevOps 是一个非常广泛的主题,这里只是触及了表面。DevOps 也是一个相对年轻且发展迅速的领域,因此及时了解最新信息非常重要。以下是一些有助于深入了解的链接和资源:
- Annual State of Database DevOps report – www.red - gate.com/solutions/overview
- Evolutionary Database Design – www.martinfowler.com/articles/evodb.html
- Agile Database Techniques – www.amazon.com/Agile - Database - Techniques - Effective - Strategies/dp/0471202835
- Introduction to DevOps: DevOps and the Database – www.red - gate.com/simple - talk/sql/database - devops - sql/introduction - to - devops - devops - and - the - database/
- Azure SQL Database Deployment task – https://docs.microsoft.com/azure/devops/pipelines/tasks/deploy/sql - azure - dacpac - deployment
- GitHub Action for deploying updates to Azure SQL database – https://github.com/marketplace/actions/azure - sql - deploy
- Django: Migrations – https://docs.djangoproject.com/en/3.0/topics/migrations/
- Django: Writing Migrations – https://docs.djangoproject.com/en/3.0/howto/writing - migrations/
- Entity Framework Core – https://docs.microsoft.com/ef/core/
- Code First Migrations – https://docs.microsoft.com/ef/ef6/modeling/code - first/migrations/
- Synchronization via SQLPackage.exe and PowerShell – www.mssqltips.com/sqlservertip/4759/sql - server - database - schema - synchronization - via - sqlpackageexe - and - powershell/
- Unit testing in .NET Core and .NET Standard – https://docs.microsoft.com/dotnet/core/testing/

## 软件功能详细介绍 1. **文本片段管理**:可以添加、编辑、删除常用文本片段,方便快速调用 2. **分组管理**:支持创建多个分组,不同类型的文本片段可以分类存储 3. **热键绑定**:为每个文本片段绑定自定义热键,实现一键粘贴 4. **窗口置顶**:支持窗口置顶功能,方便在其他应用程序上直接使用 5. **自动隐藏**:可以设置自动隐藏,减少桌面占用空间 6. **数据持久化**:所有配置和文本片段会自动保存,下次启动时自动加载 ## 软件使用技巧说明 1. **快速添加文本**:在文本输入框中输入内容后,点击"添加内容"按钮即可快速添加 2. **批量管理**:可以同时编辑多个文本片段,提高管理效率 3. **热键冲突处理**:如果设置的热键与系统或其他软件冲突,会自动提示 4. **分组切换**:使用分组按钮可以快速切换不同类别的文本片段 5. **文本格式化**:支持在文本片段中使用换行符和制表符等格式 ## 软件操作方法指南 1. **启动软件**:双击"大飞哥软件自习室——快捷粘贴工具.exe"文件即可启动 2. **添加文本片段**: - 在主界面的文本输入框中输入要保存的内容 - 点击"添加内容"按钮 - 在弹出的对话框中设置热键和分组 - 点击"确定"保存 3. **使用热键粘贴**: - 确保软件处于运行状态 - 在需要粘贴的位置按下设置的热键 - 文本片段会自动粘贴到当前位置 4. **编辑文本片段**: - 选中要编辑的文本片段 - 点击"编辑"按钮 - 修改内容或热键设置 - 点击"确定"保存修改 5. **删除文本片段**: - 选中要删除的文本片段 - 点击"删除"按钮 - 在确认对话框中点击"确定"即可删除
在全球电动汽车产业快速扩张的背景下,充电基础设施的规划与运营效率成为影响交通能源转型的关键环节。充电站作为电动汽车能源补给的核心节点,其电力负荷的波动特性直接关系到电网稳定与用户服务体验。因此,构建精确的负荷预测模型已成为提升充电网络智能化管理水平的重要基础。 为支持相关研究与应用开发,专门针对充电站电力消耗预测所构建的数据集合,系统整合了多维度变量,旨在揭示负荷变化的潜在规律。这类数据通常涵盖以下结构化信息:时序用电记录,以固定间隔(如每小时或每日)记载充电站总能耗;充电过程明细,包括各充电单元的功率曲线、充电持续时间及结束时刻;用户行为特征,例如用户群体分类、充电周期规律与时段偏好;外部环境参数,如气象指标(气温、降水、风力)及法定假期安排,这些因素共同作用于出行需求与充电决策;站点属性数据,涉及地理位置、充电设备型号与规模、服务容量上限等,用于评估站点运行效能。 数据质量与覆盖范围显著影响预测算法的可靠性。完备且精准的数据有助于识别负荷波动的驱动要素,进而支持电网侧与运营侧的协同优化。例如,基于负荷预测结果,运营商可实施动态定价机制,引导用户在低谷时段充电,以平抑电网峰值压力;电力部门则可依据预测趋势提前规划配电网络扩容,保障供电安全。 当前,随着机器学习与人工智能方法的不断成熟,将其引入充电负荷预测领域,不仅能够提升模型预测精度,还可推动充电站运营向自动化、自适应方向演进,从而促进电动汽车生态体系的长期可持续发展。总体而言,充电站负荷预测数据集为学术研究与工程实践提供了关键的数据基础,助力实现负荷精准预估、资源优化配置与能源高效利用,进一步加速电动汽车的规模化应用。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值