Последовательности в 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);
В этом случае значения в обоих столбцах будут одинаковы.