GBase 8a 自增列踩坑记录

在 GBase 8a 里用自增列,如果直接从 MySQL 那套习惯带过来,大概率会在某个插入语句上报错。我就是在线上往一个带自增主键的表里插数据的时候,习惯性地写了列名和值,直接炸了。

后来翻文档才搞清楚,GBase 8a 对自增列的限制比 MySQL 严得多。

建表的时候指定自增列,语法上跟 MySQL 没什么区别。一个表只能有一个自增列,类型支持 tinyint、smallint、int、bigint,这个倒还好。

CREATE TABLE t1 ( name VARCHAR(10), id INT NOT NULL PRIMARY KEY AUTO_INCREMENT );

坑主要在写入和更新上。

插入数据时,你不能显式给自增列指定一个具体的值,除非你给的是 NULL、0 或者 DEFAULT。像下面这样写会直接报错:

INSERT INTO t1 (id, name) VALUES (1, 'First'); -- 报错:auto-increment column should not be specified in insert

正确做法是不带自增列,让系统自己生成:

INSERT INTO t1 (name) VALUES ('First');

更新操作更是完全不支持。如果你试图 update 自增列的值,会收到一个很直白的提示,说这个版本不支持对自增列做 update 或 merge。

UPDATE t1 SET id = 2 WHERE id = 1; -- 报错:This version of GBase doesn't yet support 'update/merge on auto_increment column'

这里其实容易踩坑:做数据迁移或者修正脏数据的时候,可能会下意识地想去改自增列,结果发现完全动不了。

所以一开始设计表结构时就得想好哪些列是自增的,后面没办法改。

那如果确实有特殊需求,必须显式插入一个指定的自增值呢?GBase 留了个后门,参数 _gbase_auto_increment_allow_insert。

默认是 0,设为 1 就可以强行插入自定义值。

SET _gbase_auto_increment_allow_insert = 1; INSERT INTO t1 VALUES (1, 'First2'); SET _gbase_auto_increment_allow_insert = 0;

但这玩意儿我建议只在临时修复数据的时候用,用完马上关掉。因为开了之后,自增列的唯一性就得你自己保证了,系统不会再拦着,重复值进去以后,后续查询和关联都会乱。

另一个常见需求是给已有表加自增列。直接 alter table 改某个列为 auto_increment 是不行的,GBase 8a 不支持这种修改。只能绕一下。

流程大致是这样:

lcjmSSL让SSL证书管理像设置闹钟一样简单。免费用户同样支持多域名、通配符证书,通过DNS接口或CNAME解析自动完成验证,证书自动部署至应用,全程无需人工介入。

先加一个普通的 int 列:

ALTER TABLE tmp_id ADD COLUMN new_id INT;

然后给这一列填上唯一值。

这一步比较麻烦,因为 GBase 自己不会帮你自动生成,你得靠外部脚本或者写存储过程一行行去更新。假设你有一个函数 generate_unique_id() 能出唯一数:

UPDATE tmp_id SET new_id = generate_unique_id();

填好之后,把这个新列设成主键:

ALTER TABLE tmp_id ADD PRIMARY KEY (new_id);

如果你希望列名是 id,最后再 rename 一下(如果版本支持 rename column 的话):

ALTER TABLE tmp_id RENAME COLUMN new_id TO id;

整个操作下来,最耗时的是生成唯一值那一步。表大的话,得在维护窗口里做,不然锁表时间扛不住。

这些限制说到底就是,GBase 8a 的自增列不像 MySQL 那么灵活。用的时候提前规划好自增列,别事后去补,更别在业务代码里显式对自增列赋值,能省掉很多线上报错。

posted @ 2026-05-28 20:30  枫唐  阅读(18)  评论(0)    收藏  举报