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

西安聚研教育科技有限公司 2026/09/09 19:38: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>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

天津网站建设商业网站建设

AcFun视频下载完整攻略:5分钟掌握离线收藏A站内容的最佳方法【免费下载链接】AcFunDown包含PC端UI界面的A站 视频下载器。支持收藏夹、UP主视频批量下载 😳

2026/06/30 13:52:08

企业网站建设方案模板网站建设

终极免费方案:彻底解锁百度网盘macOS版下载速度限制【免费下载链接】BaiduNetdiskPlugin-macOSFor macOS.百度网盘 破解SVIP、下载速度限制~项目地址:

2026/06/30 11:28:55

免费网站建设襄樊网站建设

Realtek R8125 2.5G网卡终极配置指南:让高速网络触手可及【免费下载链接】realtek-r8125-dkmsA DKMS package for easy use of

2026/06/30 12:29:01

免费网站建设湘潭网站建设

Java生成图片验证码的工具类实现 - 通用安全组件开发指南在现代Web应用中,防止自动化脚本恶意注册、暴力破解或爬虫攻击是系统安全的重要一环。图形验证码作为一道简单而有效的防线

2026/06/30 14:03:08

佛山网站建设服装网站建设

一、现在的真实情况:查重过了,论文却被卡 AI 率这两年,很多同学都会遇到一个很反直觉的情况:重复率 5%–10%,老师点头AI

2026/06/30 11:37:26

建设网站杭州营销型网站建设

背景及意义在校园自助洗衣服务规模化、管理智能化需求升级的背景下,传统洗衣管理存在 “设备状态不透明、预约排队无序、计费结算混乱” 的痛点,基于 SpringBoot 构建的

2026/06/30 11:50:27

邢台网站建设湘潭网站建设

数字化笔迹生成革命:AI驱动的手写风格创作完整指南【免费下载链接】text-to-handwritingSo your teacher asked you to upload writt

2026/06/30 12:47:33

乐清网站建设徐州网站建设

BDSup2Sub完整指南:轻松掌握蓝光字幕转换的终极教程【免费下载链接】BDSup2SubBlu-Ray/DVD subtitle editor项目地址: https://gitcod

2026/06/30 12:17:31

河南网站建设石家庄网站建设

Boofuzz模糊测试实战指南:从入门到精通【免费下载链接】boofuzzA fork and successor of the Sulley Fuzzing Framework项目地址

2026/06/30 13:41:06