青岛网站建设公司番禺网站建设

龙口市鸿达畜牧机械有限公司 2026/09/09 19:42:41

关于数据库迁移


什么是数据库迁移


数据库迁移(Database Migration)是指对数据库结构进行版本控制的过程,它允许开发团队跟踪数据库模式的变更,并确保在不同环境(开发、测试、生产)中数据库结构的一致性。

为什么需要数据库迁移


在传统的软件开发中,数据库变更通常通过手动执行SQL脚本完成,这种方式存在诸多问题:

版本不一致:不同环境的数据库结构可能不一致

协作困难:多人开发时容易产生冲突

回滚复杂:出现问题时难以快速回滚到之前的版本

缺乏历史记录:无法追踪数据库结构的变更历史

Liquibase

Liquibase 是一个开源的数据库迁移工具,它通过 changelog 文件来管理数据库的变更,支持多种格式(XML、JSON、YAML、SQL)的变更定义,能够与多种数据库系统协同工作。

主要特性:

支持多种数据库(MySQL、PostgreSQL、Oracle等)

多种变更定义格式

回滚支持

与Spring Boot无缝集成

丰富的变更类型支持

Spring Boot 集成 Liquibase

添加依赖

首先,在pom.xml中添加 Liquibase 依赖:

<!-- Liquibase Database Migration --> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency>

Liquibase比起Flyway,对Springboot的支持更好。使用Springboot3也可以运行,Flyway则在Springboot3里面无法使用。

YML配置

# Liquibase Configuration liquibase: enabled: true change-log: classpath:db/changelog/db.changelog-master.xml drop-first: false default-schema: mqtt

定义Liquibase的XML

创建主变更日志文件

src/main/resources/db/changelog目录下创建主变更日志文件db.changelog-master.yaml

<?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.20.xsd"> <!-- Include all changelog files --> <include file="db/changelog/changes/v1.0-initial-schema.xml"/> <include file="db/changelog/changes/v1.1-sample-data.xml"/> </databaseChangeLog>

v1.0-initial-schema.xml 初始化数据库结构

<?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.20.xsd"> <!-- Create mqtt_connection table --> <changeSet id="1" author="mqtt-websocket-bridge"> <createTable tableName="mqtt_connection" remarks="MQTT Connection Table"> <column name="id" type="BIGINT" autoIncrement="true"> <constraints primaryKey="true" nullable="false"/> </column> <column name="client_id" type="VARCHAR(255)" remarks="MQTT Client ID"> <constraints nullable="false" unique="true"/> </column> <column name="broker_url" type="VARCHAR(255)" remarks="MQTT Broker URL"> <constraints nullable="false"/> </column> <column name="username" type="VARCHAR(255)" remarks="Username"/> <column name="password" type="VARCHAR(255)" remarks="Password"/> <column name="keep_alive" type="INT" defaultValue="60" remarks="Keep Alive Interval (seconds)"/> <column name="clean_session" type="TINYINT(1)" defaultValue="1" remarks="Clean Session Flag"/> <column name="protocol_version" type="VARCHAR(50)" defaultValue="MQTT 3.1.1" remarks="Protocol Version"/> <column name="tls_enabled" type="TINYINT(1)" defaultValue="0" remarks="TLS Enabled"/> <column name="status" type="INT" defaultValue="0" remarks="Connection Status (0: disconnected, 1: connected)"/> <column name="connected_at" type="DATETIME" remarks="Connection Timestamp"/> <column name="disconnected_at" type="DATETIME" remarks="Disconnection Timestamp"/> <column name="created_at" type="DATETIME" defaultValueComputed="CURRENT_TIMESTAMP" remarks="Create Time"/> <column name="updated_at" type="DATETIME" defaultValueComputed="CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" remarks="Update Time"/> <column name="deleted" type="INT" defaultValue="0" remarks="Logical Delete Flag"/> </createTable> <!-- Create indexes for mqtt_connection --> <createIndex indexName="idx_client_id" tableName="mqtt_connection"> <column name="client_id"/> </createIndex> <createIndex indexName="idx_status" tableName="mqtt_connection"> <column name="status"/> </createIndex> <createIndex indexName="idx_created_at" tableName="mqtt_connection"> <column name="created_at"/> </createIndex> </changeSet> <!-- Create mqtt_subscription table --> <changeSet id="2" author="mqtt-websocket-bridge"> <createTable tableName="mqtt_subscription" remarks="MQTT Subscription Table"> <column name="id" type="BIGINT" autoIncrement="true"> <constraints primaryKey="true" nullable="false"/> </column> <column name="client_id" type="VARCHAR(255)" remarks="MQTT Client ID"> <constraints nullable="false"/> </column> <column name="topic" type="VARCHAR(500)" remarks="MQTT Topic"> <constraints nullable="false"/> </column> <column name="qos" type="INT" defaultValue="0" remarks="Quality of Service (0, 1, 2)"/> <column name="subscribed_at" type="DATETIME" defaultValueComputed="CURRENT_TIMESTAMP" remarks="Subscription Timestamp"/> <column name="created_at" type="DATETIME" defaultValueComputed="CURRENT_TIMESTAMP" remarks="Create Time"/> <column name="updated_at" type="DATETIME" defaultValueComputed="CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" remarks="Update Time"/> <column name="deleted" type="INT" defaultValue="0" remarks="Logical Delete Flag"/> </createTable> <!-- Create indexes for mqtt_subscription --> <createIndex indexName="idx_client_id" tableName="mqtt_subscription"> <column name="client_id"/> </createIndex> <createIndex indexName="idx_topic" tableName="mqtt_subscription"> <column name="topic"/> </createIndex> <createIndex indexName="idx_subscribed_at" tableName="mqtt_subscription"> <column name="subscribed_at"/> </createIndex> <!-- Create unique constraint --> <addUniqueConstraint tableName="mqtt_subscription" columnNames="client_id, topic" constraintName="uk_client_topic"/> </changeSet> <!-- Create mqtt_message table --> <changeSet id="3" author="mqtt-websocket-bridge"> <createTable tableName="mqtt_message" remarks="MQTT Message Table"> <column name="id" type="BIGINT" autoIncrement="true"> <constraints primaryKey="true" nullable="false"/> </column> <column name="client_id" type="VARCHAR(255)" remarks="MQTT Client ID"> <constraints nullable="false"/> </column> <column name="topic" type="VARCHAR(500)" remarks="MQTT Topic"> <constraints nullable="false"/> </column> <column name="payload" type="TEXT" remarks="Message Payload"/> <column name="qos" type="INT" defaultValue="0" remarks="Quality of Service (0, 1, 2)"/> <column name="retained" type="TINYINT(1)" defaultValue="0" remarks="Retained Message Flag"/> <column name="direction" type="VARCHAR(50)" remarks="Message Direction (INBOUND, OUTBOUND)"> <constraints nullable="false"/> </column> <column name="created_at" type="DATETIME" defaultValueComputed="CURRENT_TIMESTAMP" remarks="Create Time"/> <column name="deleted" type="INT" defaultValue="0" remarks="Logical Delete Flag"/> </createTable> <!-- Create indexes for mqtt_message --> <createIndex indexName="idx_client_id" tableName="mqtt_message"> <column name="client_id"/> </createIndex> <createIndex indexName="idx_topic" tableName="mqtt_message"> <column name="topic"/> </createIndex> <createIndex indexName="idx_direction" tableName="mqtt_message"> <column name="direction"/> </createIndex> <createIndex indexName="idx_created_at" tableName="mqtt_message"> <column name="created_at"/> </createIndex> </changeSet> </databaseChangeLog>

