Последовательности в Phoenix

Обзор

Последовательность — это объект, последовательно генерирующий монотонно возрастающий или убывающий ряд целых чисел согласно заданным условиям. Такие ряды в основном используются для создания идентификаторов, но могут использоваться и в иных целях. Последовательности могут принадлежать или не принадлежать схемам.

Создание последовательности

Для создания последовательности используется следующий синтаксис:

CREATE SEQUENCE [IF NOT EXISTS] {[<schema_name>.]<sequence_name>}
[START [WITH] <number>]
[INCREMENT [BY] <number>]
[MINVALUE <number>]
[MAXVALUE <number>]
[CYCLE]
[CACHE <number>];
Параметры и ключевые слова команды CREATE SEQUENCE
Параметр или ключевое слово Описание

IF NOT EXISTS

Попытка создания последовательности с именем уже существующей последовательности без этого ключевого слова приведет к выводу на экран сообщения об ошибке. По умолчанию не используется

schema_name

Имя схемы, которой принадлежит последовательность

sequence_name

Имя последовательности

START (WITH)

Значение начала последовательности. Оно возвращается в качестве первого значения, генерируемого последовательностью. Это значение должно находиться в промежутке, заданном значениями ключевых слов MINVALUE и MAXVALUE, включая граничные значения. Ключевое слово WITH необязательно (ни на что не влияет). Значение по умолчанию: 1

number

Численное значение, требуемое для ключевых слов START WITH, INCREMENT BY, MINVALUE, MAXVALUE и CACHE

INCREMENT (BY)

Значение шага возрастания или убывания последовательности. Оно добавляется к текущему значению последовательности для получения следующего значения. Ключевое слово BY необязательно (ни на что не влияет). Значение по умолчанию: 1

MINVALUE

Минимальное значение последовательности. Используется в качестве предельной точки для убывающих последовательностей, а также начальной точки для возрастающих последовательностей, использующих зацикливание после достижения максимального значения. Значение по умолчанию: -9223372036854775808

MAXVALUE

Максимальное значение последовательности. Используется в качестве предельной точки для возрастающих последовательностей, а также начальной точки для убывающих последовательностей, использующих зацикливание после достижения минимального значения. Значение по умолчанию: 9223372036854775807

CYCLE

Определяет, нужно ли при выходе за пределы заданного промежутка зациклить последовательность, то есть продолжать её от минимального значения (или от максимального для убывающих последовательностей), или выдать ошибку. По умолчанию не используется

CACHE

Размер порции последовательных значений, хранящихся на стороне клиента, по исчерпании которых он сможет запросить следующую порцию с сервера. Одну и ту же последовательность могут использовать несколько клиентов. Каждый раз, когда любой из клиентов запрашивает новую порцию значений, он будет получать следующую в очереди. Значение по умолчанию: 100. Оно может быть изменено вручную при помощи добавления параметра phoenix.sequence.cacheSize в секцию Custom hbase-site.xml страницы конфигурации сервиса HBase

ПРИМЕЧАНИЕ
Последовательности в 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);

    В этом случае значения в обоих столбцах будут одинаковы.

Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней