如何使 mysql 数据库模式与 h2 数据库兼容

how to make mysql database schema to be compatible with h2 database

我目前正在使用 mysql 作为我的数据库,并使用 flyway 来管理数据库模式。我所有的单元测试都是 运行ning 而不是 mysql 并且它们 运行ning 添加更多单元测试真的很慢。现在我想在单元测试中将数据库从 mysql 更改为 h2 内存数据库。以下是我对 h2 数据库连接的设置:

#Datasource
spring.datasource.url=jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=true
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.default-transaction-isolation-level=1

当我 运行 flywayMigrate 时,我遇到了一些 sql 错误。下面是一个示例,此 sql 用于在 mysql 上创建一个 table 但未能在 h2 上创建 运行。

CREATE TABLE `file_storage` (
  `id` BIGINT(64) NOT NULL AUTO_INCREMENT,
  `file_name` VARCHAR(45) NULL,
  PRIMARY KEY (`id`))
DEFAULT CHARACTER SET = utf8;

下面是我从 h2 得到的错误。我不知道我的 sql 有什么问题。有没有办法让 h2 接受 mysql 数据库模式?

Execution failed for task ':dbschema:flywayMigrate'.
> Error occurred while executing flywayMigrate

  Migration V2016_02_26_12_59__create_file_storage.sql failed
  -----------------------------------------------------------
  SQL State  : 42000
  Error Code : 42000
  Message    : Syntax error in SQL statement "CREATE TABLE ""FILE_STORAGE"" (
    ""ID"" BIGINT(64) NOT NULL AUTO_INCREMENT,
    ""FILE_NAME"" VARCHAR(45) NULL,
    PRIMARY KEY (""ID""))
  DEFAULT CHARACTER[*] SET = UTF8 "; SQL statement:
  CREATE TABLE `file_storage` (
    `id` BIGINT(64) NOT NULL AUTO_INCREMENT,
    `file_name` VARCHAR(45) NULL,
    PRIMARY KEY (`id`))
  DEFAULT CHARACTER SET = utf8 [42000-190]
  Location   : db/migration/V2016_02_26_12_59__create_file_storage.sql (/Users/yzzhao/dev/cooltoo/cooltoo_backend/dbschema/build/resources/main/db/migration/V2016_02_26_12_59__create_file_storage.sql)
  Line       : 1
  Statement  : CREATE TABLE `file_storage` (
    `id` BIGINT(64) NOT NULL AUTO_INCREMENT,
    `file_name` VARCHAR(45) NULL,
    PRIMARY KEY (`id`))
  DEFAULT CHARACTER SET = utf8

  Syntax error in SQL statement "CREATE TABLE ""FILE_STORAGE"" (
    ""ID"" BIGINT(64) NOT NULL AUTO_INCREMENT,
    ""FILE_NAME"" VARCHAR(45) NULL,
    PRIMARY KEY (""ID""))
  DEFAULT CHARACTER[*] SET = UTF8 "; SQL statement:
  CREATE TABLE `file_storage` (
    `id` BIGINT(64) NOT NULL AUTO_INCREMENT,
    `file_name` VARCHAR(45) NULL,
    PRIMARY KEY (`id`))
  DEFAULT CHARACTER SET = utf8 [42000-190]

编辑

我有数百个 sql 脚本,在 mysql 中 运行 没问题。所以我不想更改这些脚本中的任何内容。有没有办法让 h2 接受 mysql 脚本?

根据this的描述,您可以尝试在MySQL兼容模式下使用您的H2数据库,方法是在连接字符串中将其设置为MODE=MySQL。这正是关于它的说法:

To use the MySQL mode, use the database URL jdbc:h2:~/test;MODE=MySQL or the SQL statement SET MODE MySQL.

  • When inserting data, if a column is defined to be NOT NULL and NULL is inserted, then a 0 (or empty string, or the current timestamp for timestamp columns) value is used. Usually, this operation is not allowed and an exception is thrown.

  • Creating indexes in the CREATE TABLE statement is allowed using INDEX(..) or KEY(..). Example: create table test(id int primary key, name varchar(255), key idx_name(name));

  • Meta data calls return identifiers in lower case.

  • When converting a floating point number to an integer, the fractional digits are not truncated, but the value is rounded.

  • Concatenating NULL with another value results in the other value.

Text comparison in MySQL is case insensitive by default, while in H2 it is case sensitive (as in most other databases). H2 does support case insensitive text comparison, but it needs to be set separately, using SET IGNORECASE TRUE. This affects comparison using =, LIKE, REGEXP.

你的问题可以通过你的例子看出

CREATE TABLE `file_storage`
(
   'id` BIGINT(64) NOT NULL AUTO_INCREMENT, 
   `file_name` VARCHAR(45) NULL, 
   PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET = utf8;

最后一行 "DEFAULT CHARACTER SET = utf8" 设置 mySQL table 选项。 H2 在 table 或架构级别没有这样的选项,因为它始终使用 Unicode 运行。

如果您有很多 SQL 多年来为 MySQL 编写的 DDL 语句,您可能会看到很多此类问题。