如何获取vertica中最后发布的序列ID?
How can I get the last issued sequence ID in vertica?
背景: 我正在从 postgreSQL 迁移到 Vertica,发现 IDENTITY
或 AUTO_INCREMENT
列中存在一些问题。其中一个问题是,vertica 无法将值分配给 IDENTITY
列或更改已将数据放入 IDENTITY
列的列。因此我创建了一个序列并将列的默认值设置为唯一的:
SELECT MAX(id_column) FROM MY_SCHEMA.my_table;
也就是 12345
CREATE SEQUENCE MY_SCHEMA.seq_id_column MINVALUE 12346 CACHE 1;
ALTER TABLE MY_SCHEMA.my_table
ALTER COLUMN id_column SET DEFAULT(MY_SCHEMA.seq_id_column.nextval);
ALTER TABLE MY_SCHEMA.log ADD UNIQUE(id_column);
按预期工作。在这种情况下,我停用了缓存,因为我在单节点安装上并且我希望我的 ID 列是连续的。但是,这不是集群安装的一个选项,因为所需的锁会导致瓶颈。
问题:在具有多个节点的vertica集群中,如何访问会话中最后插入的ID(无需额外select)?
例如在 postgreSQL 中我可以做类似
的事情
INSERT INTO MY_SCHEMA.my_table RETURNING id_column;
这在 Vertica 中不起作用。此外,Vertica 的 LAST_INSERT_ID()
函数不适用于命名序列。我也觉得,查询 MY_SCHEMA.seq_id_column
的 current_value
可能会由于缓存而给出错误的结果,但我不确定这一点。
为什么没有额外的SELECT?
据我所知,select 只会在提交后给出正确的值。由于性能原因,我无法在每次插入后都进行提交。
LukStorms 的评论为我指明了正确的方向。
NEXTVAL()
函数(据我测试)在这种情况下给出了连续的值,其中一个会话查询它们。此外,在并发访问中,如果在插入之后发出,CURRVAL
检索缓存值,保证唯一但不一定连续。因为我从来没有像在我的默认子句中那样在其他任何地方调用 NEXTVAL
,所以这解决了我的问题,尽管可能存在这样的情况,即在插入之间对 NEXTVAL
的额外调用会增加序列计数器。
我能想到的一个案例(我将在未来测试)是如果 AUTO COMMIT
设置为 OFF
,默认情况下是 ON
vertica 客户端驱动程序。
更新:
这甚至似乎与 AUTOCOMMIT
一起使用 OFF
(使用 vertica-python
客户端驱动程序显示,其中 C
是连接,cur
光标):
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.fetchall()
--> 1
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 1
cur.execute("SET SESSION AUTOCOMMIT TO OFF")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 4
然而,这似乎在连接回滚期间没有改变。所以会发生以下情况:
C.rollback()
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 4
背景: 我正在从 postgreSQL 迁移到 Vertica,发现 IDENTITY
或 AUTO_INCREMENT
列中存在一些问题。其中一个问题是,vertica 无法将值分配给 IDENTITY
列或更改已将数据放入 IDENTITY
列的列。因此我创建了一个序列并将列的默认值设置为唯一的:
SELECT MAX(id_column) FROM MY_SCHEMA.my_table;
也就是 12345
CREATE SEQUENCE MY_SCHEMA.seq_id_column MINVALUE 12346 CACHE 1;
ALTER TABLE MY_SCHEMA.my_table
ALTER COLUMN id_column SET DEFAULT(MY_SCHEMA.seq_id_column.nextval);
ALTER TABLE MY_SCHEMA.log ADD UNIQUE(id_column);
按预期工作。在这种情况下,我停用了缓存,因为我在单节点安装上并且我希望我的 ID 列是连续的。但是,这不是集群安装的一个选项,因为所需的锁会导致瓶颈。
问题:在具有多个节点的vertica集群中,如何访问会话中最后插入的ID(无需额外select)?
例如在 postgreSQL 中我可以做类似
的事情INSERT INTO MY_SCHEMA.my_table RETURNING id_column;
这在 Vertica 中不起作用。此外,Vertica 的 LAST_INSERT_ID()
函数不适用于命名序列。我也觉得,查询 MY_SCHEMA.seq_id_column
的 current_value
可能会由于缓存而给出错误的结果,但我不确定这一点。
为什么没有额外的SELECT?
据我所知,select 只会在提交后给出正确的值。由于性能原因,我无法在每次插入后都进行提交。
LukStorms 的评论为我指明了正确的方向。
NEXTVAL()
函数(据我测试)在这种情况下给出了连续的值,其中一个会话查询它们。此外,在并发访问中,如果在插入之后发出,CURRVAL
检索缓存值,保证唯一但不一定连续。因为我从来没有像在我的默认子句中那样在其他任何地方调用 NEXTVAL
,所以这解决了我的问题,尽管可能存在这样的情况,即在插入之间对 NEXTVAL
的额外调用会增加序列计数器。
我能想到的一个案例(我将在未来测试)是如果 AUTO COMMIT
设置为 OFF
,默认情况下是 ON
vertica 客户端驱动程序。
更新:
这甚至似乎与 AUTOCOMMIT
一起使用 OFF
(使用 vertica-python
客户端驱动程序显示,其中 C
是连接,cur
光标):
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.fetchall()
--> 1
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 1
cur.execute("SET SESSION AUTOCOMMIT TO OFF")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 4
然而,这似乎在连接回滚期间没有改变。所以会发生以下情况:
C.rollback()
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 4