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

武汉迈极环保科技有限公司 2026/09/09 18:07:14

关于数据库迁移


什么是数据库迁移


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

天门网站建设好的网站建设

从零开始:Equalizer APO音频调校完整指南【免费下载链接】equalizerapoEqualizer APO mirror项目地址: https://gitcode.com/g

2026/06/30 14:17:39

网站建设与管理网站建设推广

AI与提示工程协同进化的瓶颈突破:提示工程架构师的5大创新方案一、引言:当“调提示”成为AI应用的“卡脖子”问题1. 一个让所有AI从业者崩溃的场景你是否有过这样的经历&#

2026/06/30 10:29:51

服装网站建设大型网站建设

免费打造个性化macOS光标:Mousecape完整使用指南【免费下载链接】MousecapeCursor Manager for OSX项目地址: https://gitcode.co

2026/06/30 13:32:36

建设网站网站建设团队

YoloMouse终极指南:快速掌握游戏光标自定义技巧【免费下载链接】YoloMouseGame Cursor Changer项目地址: https://gitcode.com/gh_m

2026/06/30 13:28:06

郑州建设网站长沙企业网站建设

从CAN到CAN FD:AUTOSAR通信栈升级实战全解析车载网络的演进,从来不是一场突如其来的革命,而是一次次在带宽瓶颈边缘的精准突围。十年前,

2026/06/30 10:13:49

商务网站建设西宁网站建设

autofit.js大屏自适应终极方案:一键配置实现完美布局【免费下载链接】autofit.jsautofit.js 迄今为止最易用的自适应工具项目地址: https://gitcode

2026/06/30 13:08:34

中山网站建设十堰网站建设

Jupyter Notebook转PDF或HTML分享研究成果在深度学习项目开发中,一个常见的挑战是:如何让辛苦跑出来的实验结果不仅能在自己的GPU服务器上重现࿰

2026/06/30 11:31:26