通过自定义函数实现postgres主键ID自增

一、背景

考虑业务连续性,新项目使用postgres数据库。从mysql数据库换到postgres很多地方不熟悉,之前常用的在表中增加一个自增 id 做主键,在mysql中建表时可以直接设置自增,postgres没有这种功能。postgres中可以设置序列,但发现序列自增时不会绕过已有的 id,如果谁手动在数据库插入了一条数据,设置了一个大一些的id,后面再插入数据使用序列自增的话,会报主键id重复,插入失败。

二、解决方案

1、创建一个测试表t_user.

t_user表有两个字段, id是int4类型的, name是字符串。id设置为主键。

2、自定义一个函数,返回id的最大值+1.

为了让函数通用一点,传入两个参数:表名和字段名。这样后面所有的表都可以用这个函数。

CREATE OR  REPLACE FUNCTION self_increment_id(table_name TEXT, field_name TEXT) 
RETURNS INTEGER AS $BODY$

DECLARE 
new_id INTEGER;

BEGIN
	EXECUTE format('SELECT CASE COUNT(1)
	                WHEN 0 THEN 1
	                ELSE MAX(%s) + 1 END 
					FROM %s ;', field_name, table_name) INTO new_id;
	RETURN new_id;
END
$BODY$

LANGUAGE 'plpgsql';

在这个函数里面判断了表是否为空,如果是空表返回1,否则返回 id 的最大值+1。这样它的行为跟mysql的自增 id 就比较类似了,还有一个差别是mysql会记住用过的id,数据删除后,id也不会再重复使用了;这个函数会回收再用,大部分情况下对业务没什么影响。

3、使用函数来指定id的默认值

在这里插入图片描述
我用的客户端工具是Navicat。

可以看一下表的DDL, id默认值指定为了一个函数:

CREATE TABLE "public"."t_user" (
  "id" int4 NOT NULL DEFAULT self_increment_id('t_user'::text, 'id'::text),
  "name" varchar(255) COLLATE "pg_catalog"."default" NOT NULL DEFAULT ''::character varying,
  CONSTRAINT "t_user_pkey" PRIMARY KEY ("id")
)
;

ALTER TABLE "public"."t_user" 
  OWNER TO "postgres";

COMMENT ON COLUMN "public"."t_user"."id" IS '自增ID';

COMMENT ON COLUMN "public"."t_user"."name" IS '姓名';

4、测试一下

在t_user表中录入数据,只输入name,不输入id。
在这里插入图片描述

提交后,id默认设置为当前最大值+1:
在这里插入图片描述

发布了113 篇原创文章 · 获赞 183 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/ylforever/article/details/96556744