Как я могу получить последний выданный идентификатор последовательности в 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);

Что работает, как ожидалось. В этом случае у меня деактивирован кеш, поскольку я использую установку с одним узлом, и я хочу, чтобы мой столбец идентификатора был непрерывным. Однако это не вариант для кластерной установки, поскольку необходимая блокировка ведет к узкому месту.

Вопрос: В кластере Vertica с несколькими узлами, как я могу получить доступ к идентификатору последней вставки в сеансе (без дополнительного выбора)?

Например. в postgreSQL я мог бы сделать что-то вроде

INSERT INTO MY_SCHEMA.my_table RETURNING id_column;

который не работает в Vertica. Кроме того, функция Vertica LAST_INSERT_ID() не работает для названных последовательностей. Я также считаю, что запрос current_value из MY_SCHEMA.seq_id_column может давать неправильные результаты из-за кеширования, но я не уверен в этом.

Почему без дополнительного SELECT?

Насколько мне известно, выбор даст правильные значения только после фиксации. Я не могу делать коммит после каждой вставки из-за производительности.

Вы проверяли системную таблицу ПОСЛЕДОВАТЕЛЬНОСТИ? Также не могли бы вы описать, чего вы пытаетесь достичь, получая последний идентификатор вставки?

Dmitry Shaldin 31.07.2018 06:24

Как уже упоминалось, SEQUENCES не поддерживают LAST_INSERT_ID, и я боюсь попасть в состояние гонки при запросе таблицы SEQUENCES. Я просто хочу иметь первичный ключ последней вставленной записи в сеансе.

Dschoni 01.08.2018 12:06

Интересно, подойдет ли для этого CURRVAL? F.e. CURRVAL(MY_SCHEMA.seq_id_column). Справка. Да ладно, вы беспокоитесь об эффекте кеширования. Уходит

LukStorms 19.08.2018 22:14

@LukStorms На самом деле, это так. Я пробовал это с двумя параллельными сеансами, и каждый сеанс дает мне правильное (кешированное) значение. Если вы добавите свой комментарий в качестве ответа, вы получите награду.

Dschoni 20.08.2018 12:00

Спасибо, но, хотя это заманчиво, я пропущу это. Это было бы неправильно. Все, что я сделал, это поискал документацию, основанную на предыдущем опыте работы с другими распределенными СУБД. У меня нет доступа к Vertica. И мне не нравится публиковать ответы, которые я не могу проверить или не знаю, сработает наизусть. Поскольку вы выполнили основную работу, протестировав его, и никто другой не дал достойного ответа, то эти баллы также могут быть возвращены вам. Может быть, вы даже могли бы опубликовать свой собственный ответ. Поскольку сама проблема может быть полезна для других, кто когда-нибудь столкнется с той же проблемой.

LukStorms 20.08.2018 12:42
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
3
5
715
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Комментарии 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

Интересно. Я как бы ожидал чего-то подобного, что значение последовательности не будет отменено. И я предполагаю, что вы продолжаете стремиться к количеству. Но, возможно, вы могли бы сохранить стоимость до транзакции. Или получите значение MAX из таблицы. И ИЗМЕНИТЬ последовательность ПЕРЕЗАПУСКОМ после отката? Ссылка здесь

LukStorms 20.08.2018 17:40

Насколько я понимаю, непрерывные числа приводят к возникновению узких мест из-за глобальных блокировок. Я готов пожертвовать непрерывностью в пользу производительности.

Dschoni 20.08.2018 17:53

Другие вопросы по теме