Skip to content

Commit a6fb589

Browse files
committed
Initial commit
1 parent 44aff91 commit a6fb589

File tree

4 files changed

+152
-36
lines changed

4 files changed

+152
-36
lines changed

ydb/docs/en/core/yql/reference/types/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
This section contains articles on YQL data types:
44

55
- [Simple/Primitive types](primitive.md)
6+
{% if feature_serial %}- [Serial types](serial.md){% endif %}
67
- [Optional types](optional.md)
78
- [Containers](containers.md)
89
- [Special types](special.md)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Serial Types
2+
3+
Serial types are integer types with an associated value-generation mechanism. These types are used to create auto-increment columns: for each new row inserted into a table, a unique value for this column is generated automatically (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).
4+
5+
## Description
6+
7+
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 is hidden from the user. The `Sequence` will be destroyed together with the table.
8+
9+
Values generated by the sequence start from one, are incremented by one with each new value, and are limited according to the chosen type.
10+
11+
> **Note:**
12+
> Serial columns are supported both for columns included in the primary key and for non-key columns.
13+
>
14+
> However, such columns cannot be [altered](../syntax/alter_table/family#mod-column-groups) or [dropped](../syntax/alter_table/columns.md) from the table —
15+
> attempting to perform these operations will result in an error.
16+
17+
| Type | Maximum Value | YDB Type |
18+
|-------------|----------------------|----------|
19+
| SmallSerial | 2^15–1 | Int16 |
20+
| Serial2 | 2^15–1 | Int16 |
21+
| Serial | 2^31–1 | Int32 |
22+
| Serial4 | 2^31–1 | Int32 |
23+
| Serial8 | 2^63–1 | Int64 |
24+
| BigSerial | 2^63–1 | Int64 |
25+
26+
If the sequence reaches its maximum value, insertion will result in an error:
27+
28+
```text
29+
Error: Failed to get next val for sequence: /dev/test/users/_serial_column_user_id, status: SCHEME_ERROR
30+
<main>: Error: sequence [OwnerId: <some>, LocalPathId: <some>] doesn't have any more values available, code: 200503
31+
```
32+
33+
**Note:** 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).
34+
As a result, the values in such a column may have gaps and may not form a continuous sequence.
35+
36+
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) operations.
37+
38+
## Usage Example
39+
40+
You should carefully choose the columns for your [PRIMARY KEY](../../../dev/primary-key/row-oriented.md). For scalability and high performance, you should avoid writing rows with monotonically increasing primary keys. In this case, all records will go to the last partition, and all the load will target a single server.
41+
42+
As a recommended approach, use a hash (for example, from the whole or a part of the primary key) as the first key element, which will help evenly distribute data across cluster partitions.
43+
44+
```yql
45+
CREATE TABLE users (
46+
user_hash Uint64,
47+
user_id Serial,
48+
name Utf8,
49+
email Utf8,
50+
PRIMARY KEY (user_hash, user_id)
51+
);
52+
53+
The `user_hash` field can be calculated on the application side, for example, by applying a hash function to the `email`.
54+
55+
``` yql
56+
UPSERT INTO users (user_hash, name, email) VALUES (123456789, 'Alice', 'alice@example.com');
57+
INSERT INTO users (user_hash, name, email) VALUES (987654321, 'Bob', 'bob@example.com');
58+
REPLACE INTO users (user_hash, name, email) VALUES (111111111, 'John', 'john@example.com');
59+
```
60+
61+
Result (example `user_hash` values are used):
62+
63+
| user_hash | email | name | user_id |
64+
|-------------|---------------------|-------|---------|
65+
| 123456789 | alice@example.com | Alice | 1 |
66+
| 987654321 | bob@example.com | Bob | 2 |
67+
| 111111111 | john@example.com | John | 3 |
68+
69+
You can also explicitly specify a value for the `Serial` column during insertion, for example, when restoring data. In this case, the insertion will work like with a regular integer column, and the `Sequence` will not be affected:
70+
71+
``` yql
72+
UPSERT INTO users (user_hash, user_id, name, email) VALUES (222222222, 10, 'Peter', 'peter@example.com');
73+
```
74+
75+
### Suboptimal Schema Example
76+
77+
```yql
78+
CREATE TABLE users_bad (
79+
user_id Serial,
80+
name Utf8,
81+
email Utf8,
82+
PRIMARY KEY (user_id)
83+
);
84+
```
85+
86+
In this example, the auto-increment column is the first and only element of the primary key. This leads to an uneven load and a bottleneck on the last partition.

ydb/docs/en/core/yql/reference/types/toc_i.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ items:
33
href: index.md
44
- name: Simple
55
href: primitive.md
6+
- name: Serial
7+
href: serial.md
8+
when: feature_serial
69
- name: Optional
710
href: optional.md
811
- name: Containers
Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,92 @@
11

22
# Серийные типы данных
33

4-
Серийные типы данных представляют собой целые числа, но с дополнительным механизмом генерации значений. Эти типы данных используются для создания автоинкрементных колонок, а именно для каждой новой строки, добавляемой в таблицу, будет автоматически генерироваться уникальное значение для такой колонки (подобно типу [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).
4+
Серийные типы данных представляют собой целые числа, но с дополнительным механизмом генерации значений. Эти типы данных используются для создания автоинкрементных колонок, а именно - для каждой новой строки, добавляемой в таблицу, будет автоматически генерироваться уникальное значение для такой колонки (подобно типу [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).
5+
6+
## Описание
7+
8+
При определении такого типа для колонки создаётся отдельный схемный объект `Sequence`, привязанный к этой колонке и являющийся генератором последовательности, из которого извлекаются значения. Этот объект является приватным и скрыт от пользователя. `Sequence` будет уничтожен вместе с таблицей.
9+
10+
Значения последовательности начинаются с единицы, выдаются с шагом, равным единице, и ограничены в зависимости от используемого типа.
11+
12+
> **Примечание:**
13+
> Колонки типа `Serial` поддерживаются как для колонок, входящих в состав первичного ключа, так и для неключевых колонок.
14+
>
15+
> Однако такие колонки нельзя [изменить](../syntax/alter_table/family#mod-column-groups) или [удалить](../syntax/alter_table/columns.md) из таблицы —
16+
> при попытке выполнить эти операции будет возвращена ошибка.
17+
18+
| Тип | Максимальное значение | Тип значения |
19+
|---------------|-----------------------|--------------|
20+
| `SmallSerial` | $2^{15}–1$ | `Int16` |
21+
| `Serial2` | $2^{15}–1$ | `Int16` |
22+
| `Serial` | $2^{31}–1$ | `Int32` |
23+
| `Serial4` | $2^{31}–1$ | `Int32` |
24+
| `Serial8` | $2^{63}–1$ | `Int64` |
25+
| `BigSerial` | $2^{63}–1$ | `Int64` |
26+
27+
При переполнении `Sequence` на вставке будет возвращаться ошибка:
28+
29+
```text
30+
Error: Failed to get next val for sequence: /dev/test/users/_serial_column_user_id, status: SCHEME_ERROR
31+
<main>: Error: sequence [OwnerId: <some>, LocalPathId: <some>] doesn't have any more values available, code: 200503
32+
```
33+
34+
Отметим, что следующее значение выдаётся генератором до непосредственной вставки в таблицу и уже будет считаться использованным, даже если строка, содержащая это значение, не была успешно вставлена, например, при откате транзакции. Поэтому множество значений такой колонки может содержать пропуски и состоять из нескольких промежутков.
35+
36+
Для таблиц с автоинкрементными колонками поддержаны операции [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).
537

638
## Пример использования
739

40+
Cледует обратить внимание на правильный выбор колонок для [PRIMARY KEY](../../../dev/primary-key/row-oriented.md). Для масштабируемости нагрузки и высокой производительности стоит избегать записи строк с монотонно возрастающими первичными ключами. В этом случае все записи будут попадать в последнюю партицию, и вся нагрузка будет приходиться на один сервер.
41+
42+
Например, в качестве первого элемента ключа использовать можно хеш от всего первичного ключа либо его части, чтобы равномерно распределять данные по партициям кластера.
43+
844
``` yql
945
CREATE TABLE users (
46+
user_hash Uint64,
1047
user_id Serial,
1148
name Utf8,
1249
email Utf8,
13-
PRIMARY KEY (user_id)
50+
PRIMARY KEY (user_hash, user_id)
1451
);
1552
```
1653

54+
Хеш для поля `user_hash` можно рассчитать на стороне приложения, например, используя хеш-функцию от `email`.
55+
1756
``` yql
18-
UPSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
19-
INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com');
20-
REPLACE INTO users (name, email) VALUES ('John', 'john@example.com');
57+
UPSERT INTO users (user_hash, name, email) VALUES (123456789, 'Alice', 'alice@example.com');
58+
INSERT INTO users (user_hash, name, email) VALUES (987654321, 'Bob', 'bob@example.com');
59+
REPLACE INTO users (user_hash, name, email) VALUES (111111111, 'John', 'john@example.com');
2160
```
2261

2362
``` yql
2463
SELECT * FROM users;
2564
```
2665

27-
| email | name | user_id |
28-
|---------------------|-------|---------|
29-
| `alice@example.com` | Alice | 1 |
30-
| `bob@example.com` | Bob | 2 |
31-
| `john@example.com` | John | 3 |
66+
Результат (значения `user_hash` приведены для примера):
3267

33-
Можно самостоятельно указать значение `Serial` колонки при вставке, в этом случае вставка будет выполняться, как с обычной целочисленной колонкой, и `Sequence` затрагиваться при таком запросе никак не будет:
68+
| user_hash | email | name | user_id |
69+
|-------------|---------------------|-------|---------|
70+
| 123456789 | alice@example.com | Alice | 1 |
71+
| 987654321 | bob@example.com | Bob | 2 |
72+
| 111111111 | john@example.com | John | 3 |
73+
74+
Можно самостоятельно указать значение `Serial`-колонки при вставке, например для восстановления данных. В этом случае вставка будет выполняться, как с обычной целочисленной колонкой, и `Sequence` затрагиваться при таком запросе никак не будет:
3475

3576
``` yql
36-
UPSERT INTO users (user_id, name, email) VALUES (4, 'Peter', 'peter@example.com');
77+
UPSERT INTO users (user_hash, user_id, name, email) VALUES (222222222, 10, 'Peter', 'peter@example.com');
3778
```
3879

39-
## Описание
40-
41-
Только колонки, участвующие в первичном ключе таблиц, могут иметь тип `Serial`.
42-
43-
При определении такого типа для колонки создаётся отдельный схемный объект `Sequence`, привязанный к этой колонке и являющийся генератором последовательности, из которого извлекаются значения. Этот объект является приватным и скрыт от пользователя. `Sequence` будет уничтожен вместе с таблицей.
44-
45-
Значения последовательности начинаются с единицы, выдаются с шагом, равным единице, и ограничены в зависимости от используемого типа.
80+
### Пример неудачной схемы
4681

47-
| Тип | Максимальное значение | Тип значения |
48-
|---------------|-----------------------|--------------|
49-
| `SmallSerial` | $2^{15}–1$ | `Int16` |
50-
| `Serial2` | $2^{15}–1$ | `Int16` |
51-
| `Serial` | $2^{31}–1$ | `Int32` |
52-
| `Serial4` | $2^{31}–1$ | `Int32` |
53-
| `Serial8` | $2^{63}–1$ | `Int64` |
54-
| `BigSerial` | $2^{63}–1$ | `Int64` |
55-
56-
При переполнении `Sequence` на вставке будет возвращаться ошибка:
57-
58-
```text
59-
Error: Failed to get next val for sequence: /dev/test/users/_serial_column_user_id, status: SCHEME_ERROR
60-
<main>: Error: sequence [OwnerId: <some>, LocalPathId: <some>] doesn't have any more values available, code: 200503
82+
``` yql
83+
CREATE TABLE users_bad (
84+
user_id Serial,
85+
name Utf8,
86+
email Utf8,
87+
PRIMARY KEY (user_id)
88+
);
6189
```
6290

63-
Отметим, что следующее значение выдаётся генератором до непосредственной вставки в таблицу и уже будет считаться использованным, даже если строка, содержащая это значение, не была успешно вставлена, например, при откате транзакции. Поэтому множество значений такой колонки может содержать пропуски и состоять из нескольких промежутков.
64-
65-
Для таблиц с автоинкрементными колонками поддержаны операции [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).
91+
В следующем примере автоинкрементная колонка является единственным и первым элементом ключа — это приведёт к неравномерной нагрузке и узкому месту на последней партиции.
6692

0 commit comments

Comments
 (0)