一、创建自增主键
1. MySQL 创建自增主键sql:
CREATE TABLE test (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
2. PostgreSQL 创建自增主键sql:
CREATE TABLE test(
id serial8,
CONSTRAINT "test_primary_key" PRIMARY KEY ("id")
);
二、清空表时自增主键的变化
1. MySQL
mysql中如果需要清空表,只需要
TRUNCATE table_name;
即可,如果有自增的 id 字段,也会自动还原回 1 。
2. PostgreSQL
与 mysql 稍有不同,postgresql 的自增字段 是通过 序列 sequence来实现的,
所以在清空表的时候,还需要还原序列:
-------------- identity ------------
TRUNCATE TABLE 表名 RESTART IDENTITY;
-------------- serial --------------
ALTER SEQUENCE 表序列 restart with 1;
三、PostgreSQL 设置自增id从表最大值开始
sequence,serial,identity共同的缺点是在显式插入之后,无法将自增值更新为表中的最大Id,这一点再显式插入的情况下是潜在自增字段Id冲突的。
结论:自增列在显式插入之后,一定要手动重置为表的最大Id。
执行sql语句如下,将下列语句中的 tablename 换成具体的表名即可:
select setval('tablename_id_seq', (select max(id) from tablename));
批量生成SQL语句:
序列名通常为表名后加 “_id_seq”。为了达到本文的目的,我们先需要得到数据库中所有的表名,对应的查询语句如下:
SELECT tablename FROM pg_tables where tableowner='postgres' and SCHEMANAME='public'
得到了表名,我们就可以得到序列名,并针对序列进行修改,批量生成sql如下,注意数据库表owner和schema:
SELECT 'select setval('''||tablename||'_id_seq'||''', (select max(id) from '||tablename||'));'
FROM pg_tables where tableowner='postgres' and SCHEMANAME='public';
四、PostgreSQL 序列函数
下面序列函数,为我们从序列对象中获取最新的序列值提供了简单和并发读取安全的方法:
函数 | 返回类型 | 描述 |
nextval(regclass) | bigint | 递增序列对象到它的下一个数值并且返回该值。这个动作是自动完成的。即使多个会话并发运行nextval,每个进程也会安全地收到一个唯一的序列值。 |
currval(regclass) | bigint | 在当前会话中返回最近一次nextval抓到的该序列的数值。(如果在本会话中从未在该序列上调用过 nextval,那么会报告一个错误。)请注意因为此函数返回一个会话范围的数值,而且也能给出一个可预计的结果,因此可以用于判断其它会话是否执行过nextval。 |
lastval() | bigint | 返回当前会话里最近一次nextval返回的数值。这个函数等效于currval,只是它不用序列名为参数,它抓取当前会话里面最近一次nextval使用的序列。如果当前会话还没有调用过nextval,那么调用lastval将会报错。 |
setval(regclass, bigint) | bigint | 重置序列对象的计数器数值。设置序列的last_value字段为指定数值并且将其is_called字段设置为true,表示下一次nextval将在返回数值之前递增该序列。 |
setval(regclass, bigint, boolean) | bigint | 重置序列对象的计数器数值。功能等同于上面的setval函数,只是is_called可以设置为true或false。如果将其设置为false,那么下一次nextval将返回该数值,随后的nextval才开始递增该序列。 |
注意: 执行nextval会使得自增序列自动加一.