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

杭州蓝科信息技术有限公司 2026/09/09 18:56:34

关于数据库迁移


什么是数据库迁移


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

东莞网站建设宝山网站建设

Ubuntu系统进程调优与启动管理全解析在Ubuntu系统的使用过程中,了解系统进程的启动方式和如何进行调优是非常重要的。这不仅有助于我们理解系统的运行机制,还能帮助我们优化系统性能,解决一些潜在的问

2026/06/30 10:54:52

建设厅网站网站正在建设中

腾讯正式宣布开源混元大模型的FP8量化版本——Hunyuan-A13B-Instruct-FP8,该模型凭借创新的混合专家架构和高效量化技术,在仅激活130亿参数的情况下实

2026/06/30 13:01:34

律师网站建设襄樊网站建设

G-Helper:解锁华硕笔记本隐藏性能的智能调校利器【免费下载链接】g-helperLightweight Armoury Crate alternative for Asus lap

2026/06/30 12:08:29

网站建设集团网站建设及推广

异腾SGLang与vLLM-Ascend性能测评与调优指南性能测评与调优需要围绕模型推理速度、吞吐量、资源利用率等核心指标展开。以下是针对异腾SGLang和vLLM-Ascend的测评框架与调优方法。

2026/06/30 14:17:39

律师网站建设网站专业建设

QMC解码器使用指南:3步完成QQ音乐加密音频转换【免费下载链接】qmc-decoderFastest & best convert qmc 2 mp3 | flac tools

2026/06/30 11:43:28

免费网站建设贵州网站建设

随着微信生态流量的持续爆发,搭建专属微信店铺小程序已成为企业、创业者数字化转型的核心选择。但多数人困惑 “微信上怎么做自己的店铺小程序”,且担心定制化不足、后期无法拓展。象

2026/06/30 11:11:24

温州网站建设泸州网站建设

HeyGem是否支持并发任务?系统队列机制深度解析在AI数字人内容创作日益普及的今天,越来越多的企业和个人开始尝试批量生成口型同步视频。无论是制作系列课程、产品宣传

2026/06/30 11:03:53

邵阳网站建设商丘网站建设

开源机械臂控制平台完整指南:从入门到精通【免费下载链接】open_manipulatorOpenManipulator for controlling in Gazebo and Mov

2026/06/30 12:32:31

九江网站建设衡水网站建设

随着微服务架构的普及,企业 API 数量呈指数级增长。然而,安全策略若分散在各个服务中,将导致防护不一致、漏洞难管控、审计难追溯。API 网关作为流量统一入口

2026/06/30 11:46:57