diff --git a/ydb/docs/en/core/reference/ydb-cli/export-import/_includes/tools_dump.md b/ydb/docs/en/core/reference/ydb-cli/export-import/_includes/tools_dump.md index 81f69880854b..02f8494ab270 100644 --- a/ydb/docs/en/core/reference/ydb-cli/export-import/_includes/tools_dump.md +++ b/ydb/docs/en/core/reference/ydb-cli/export-import/_includes/tools_dump.md @@ -51,7 +51,7 @@ The `tools dump` command dumps the schema objects to the client file system in t - `database`: A fully consistent dump, with one snapshot taken before starting the dump. Applied by default. - `table`: Consistency within each dumped table, taking individual independent snapshots for each table. Might run faster and have less impact on the current workload processing in the database. -- `--avoid-copy`: Do not create a snapshot before dumping. The default consistency snapshot might be inapplicable in some cases (for example, for tables with external blobs). +- `--avoid-copy`: Do not create a snapshot before dumping. The default consistency snapshot might be inapplicable in some cases (for example, for tables with external blobs).{% if feature_serial %} For correct export of tables with [serial](../../../../yql/reference/types/serial.md) types, this parameter must not be set. Otherwise, the current value of the sequence generator will not be copied, and new values will start from the initial value, which may lead to primary key conflicts.{% endif %} - `--save-partial-result`: Retain the result of a partial dump. Without this option, dumps that terminate with an error are deleted. diff --git a/ydb/docs/en/core/yql/reference/syntax/alter-sequence.md b/ydb/docs/en/core/yql/reference/syntax/alter-sequence.md new file mode 100644 index 000000000000..0be90f9c76e2 --- /dev/null +++ b/ydb/docs/en/core/yql/reference/syntax/alter-sequence.md @@ -0,0 +1,60 @@ +# ALTER SEQUENCE + +Modifies the parameters of an existing `Sequence` object associated with a [Serial](../types/serial.md) column. + +## Syntax + +```yql +ALTER SEQUENCE [ IF EXISTS ] path_to_sequence + [ INCREMENT [ BY ] increment ] + [ START [ WITH ] start_value ] + [ RESTART [ [ WITH ] restart_value ]]; +``` + +## Parameters + +* `path_to_sequence` — the absolute path to the sequence object. + + The path is constructed as `/_serial_column_`, + where `` is the absolute path to the table, and `` is the name of the column with the `Serial` data type. + For example, for the column `user_id` in the table `/local/users`, the corresponding `Sequence` path will be `/local/users/_serial_column_user_id`. + +* `IF EXISTS` — when used, the statement does not return an error if the sequence does not exist at the specified path. + +* `INCREMENT [ BY ] increment` — sets the increment step for the sequence. Default: 1. + +* `START [ WITH ] start_value` — sets a new start value for the sequence. Changing this parameter with `ALTER SEQUENCE` does not affect the current value; the new start value is used with `ALTER SEQUENCE RESTART` if no value is specified. Default: 1. + +* `RESTART [ [ WITH ] restart_value ]` — sets the current sequence value to the specified `restart_value`. If no value is specified, it sets the current value to the start value. + +## Examples + +```yql +CREATE TABLE users ( + user_hash Uint64, + user_id Serial, + name Utf8, + email Utf8, + PRIMARY KEY (user_hash, user_id) +); +``` + +Change the increment step for `user_id` and set the current value to 1000: + +```yql +ALTER SEQUENCE `/Root/users/_serial_column_user_id` + INCREMENT BY 5 + RESTART 1000; +``` + +An alternative way to change the current value is to first set a new start value, and then `RESTART` the `Sequence`. After this, subsequent calls to `RESTART` without an explicit value will set the current value to 1000: + +```yql +ALTER SEQUENCE `/Root/users/_serial_column_user_id` INCREMENT BY 5 START WITH 1000; +ALTER SEQUENCE `/Root/users/_serial_column_user_id` RESTART; +``` + +## See also + +* [{#T}](create_table/index.md) +* [{#T}](../types/serial.md) \ No newline at end of file diff --git a/ydb/docs/en/core/yql/reference/syntax/create_table/index.md b/ydb/docs/en/core/yql/reference/syntax/create_table/index.md index 9988199ae81e..eb4fed6881ff 100644 --- a/ydb/docs/en/core/yql/reference/syntax/create_table/index.md +++ b/ydb/docs/en/core/yql/reference/syntax/create_table/index.md @@ -95,11 +95,11 @@ By default, if the `STORE` parameter is not specified, a row-oriented table is c {% if feature_column_container_type == true %} - For non-key columns, any data types are allowed, whereas for key columns only [primitive](../../types/primitive.md) types are permitted. When specifying complex types (for example, List), the type should be enclosed in double quotes. + For non-key columns, any data types are allowed, whereas for key columns only [primitive](../../types/primitive.md){% if feature_serial %} and [serial](../../types/serial.md){% endif %} types are permitted. When specifying complex types (for example, List), the type should be enclosed in double quotes. {% else %} - For both key and non-key columns, only [primitive](../../types/primitive.md) data types are allowed. + For both key and non-key columns, only [primitive](../../types/primitive.md){% if feature_serial %} and [serial](../../types/serial.md){% endif %} data types are allowed. {% endif %} diff --git a/ydb/docs/en/core/yql/reference/syntax/index.md b/ydb/docs/en/core/yql/reference/syntax/index.md index c792f5acb3ff..78dc5e38d68f 100644 --- a/ydb/docs/en/core/yql/reference/syntax/index.md +++ b/ydb/docs/en/core/yql/reference/syntax/index.md @@ -98,3 +98,9 @@ {% endif %} +{% if feature_serial %} + +* [ALTER SEQUENCE](alter-sequence.md) + +{% endif %} + diff --git a/ydb/docs/en/core/yql/reference/syntax/show_create.md b/ydb/docs/en/core/yql/reference/syntax/show_create.md index 8479ae57b265..d43c3ec67504 100644 --- a/ydb/docs/en/core/yql/reference/syntax/show_create.md +++ b/ydb/docs/en/core/yql/reference/syntax/show_create.md @@ -27,7 +27,7 @@ The command always returns **exactly one row** with three columns: - For tables: the main [CREATE TABLE](create_table/index.md) statement (with the path relative to the database root), plus any additional statements describing the current configuration, such as: - [ALTER TABLE ... ALTER INDEX](alter_table/secondary_index#alter-index) — for index partitioning settings. - [ALTER TABLE ... ADD CHANGEFEED](alter_table/changefeed.md) — for adding a changefeed. - - `ALTER SEQUENCE` — for restoring a `Sequence` state for `Serial` columns. + - [ALTER SEQUENCE](alter-sequence.md) — for restoring a `Sequence` state for [Serial](../types/serial.md) columns. - For views: the definition via [CREATE VIEW](create-view.md), and, if necessary, the statements the view has captured from the creation context, for example, [PRAGMA TablePathPrefix](pragma#table-path-prefix). diff --git a/ydb/docs/en/core/yql/reference/syntax/toc_i.yaml b/ydb/docs/en/core/yql/reference/syntax/toc_i.yaml index 5863cee93d6f..6a4bcd284651 100644 --- a/ydb/docs/en/core/yql/reference/syntax/toc_i.yaml +++ b/ydb/docs/en/core/yql/reference/syntax/toc_i.yaml @@ -9,6 +9,7 @@ items: - { name: ALTER VIEW, href: alter-view.md, when: feature_view } - { name: ALTER TOPIC, href: alter-topic.md, when: feature_topic_control_plane } - { name: ALTER USER, href: alter-user.md, when: feature_user_and_group } +- { name: ALTER SEQUENCE, href: alter-sequence.md, when: feature_serial } - { name: ANALYZE, href: analyze.md, when: backend_name == "YDB" } - { name: CREATE ASYNC REPLICATION, href: create-async-replication.md, when: feature_async_replication } - { name: CREATE GROUP, href: create-group.md, when: feature_user_and_group } diff --git a/ydb/docs/en/core/yql/reference/types/index.md b/ydb/docs/en/core/yql/reference/types/index.md index f1c2fbab3b20..95e4d1c7d217 100644 --- a/ydb/docs/en/core/yql/reference/types/index.md +++ b/ydb/docs/en/core/yql/reference/types/index.md @@ -3,6 +3,7 @@ This section contains articles on YQL data types: - [Simple/Primitive types](primitive.md) +{% if feature_serial %}- [Serial types](serial.md){% endif %} - [Optional types](optional.md) - [Containers](containers.md) - [Special types](special.md) diff --git a/ydb/docs/en/core/yql/reference/types/serial.md b/ydb/docs/en/core/yql/reference/types/serial.md new file mode 100644 index 000000000000..61a0b5b9ccfc --- /dev/null +++ b/ydb/docs/en/core/yql/reference/types/serial.md @@ -0,0 +1,95 @@ +# Serial Types + +Serial types are integer data types with an associated value-generation mechanism. They create auto-increment columns: each new row inserted into a table automatically generates a unique value for this column (similar to the [SERIAL](https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-SERIAL) type in PostgreSQL or the [AUTO_INCREMENT](https://dev.mysql.com/doc/refman/9.0/en/example-auto-increment.html) property in MySQL). + +## Description + +When a column of a serial type is defined, a separate schema object called a `Sequence` is created and bound to this column. This object is a private sequence generator and it is hidden from the user. The `Sequence` will be destroyed together with the table. + +The `Sequence` object supports several parameters that determine its behavior. These parameters can be altered after creation using the [ALTER SEQUENCE](../syntax/alter-sequence.md) command. + +By default, values generated by the `Sequence` start from one, are incremented by one with each new value, and are limited according to the chosen type. + +{% note info %} + +Serial columns are supported both for columns included in the primary key and for non-key columns. + +However, such columns cannot be [altered](../syntax/alter_table/family#mod-column-groups) or [dropped](../syntax/alter_table/columns.md) from the table — attempting to perform these operations will result in an error. + +{% endnote %} + +| Type | Maximum Value | Underlying Type | +|-------------|----------------------|----------| +| `SmallSerial` | $2^15–1$ | `Int16` | +| `Serial2` | $2^15–1$ | `Int16` | +| `Serial` | $2^31–1$ | `Int32` | +| `Serial4` | $2^31–1$ | `Int32` | +| `Serial8` | $2^63–1$ | `Int64` | +| `BigSerial` | $2^63–1$ | `Int64` | + +If a sequence reaches its maximum value, insertion results in an error: + +```text +Error: Failed to get next val for sequence: /dev/test/users/_serial_column_user_id, status: SCHEME_ERROR +
: Error: sequence [OwnerId: , LocalPathId: ] doesn't have any more values available, code: 200503 +``` + +{% note info %} + +The next value is allocated by the generator before the actual insertion into the table and is considered used even if the row is not successfully inserted (for example, in case of transaction rollback). +As a result, the values in such a column may have gaps and may not form a continuous sequence. + +{% endnote %} + +Tables with `Serial` columns support [copy](../../../reference/ydb-cli/tools-copy.md), [rename](../../../reference/ydb-cli/commands/tools/rename.md), [dump](../../../reference/ydb-cli/export-import/tools-dump.md), [restore](../../../reference/ydb-cli/export-import/import-file.md), and [import](../../../reference/ydb-cli/export-import/import-s3.md)/[export](../../../reference/ydb-cli/export-import/export-s3.md) CLI operations. + +## Usage Example + +Carefully choose the columns for your [PRIMARY KEY](../../../dev/primary-key/row-oriented.md). To ensure scalability and high performance, avoid using monotonically increasing primary keys; this pattern directs all inserts to the last partition, concentrating load on a single server. + +Instead, use a hash of the entire primary key (or a portion of it) as the first key element to distribute data evenly across cluster partitions. + +```yql +CREATE TABLE users ( + user_hash Uint64, + user_id Serial, + name Utf8, + email Utf8, + PRIMARY KEY (user_hash, user_id) +); +``` + +The `user_hash` field can be calculated on the application side, for example, by applying a hash function to the `email` column. + +``` yql +UPSERT INTO users (user_hash, name, email) VALUES (123456789, 'Alice', 'alice@example.com'); +INSERT INTO users (user_hash, name, email) VALUES (987654321, 'Bob', 'bob@example.com'); +REPLACE INTO users (user_hash, name, email) VALUES (111111111, 'John', 'john@example.com'); +``` + +Result (example `user_hash` values are used): + +| user_hash | email | name | user_id | +|-------------|-----------------------|-------|---------| +| 123456789 | `alice@example.com` | Alice | 1 | +| 987654321 | `bob@example.com` | Bob | 2 | +| 111111111 | `john@example.com` | John | 3 | + +You can also explicitly specify a value for a column of type `Serial` during insertion, for example, when restoring data. In this case, the insertion behaves like a regular integer column, and the sequence remains unaffected: + +``` yql +UPSERT INTO users (user_hash, user_id, name, email) VALUES (222222222, 10, 'Peter', 'peter@example.com'); +``` + +### Suboptimal Schema Example + +```yql +CREATE TABLE users_bad ( + user_id Serial, + name Utf8, + email Utf8, + PRIMARY KEY (user_id) +); +``` + +In this example, the auto-increment column is the sole component of the primary key, resulting in an uneven load and creating a bottleneck on the last partition. diff --git a/ydb/docs/en/core/yql/reference/types/toc_i.yaml b/ydb/docs/en/core/yql/reference/types/toc_i.yaml index 060dd02891fa..ca05b3f8c400 100644 --- a/ydb/docs/en/core/yql/reference/types/toc_i.yaml +++ b/ydb/docs/en/core/yql/reference/types/toc_i.yaml @@ -3,6 +3,9 @@ items: href: index.md - name: Simple href: primitive.md +- name: Serial + href: serial.md + when: feature_serial - name: Optional href: optional.md - name: Containers diff --git a/ydb/docs/ru/core/yql/reference/syntax/alter-sequence.md b/ydb/docs/ru/core/yql/reference/syntax/alter-sequence.md new file mode 100644 index 000000000000..8e23e9b6c946 --- /dev/null +++ b/ydb/docs/ru/core/yql/reference/syntax/alter-sequence.md @@ -0,0 +1,51 @@ +# ALTER SEQUENCE + +Изменяет параметры уже существующего объекта `Sequence`, привязанного к колонке [Serial](../types/serial.md) типа. + +## Синтаксис + +```yql +ALTER SEQUENCE [ IF EXISTS ] path_to_sequence + [ INCREMENT [ BY ] increment ] + [ START [ WITH ] start_value ] + [ RESTART [ [ WITH ] restart_value ]]; +``` + +## Параметры + +* `path_to_sequence` - абсолютный путь до объекта `Sequence`. + + Путь формируется как `/_serial_column_{column_name}`, + где `` — абсолютный путь до таблицы, a `{column_name}` — имя колонки типа `Serial`. + Например, для таблицы с путём `/local/users` и колонки `user_id` путь к соответствующему `Sequence` будет `/local/users/_serial_column_user_id`. +* `IF EXISTS` - при использовании этой конструкции, выражение не возвращает ошибку, если не существует `Sequence` по указаному пути. +* `INCREMENT [ BY ] increment` - задает шаг изменения последовательности. Значение по умолчанию: 1. +* `START [ WITH ] start_value` - устанавливает новое стартовое значение для последовательности. Изменение этого параметра через `ALTER SEQUENCE` не влияет на текущее значение последовательности, но будет использовано, если выполнить `ALTER SEQUENCE RESTART` без указания значения. Значение по умолчанию: 1. +* `RESTART [ [ WITH ] restart_value ]` - изменяет текущее значение последовательности на указанное в `restart_value`. Если значение не указано, текущее значение последовательности будет установлено в текущее стартовое значение. + +## Примеры + +``` yql +CREATE TABLE users ( + user_hash Uint64, + user_id Serial, + name Utf8, + email Utf8, + PRIMARY KEY (user_hash, user_id) +); +``` + +Изменить шаг последовательности для `user_id` и установить текущее значение равным 1000: + +```yql +ALTER SEQUENCE `/Root/users/_serial_column_user_id` + INCREMENT BY 5 + RESTART 1000; +``` + +Альтернативный способ изменить текущее значение — сначала изменить стартовое значение, а затем выполнить `RESTART` (после этого последующие сбросы через `RESTART` без указания `restart_value` будут устанавливать текущее значение в 1000): + +```yql +ALTER SEQUENCE `/Root/users/_serial_column_user_id` INCREMENT BY 5 START WITH 1000; +ALTER SEQUENCE `/Root/users/_serial_column_user_id` RESTART; +``` diff --git a/ydb/docs/ru/core/yql/reference/syntax/create_table/index.md b/ydb/docs/ru/core/yql/reference/syntax/create_table/index.md index e9b19453590b..0edc250e01b1 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/create_table/index.md +++ b/ydb/docs/ru/core/yql/reference/syntax/create_table/index.md @@ -96,19 +96,11 @@ WITH ( {% if feature_column_container_type == true %} - Для неключевых колонок допускаются любые типы данных{% if feature_serial %} , кроме [серийных](../../types/serial.md) {% endif %}, для ключевых - только [примитивные](../../types/primitive.md){% if feature_serial %} и [серийные](../../types/serial.md){% endif %}. При указании сложных типов (например, `List`) тип заключается в двойные кавычки. + Для неключевых колонок допускаются любые типы данных, для ключевых - только [примитивные](../../types/primitive.md){% if feature_serial %} и [серийные](../../types/serial.md){% endif %}. При указании сложных типов (например, `List`) тип заключается в двойные кавычки. {% else %} - {% if feature_serial %} - - Для ключевых колонок допускаются только [примитивные](../../types/primitive.md) и [серийные](../../types/serial.md) типы данных, для неключевых колонок допускаются только [примитивные](../../types/primitive.md). - - {% else %} - - Для ключевых и неключевых колонок допускаются только [примитивные](../../types/primitive.md) типы данных. - - {% endif %} + Для ключевых и неключевых колонок допускаются только [примитивные](../../types/primitive.md){% if feature_serial %} и [серийные](../../types/serial.md){% endif %} типы данных. {% endif %} diff --git a/ydb/docs/ru/core/yql/reference/syntax/index.md b/ydb/docs/ru/core/yql/reference/syntax/index.md index 5fe9236db3ec..dc29e7502387 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/index.md +++ b/ydb/docs/ru/core/yql/reference/syntax/index.md @@ -105,3 +105,9 @@ * [DROP ASYNC REPLICATION](drop-async-replication.md) {% endif %} + +{% if feature_serial %} + +* [ALTER SEQUENCE](alter-sequence.md) + +{% endif %} \ No newline at end of file diff --git a/ydb/docs/ru/core/yql/reference/syntax/show_create.md b/ydb/docs/ru/core/yql/reference/syntax/show_create.md index b4c0874e9d2c..1cce8e31d7d0 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/show_create.md +++ b/ydb/docs/ru/core/yql/reference/syntax/show_create.md @@ -30,7 +30,7 @@ SHOW CREATE [TABLE|VIEW] ; - [ALTER TABLE ... ADD CHANGEFEED](alter_table/changefeed.md)— для добавления потока изменений. {% endif %} {% if feature_serial %} - - `ALTER SEQUENCE` — для восстановления состояния `Sequence` у колонок типа [Serial](../../../yql/reference/types/serial.md). + - [ALTER SEQUENCE](alter-sequence.md) — для восстановления состояния `Sequence` у колонок типа [Serial](../types/serial.md). {% endif %} {% if feature_view %} - Для представлений: определение посредством команды [CREATE VIEW](create-view.md), а также, если необходимо, выражения, которые были зафиксированы представлением из контекста создания, например, [PRAGMA TablePathPrefix](pragma#table-path-prefix). diff --git a/ydb/docs/ru/core/yql/reference/syntax/toc_i.yaml b/ydb/docs/ru/core/yql/reference/syntax/toc_i.yaml index 2359ee677d1d..c50a019258a3 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/toc_i.yaml +++ b/ydb/docs/ru/core/yql/reference/syntax/toc_i.yaml @@ -11,6 +11,7 @@ items: - { name: ALTER RESOURCE POOL CLASSIFIER, href: alter-resource-pool-classifier.md, when: feature_resource_pool_classifier } - { name: ALTER TOPIC, href: alter-topic.md, when: feature_topic_control_plane } - { name: ALTER USER, href: alter-user.md, when: feature_user_and_group } +- { name: ALTER SEQUENCE, href: alter-sequence.md, when: feature_serial } - { name: ANALYZE, href: analyze.md, when: backend_name == "YDB" } - { name: CREATE ASYNC REPLICATION, href: create-async-replication.md, when: feature_async_replication } - { name: CREATE GROUP, href: create-group.md, when: feature_user_and_group } diff --git a/ydb/docs/ru/core/yql/reference/types/serial.md b/ydb/docs/ru/core/yql/reference/types/serial.md index 64b6b1e7fcd9..aa13d8cdc409 100644 --- a/ydb/docs/ru/core/yql/reference/types/serial.md +++ b/ydb/docs/ru/core/yql/reference/types/serial.md @@ -1,48 +1,23 @@ # Серийные типы данных -Серийные типы данных представляют собой целые числа, но с дополнительным механизмом генерации значений. Эти типы данных используются для создания автоинкрементных колонок, а именно для каждой новой строки, добавляемой в таблицу, будет автоматически генерироваться уникальное значение для такой колонки (подобно типу [SERIAL](https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-SERIAL) в PostgreSQL или свойству [AUTO_INCREMENT](https://dev.mysql.com/doc/refman/9.0/en/example-auto-increment.html) в MySQL). +Серийные типы данных представляют собой целые числа, но с дополнительным механизмом генерации значений. Эти типы данных используются для создания автоинкрементных колонок, а именно: для каждой новой строки, добавляемой в таблицу, будет автоматически генерироваться уникальное значение для такой колонки (подобно типу [SERIAL](https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-SERIAL) в PostgreSQL или свойству [AUTO_INCREMENT](https://dev.mysql.com/doc/refman/9.0/en/example-auto-increment.html) в MySQL). -## Пример использования - -``` yql -CREATE TABLE users ( - user_id Serial, - name Utf8, - email Utf8, - PRIMARY KEY (user_id) -); -``` - -``` yql -UPSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com'); -INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com'); -REPLACE INTO users (name, email) VALUES ('John', 'john@example.com'); -``` - -``` yql -SELECT * FROM users; -``` +## Описание -| email | name | user_id | -|---------------------|-------|---------| -| `alice@example.com` | Alice | 1 | -| `bob@example.com` | Bob | 2 | -| `john@example.com` | John | 3 | +При определении такого типа для колонки создаётся отдельный схемный объект `Sequence`, привязанный к этой колонке и являющийся генератором последовательности, из которого извлекаются значения. Этот объект является приватным и скрыт от пользователя. `Sequence` будет уничтожен вместе с таблицей. -Можно самостоятельно указать значение `Serial` колонки при вставке, в этом случае вставка будет выполняться, как с обычной целочисленной колонкой, и `Sequence` затрагиваться при таком запросе никак не будет: +Объект `Sequence` поддерживает ряд параметров, определяющих его поведение, которые можно изменить после создания `Sequence` с помощью команды [ALTER SEQUENCE](../syntax/alter-sequence.md). -``` yql -UPSERT INTO users (user_id, name, email) VALUES (4, 'Peter', 'peter@example.com'); -``` +По умолчанию генерируемые значения начинаются с единицы, увеличиваются на один при каждом новом значении и ограничены в соответствии с выбранным типом. -## Описание +{% note info %} -Только колонки, участвующие в первичном ключе таблиц, могут иметь тип `Serial`. +Столбцы типа `Serial` поддерживаются как для колонок, входящих в состав первичного ключа, так и для неключевых колонок. -При определении такого типа для колонки создаётся отдельный схемный объект `Sequence`, привязанный к этой колонке и являющийся генератором последовательности, из которого извлекаются значения. Этот объект является приватным и скрыт от пользователя. `Sequence` будет уничтожен вместе с таблицей. +Однако такие колонки нельзя [изменить](../syntax/alter_table/family#mod-column-groups) или [удалить](../syntax/alter_table/columns.md) из таблицы — при попытке выполнить эти операции будет возвращена ошибка. -Значения последовательности начинаются с единицы, выдаются с шагом, равным единице, и ограничены в зависимости от используемого типа. +{% endnote %} | Тип | Максимальное значение | Тип значения | |---------------|-----------------------|--------------| @@ -60,7 +35,66 @@ Error: Failed to get next val for sequence: /dev/test/users/_serial_column_user_
: Error: sequence [OwnerId: , LocalPathId: ] doesn't have any more values available, code: 200503 ``` -Отметим, что следующее значение выдаётся генератором до непосредственной вставки в таблицу и уже будет считаться использованным, даже если строка, содержащая это значение, не была успешно вставлена, например, при откате транзакции. Поэтому множество значений такой колонки может содержать пропуски и состоять из нескольких промежутков. +{% note info %} + +Cледующее значение выдаётся генератором до непосредственной вставки в таблицу и уже будет считаться использованным, даже если строка, содержащая это значение, не была успешно вставлена, например, при откате транзакции. Поэтому множество значений такой колонки может содержать пропуски и состоять из нескольких промежутков. + +{% endnote %} + +Для таблиц с автоинкрементными колонками поддержаны операции [copy](../../../reference/ydb-cli/tools-copy.md), [rename](../../../reference/ydb-cli/commands/tools/rename.md), [dump](../../../reference/ydb-cli/export-import/tools-dump.md), [restore](../../../reference/ydb-cli/export-import/import-file.md) и [import](../../../reference/ydb-cli/export-import/import-s3.md)/[export](../../../reference/ydb-cli/export-import/export-s3.md). + +## Пример использования + +Следует обратить внимание на правильный выбор колонок для [PRIMARY KEY](../../../dev/primary-key/row-oriented.md). Для масштабируемости нагрузки и высокой производительности стоит избегать записи строк с монотонно возрастающими первичными ключами. В этом случае все записи будут попадать в последнюю партицию, и вся нагрузка будет приходиться на один сервер. + +Например, в качестве первого элемента ключа использовать можно хеш от всего первичного ключа либо его части, чтобы равномерно распределять данные по партициям кластера. + +``` yql +CREATE TABLE users ( + user_hash Uint64, + user_id Serial, + name Utf8, + email Utf8, + PRIMARY KEY (user_hash, user_id) +); +``` + +Хеш для поля `user_hash` можно рассчитать на стороне приложения, например, используя хеш-функцию от `email`. + +``` yql +UPSERT INTO users (user_hash, name, email) VALUES (123456789, 'Alice', 'alice@example.com'); +INSERT INTO users (user_hash, name, email) VALUES (987654321, 'Bob', 'bob@example.com'); +REPLACE INTO users (user_hash, name, email) VALUES (111111111, 'John', 'john@example.com'); +``` + +``` yql +SELECT * FROM users; +``` + +Результат (значения `user_hash` приведены для примера): + +| user_hash | email | name | user_id | +|-------------|-----------------------|-------|---------| +| 123456789 | `alice@example.com` | Alice | 1 | +| 987654321 | `bob@example.com` | Bob | 2 | +| 111111111 | `john@example.com` | John | 3 | + +Можно самостоятельно указать значение `Serial`-колонки при вставке, например для восстановления данных. В этом случае вставка будет выполняться, как с обычной целочисленной колонкой, и `Sequence` затрагиваться при таком запросе никак не будет: + +``` yql +UPSERT INTO users (user_hash, user_id, name, email) VALUES (222222222, 10, 'Peter', 'peter@example.com'); +``` + +### Пример неудачной схемы + +``` yql +CREATE TABLE users_bad ( + user_id Serial, + name Utf8, + email Utf8, + PRIMARY KEY (user_id) +); +``` -Для таблиц с автоинкрементными колонками поддержаны операции [copy](../../../reference/ydb-cli/tools-copy.md), [dump](../../../reference/ydb-cli/export-import/tools-dump.md), [restore](../../../reference/ydb-cli/export-import/import-file.md) и [import](../../../reference/ydb-cli/export-import/import-s3.md)/[export](../../../reference/ydb-cli/export-import/export-s3.md). +В этом примере автоинкрементная колонка является единственным и первым элементом ключа — это приведёт к неравномерной нагрузке и узкому месту на последней партиции.