v1.1-sample-data.xml 初始化数据

<?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.20.xsd"> <!-- Insert sample connection data --> <changeSet id="4" author="mqtt-websocket-bridge"> <insert tableName="mqtt_connection"> <column name="client_id" value="emqx_NJEONID"/> <column name="broker_url" value="tcp://localhost:1883"/> <column name="username" value=""/> <column name="password" value=""/> <column name="keep_alive" valueNumeric="60"/> <column name="clean_session" valueNumeric="1"/> <column name="protocol_version" value="MQTT 5"/> <column name="status" valueNumeric="0"/> </insert> </changeSet> </databaseChangeLog>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

深圳营销型网站建设吉安网站建设

Turn.js 作为 HTML5 时代专业的翻页效果解决方案,正在重塑企业数字内容的阅读体验。在前端技术快速迭代的今天,如何选择并有效部署一个稳定可靠的翻页组件࿰

2026/06/30 11:02:53

网站建设模板广州市网站建设

物联网平台 - Thinglinks-iot## 🌟 项目简介一个功能完备、高可扩展的物联网平台,提供完整的设备接入、管理和数据处理解决方案。支持多种网络协议࿰

2026/06/30 10:41:21

网站建设收费摄影网站建设

FUXA开源SCADA:5分钟构建工业级实时监控系统的完整指南【免费下载链接】FUXAWeb-based Process Visualization (SCADA/HMI/Dashboa

2026/06/30 10:40:21

网站建设方案内蒙古网站建设

一、前言最近很多学生和朋友问我:如何用Coze搭建自己的AI智能体工作流程?想参加线上或者线下课学习。今天花点时间跟大家讲讲如何使用Coze搭建自己的AI Agent&#x

2026/06/30 13:23:05

网站建设工作室上海网站建设的

一次上电即成功:深度拆解硬件电路中的软启动设计你有没有遇到过这样的场景?系统明明设计得很完善,元器件选型也没问题,可每次上电瞬间,

2026/06/30 12:50:03

上海网站建设舟山网站建设

Windows终极自定义神器Windhawk:零基础打造专属系统体验【免费下载链接】windhawkThe customization marketplace for Windows p

2026/06/30 13:53:37

福州网站建设济南营销型网站建设

第一章:PHP图像识别精度优化的挑战与机遇随着人工智能与Web应用深度融合,PHP作为广泛使用的服务端脚本语言,正逐步承担起图像识别任务的调度与后处理职责。尽

2026/06/30 14:08:38

长沙网站建设公司网站建设公司哪个好

基于单片机的全自动洗衣机控制器的设计与实现第一章 绪论传统半自动洗衣机依赖手动操作水位调节、程序切换与进水排水控制,存在明显局限:水位判断依赖经验(易导致水量

2026/06/30 12:39:32

企业网站建设方案丹阳网站建设

作为高校助教,每年指导本科毕业论文时,我都会遇到相似的场景:学生手里攥着十几篇文献,眼神却充满迷茫;提纲写了三版,逻

2026/06/30 11:34:26

网站建设项目海口网站建设

5分钟极速上手:让你的网易云音乐插上翅膀【免费下载链接】BetterNCM-Installer一键安装 Better 系软件项目地址: https://gitcode.com/gh_mi

2026/06/30 12:52:03