👨🏻‍💻 OceanBase x Drizzle: serial 数据类型问题

问题背景

  • 在 Drizzle 中定义的users 业务表 schema 如下:
import { mysqlTable, serial, varchar } from "drizzle-orm/mysql-core";

export const usersTable = mysqlTable("users", {
  id: serial().primaryKey(),
  email: varchar({ length: 255 }).notNull().unique(),
  name: varchar({ length: 255 }).notNull(),
});
  • 对应的建表语句:
CREATE TABLE `users` (
	`id` serial AUTO_INCREMENT NOT NULL,
	`email` varchar(255) NOT NULL,
	`name` varchar(255) NOT NULL,
	CONSTRAINT `users_id` PRIMARY KEY(`id`),
	CONSTRAINT `users_email_unique` UNIQUE(`email`)
);

问题原因

  • 在官网搜索 serial 关键字,发现从 OB 4.2.3 版本开始才支持 SERIAL 数据类型。因此该问题本质是 OB 4.2.3 以下版本不兼容 MySQL 的 SERIAL 数据类型。

解决方案

:white_check_mark: 方案 1: 修改 OB 版本

:x: 方案 2: 修改 schema

  • 使用 bigint + autoincrement 代替 serial,用于声明自增 ID:
-import { mysqlTable, serial, varchar } from "drizzle-orm/mysql-core";
+import { mysqlTable, bigint, varchar } from "drizzle-orm/mysql-core";
 
 export const usersTable = mysqlTable("users", {
-  id: serial().primaryKey(),
+  id: bigint({ mode: "bigint" }).autoincrement().primaryKey(),
   email: varchar({ length: 255 }).notNull().unique(),
   name: varchar({ length: 255 }).notNull(),
 });
  • 对应的建表语句:
 CREATE TABLE `users` (
-   `id` serial AUTO_INCREMENT NOT NULL,
+   `id` bigint AUTO_INCREMENT NOT NULL,
    `email` varchar(255) NOT NULL,
    `name` varchar(255) NOT NULL,
    CONSTRAINT `users_id` PRIMARY KEY(`id`),
    CONSTRAINT `users_email_unique` UNIQUE(`email`)
 );

:white_check_mark: 方案 3: 修改 Drizzle 以避免触发 serial 的兼容性问题

 import { defineConfig } from "drizzle-kit";

 export default defineConfig({
   migrations: {
+    tableIdTable: 'bigint AUTO_INCREMENT', 
   },
 });
  • 迁移时 __drizzle_migrations 的建表语句:
 create table if not exists `__drizzle_migrations` (
-  id serial primary key,
+  id bigint AUTO_INCREMENT primary key,
   hash text not null,
   created_at bigint
 );