背景:我从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(无其他选择)?
例如在postgreSQL中,我可以做类似的事情
INSERT INTO MY_SCHEMA.my_table RETURNING id_column;
在Vertica中不起作用。此外,Vertica的LAST_INSERT_ID()
函数不适用于命名序列。我还感到,由于缓存,查询current_value
的{{1}}可能会给出错误的结果,但是我不确定。
为什么没有其他选择?
据我所知,选择仅会在提交后给出正确的值。由于性能原因,我无法在每次插入后进行提交。
答案 0 :(得分:1)
LukStorms的评论为我指明了正确的方向。
NEXTVAL()
函数(据我所测试)在连续的情况下给出了一个连续的值,即单个会话查询它们。此外,在并发访问时,如果在插入之后发出,CURRVAL
将检索缓存的值,该值可以保证是唯一的,但不一定是连续的。由于我从未像在默认子句中那样在其他任何地方调用过NEXTVAL
,所以这为我解决了这个问题,尽管在某些情况下,插入之间对NEXTVAL
的附加调用会增加序列计数器。
我可以想到的一种情况(以后将进行测试)是将AUTO COMMIT
设置为OFF
的情况,对于vertica客户端,默认设置为ON
驱动程序。
更新:
这似乎在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