Последовательности в Phoenix
Обзор
Последовательность — это объект, последовательно генерирующий монотонно возрастающий или убывающий ряд целых чисел согласно заданным условиям. Такие ряды в основном используются для создания идентификаторов, но могут использоваться и в иных целях. Последовательности могут принадлежать или не принадлежать схемам.
Создание последовательности
Для создания последовательности используется следующий синтаксис:
CREATE SEQUENCE [IF NOT EXISTS] {[<schema_name>.]<sequence_name>}
[START [WITH] <number>]
[INCREMENT [BY] <number>]
[MINVALUE <number>]
[MAXVALUE <number>]
[CYCLE]
[CACHE <number>];| Параметр или ключевое слово | Описание | 
|---|---|
| IF NOT EXISTS | Попытка создания последовательности с именем уже существующей последовательности без этого ключевого слова приведет к выводу на экран сообщения об ошибке. По умолчанию не используется | 
| schema_name | Имя схемы, которой принадлежит последовательность | 
| sequence_name | Имя последовательности | 
| START (WITH) | Значение начала последовательности. Оно возвращается в качестве первого значения, генерируемого последовательностью. Это значение должно находиться в промежутке, заданном значениями ключевых слов  | 
| number | Численное значение, требуемое для ключевых слов  | 
| INCREMENT (BY) | Значение шага возрастания или убывания последовательности. Оно добавляется к текущему значению последовательности для получения следующего значения. Ключевое слово  | 
| MINVALUE | Минимальное значение последовательности. Используется в качестве предельной точки для убывающих последовательностей, а также начальной точки для возрастающих последовательностей, использующих зацикливание после достижения максимального значения. Значение по умолчанию:  | 
| MAXVALUE | Максимальное значение последовательности. Используется в качестве предельной точки для возрастающих последовательностей, а также начальной точки для убывающих последовательностей, использующих зацикливание после достижения минимального значения. Значение по умолчанию:  | 
| CYCLE | Определяет, нужно ли при выходе за пределы заданного промежутка зациклить последовательность, то есть продолжать её от минимального значения (или от максимального для убывающих последовательностей), или выдать ошибку. По умолчанию не используется | 
| CACHE | Размер порции последовательных значений, хранящихся на стороне клиента, по исчерпании которых он сможет запросить следующую порцию с сервера. Одну и ту же последовательность могут использовать несколько клиентов. Каждый раз, когда любой из клиентов запрашивает новую порцию значений, он будет получать следующую в очереди. Значение по умолчанию:  | 
| ПРИМЕЧАНИЕПоследовательности в Phoenix используют только тип BIGINTдля возвращаемых значений (от-9223372036854775808до9223372036854775807). | 
Пример:
CREATE SEQUENCE IF NOT EXISTS test_schema.test_sequence
START WITH 97 INCREMENT BY 2 MINVALUE 0 MAXVALUE 100 CYCLE CACHE 50;Эта команда создает последовательность, которая вернет 97 в качестве первого значения, затем 99, а после этого будет циклично возвращать четные числа от 0 до 100 в возрастающем порядке. Первые 50 значений будут храниться на стороне клиента и последовательно возвращаться согласно исполняемым запросам, а после их исчерпания будут запрошены следующие 50 значений с сервера.
Удаление последовательности
Для удаления последовательности используется следующий синтаксис:
DROP SEQUENCE [IF EXISTS] <sequence_ref>;где <sequence_ref> — точное название последовательности, как оно было указано при изначальном её создании. Если последовательность принадлежит схеме, то её тоже нужно указать в этой команде.
Пример:
DROP SEQUENCE IF EXISTS test_schema.test_sequence;Получение новых значений
Для получения нового значения последовательности используется выражение NEXT VALUE FOR с указанием имени последовательности в командах SELECT и UPSERT VALUES. Последовательность, вызываемая в первый раз, возвращает начальное значение (заданное ключевым словом или по умолчанию).
Команда UPSERT VALUES
Например, чтобы создать таблицу и наполнить её значениями, используя последовательность для генерации первичных ключей, нужно выполнить следующие команды:
CREATE TABLE weapon_types (
id INTEGER NOT NULL PRIMARY KEY,
wpn_type VARCHAR(50),
ammo_type VARCHAR(50));
CREATE SEQUENCE IF NOT EXISTS test_schema.test_sequence START 1 INCREMENT 1;
UPSERT INTO weapon_types(id, wpn_type, ammo_type) VALUES (NEXT VALUE FOR test_schema.test_sequence, 'handgun', 'bullet');
UPSERT INTO weapon_types(id, wpn_type, ammo_type) VALUES (NEXT VALUE FOR test_schema.test_sequence, 'shotgun', 'buckshot');
UPSERT INTO weapon_types(id, wpn_type, ammo_type) VALUES (NEXT VALUE FOR test_schema.test_sequence, 'shotgun', 'slug');
UPSERT INTO weapon_types(id, wpn_type, ammo_type) VALUES (NEXT VALUE FOR test_schema.test_sequence, 'assault rifle', 'bullet');
UPSERT INTO weapon_types(id, wpn_type, ammo_type) VALUES (NEXT VALUE FOR test_schema.test_sequence, 'sniper rifle', 'bullet');
UPSERT INTO weapon_types(id, wpn_type, ammo_type) VALUES (NEXT VALUE FOR test_schema.test_sequence, 'crossbow', 'arrow');
SELECT * FROM weapon_types;Результат:
+----+---------------+-----------+ | ID | WPN_TYPE | AMMO_TYPE | +----+---------------+-----------+ | 1 | handgun | bullet | | 2 | shotgun | buckshot | | 3 | shotgun | slug | | 4 | assault rifle | bullet | | 5 | sniper rifle | bullet | | 6 | crossbow | arrow | +----+---------------+-----------+
Команда SELECT
Для загрузки значений из одной таблицы в другую с помощью одной команды UPSERT можно использовать команду SELECT. Например, чтобы создать таблицу, содержащую типы боеприпасов из ранее созданной таблицы, используя последовательность для генерации первичных ключей, нужно выполнить следующие команды:
CREATE TABLE ammo_types (
id INTEGER NOT NULL PRIMARY KEY,
ammo_type VARCHAR(50));
CREATE SEQUENCE IF NOT EXISTS test_schema.test_sequence2 START 1 INCREMENT 1;
UPSERT INTO ammo_types(id, ammo_type)
SELECT NEXT VALUE FOR test_schema.test_sequence2, ammo_type
FROM weapon_types
GROUP BY ammo_type;
SELECT * FROM ammo_types;Результат:
+----+-----------+ | ID | AMMO_TYPE | +----+-----------+ | 1 | arrow | | 2 | buckshot | | 3 | bullet | | 4 | slug | +----+-----------+
Просмотр последнего значения
Для просмотра последнего значения, сгенерированного последовательностью, используйте в команде SELECT выражение CURRENT VALUE FOR с указанием имени последовательности. Пример:
SELECT CURRENT VALUE FOR test_schema.test_sequence;Результат:
+---------------------------------------------+ | CURRENT VALUE FOR TEST_SCHEMA.TEST_SEQUENCE | +---------------------------------------------+ | 4 | +---------------------------------------------+
| ПРИМЕЧАНИЕЭта команда вернет сообщение об ошибке, если последовательность еще ни разу не вызывалась для генерации значений. | 
Если выражение CURRENT VALUE FOR используется совместно с выражением NEXT VALUE FOR для одной и той же последовательности в рамках одной команды, они оба вернут одно и то же вновь сгенерированное значение.
Просмотр информации о последовательности
Для просмотра информации о всех последовательностях выполните следующую команду:
SELECT * FROM SYSTEM."SEQUENCE";Результат:
+-----------+-----------------+---------------+------------+---------------+--------------+------------+----------------------+---------------------+------------+--------------------+ | TENANT_ID | SEQUENCE_SCHEMA | SEQUENCE_NAME | START_WITH | CURRENT_VALUE | INCREMENT_BY | CACHE_SIZE | MIN_VALUE | MAX_VALUE | CYCLE_FLAG | LIMIT_REACHED_FLAG | +-----------+-----------------+---------------+------------+---------------+--------------+------------+----------------------+---------------------+------------+--------------------+ | | TEST_SCHEMA | TEST_SEQUENCE | 1 | 101 | 1 | 100 | -9223372036854775808 | 9223372036854775807 | false | false | +-----------+-----------------+---------------+------------+---------------+--------------+------------+----------------------+---------------------+------------+--------------------+
Обратите внимание, что значение столбца CURRENT_VALUE для последовательности равно 101. Причина этого в том, что размер порции значений равен 100 (столбец CACHE_SIZE) и первые 100 значений уже были отправлены клиенту. Если создать еще одну сессию подключения к Phoenix Query Server, она будет рассматриваться как новый клиент. Если в этом случае запросить следующее значение этой же последовательности, будет сгенерировано значение 101, а значение столбца CURRENT_VALUE станет равным 201. После исчерпания клиентом своей порции значений он получит следующую с сервера. Начальное значение этой порции будет зависеть от того, сколько порций было передано ранее другим клиентам.
Таблица SYSTEM.SEQUENCE доступна только для чтения.
Особенности использования последовательностей
При использовании последовательностей имейте в виду следующее:
- 
После создания последовательности изменить ее нельзя. 
- 
Выражения NEXT VALUE FORиCURRENT VALUE FORмогут использоваться только командамиSELECTиUPSERT VALUES. Использование этих выражений в командахWHERE,GROUP BY,HAVINGилиORDER BYприведет к ошибке.
- 
Выражение NEXT VALUE FORгенерирует новое значение только один раз для одной командыSELECTилиUPSERT. Например, используется команда следующего вида:UPSERT INTO test_table(c1,c2) VALUES (NEXT VALUE FOR some_sequence, NEXT VALUE FOR some_sequence);В этом случае значения в обоих столбцах будут одинаковы.