老板:改了数据库,整整齐齐了。转载本文请联系味觉小姐公众号。经过千辛万苦的开发,系统终于上线了,进入了更加惊险刺激的抓bug阶段。在修修补补的过程中,我们需要清理数据库,才能给后代留下一堆狗屎。想一想,我们在开发环境修改了多个字段的名称,经历了测试环境的洗礼,甚至还设置了pre-launch来接受变化。结果,就是忘了在线上操作其中一个SQL,之前的努力都白费了。如果你做的是项目型的工作,而客户每六个月才升级一次,那么这些脚本的管理就会变得更加混乱。我们需要使用git等工具来管理这些数据库的变化,可以在系统启动时自动更改。口口相传,太不可思议了。没有人愿意承担责任。翻聊天记录?有用吗?这都是事后的事。人和动物的区别在于工具的使用。经常使用的两个是Liquibase和Flyway。但是,Liquibase的迁移脚本写起来太复杂,维护起来也很费时间,远不如Flyway的开箱即用(牺牲了跨平台)。如果你的项目不是很复杂,不熟悉Liquibase,建议直接选择flyway。一般对数据库的改动有如下几种语句,我们可以使用flyway来完成。DDL建表、建索引时,使用的语句,如CREATE、ALTER、DROP等。DML是一些常用的数据操作语句,如update、delete、insertDCL语句,用于设置和管理权限信息,如grant、Deny、revoke等。下面以flyway为例,看看数据库的版本是如何变化的。1.flywaymigrate首先使用mvn命令创建一个演示工程。mvnarchetype:生成-B\-DarchetypeGroupId=org.apache.maven.archetypes\-DarchetypeArtifactId=maven-archetype-quickstart\-DarchetypeVersion=1.1\-DgroupId=foo\-DartifactId=bar\-Dversion=1.0-SNAPSHOT\-Dpackage=foobar在pom.xml文件中添加如下内容:org.flywaydbflyway-maven-plugin7??.3.1jdbc:h2:file:./target/foobarsacom.h2database/groupId>h21.4.200创建数据库更改目录。mkdir-psrc/main/resources/db/migration创建新的数据库文件,我们称之为版本一:src/main/resources/db/migration/V1__Create_person_table.sqlcreatetablePERSON(IDintnotnull,NAMEvarchar(100)notnull);使用mvn命令完成数据库更新。不要害怕,这个命令是幂等的。mvnflyway:migrate终端将输出以下内容:[INFO]Database:jdbc:h2:file:./target/foobar(H21.4)[INFO]Successfullyvalidated1migration(executiontime00:00.009s)[INFO]CreatingSchemaHistorytable:"PUBLIC"."flyway_schema_history"[INFO]Currentversionofschema"PUBLIC":<>[INFO]Migratingschema"PUBLIC"toversion1-Createpersontable[INFO]Successfullyapplied1migrationtoschema"PUBLIC"(executiontime00:00.038s)接下来,我们准备第二次更改,同样,我们创建文件的第二个版本:src/main/resources/db/migration/V2__Add_people.sql以下是SQL文件的内容:insertintoPERSON(ID,NAME)values(1,'Axel');insertintoPERSON(ID,NAME)values(2,'Mr.Foo');insertintoPERSON(ID,NAME)values(3,'Ms.Bar');再次执行mvnflyway:migrate,可以发现第二版的DML信息已经写入数据库。2.它是如何工作的?flyway是如何做到幂等的?我们使用DBeaver打开这个h2文件。在JDBC连接处,输入:jdbc:h2:/private/tmp/bar/target/foobar.mv.db;然后选择H2嵌入式模式。我们发现除了用户创建的PERSON表外,数据库中多了一张表flyway_schema_history。让我们看看里面有什么。使用mvnflyway:info命令,可以看到同样的内容。可见,这种幂等操作实际上是由一张自动创建的状态表来保证的。其中还有一个名为校验和的字段。liman存储了一个CRC32值,用来判断你的SQL文件是否被非法篡改(篡改后不会通过)。戳破这层窗户纸后,所有神奇的事情顿时变得清晰起来。所以如果要使用flyway,你的账号至少要有创建表的权限,否则需要手动创建这种表。从上面的SQL文件定义也可以看出,这些文件需要遵循一定的规则。大致如上图所示,包括:PrefixVersionnumberSeparatorVersiondescriptionflyway就是靠这个约定来改变库表的。因此,需要严格按照其要求对Sql文件进行命名。3、SpringBoot项目集成将flyway的坐标添加到pom.xml中。可以看出我们没有提供版本号,说明在bom文件中已经定义好了。而它的autoconfigure是在SpringBoot的autoconfigure包中默认提供的。org.flywaydbflyway-core...当然我们要看定义在FlywayProperties文件。可以看到它的前缀是spring.flyway。默认的DB变更文件放在classpath:db/migration,我们也可以通过locations配置自定义一个,比如classpath:cn/xjjdog/flyway。当然你也可以通过table属性来定义his表的名字。也可以提供URL、用户、密码等,his表和business表存放在不同的地方。如果不提供,默认使用datasource定义的库。所以,最低配置就是什么都不做,直接把change文件丢到change目录下。spring:datasource:#jdbcconfiguration...flyway:enable:truelocations:classpath:cn/xjjdog/flywayEnd寸金寸金,寸金难买寸光阴。久而久之,代码和sql就会变得一团糟。如何让我们的工程师在软件生命周期结束前过上更幸福的生活,才是我们应该做的。作者简介:品味小姐姐(xjjdog),一个不允许程序员走弯路的公众号。专注于基础架构和Linux。十年架构,每天百亿流量,与你探讨高并发世界,给你不一样的滋味。我的个人微信xjjdog0,欢迎加好友进一步交流。