Перейти к основному содержимому
Версия: 2.0.x

AUTO_INCREMENT

Начиная с версии 3.0, Selena поддерживает атрибут столбца AUTO_INCREMENT, который может упростить управление данными. В этой теме рассматриваются сценарии применения, использование и функции атрибута столбца AUTO_INCREMENT.

Введение

Когда новая строка данных загружается в таблицу и значения для столбца AUTO_INCREMENT не указаны, Selena автоматически присваивает целочисленное значение для столбца AUTO_INCREMENT этой строки в качестве её уникального ID в таблице. Последующие значения для столбца AUTO_INCREMENT автоматически увеличиваются с определенным шагом, начиная с ID этой строки. Столбец AUTO_INCREMENT может использоваться для упрощения управления данными и ускорения некоторых запросов. Вот некоторые сценарии применения столбца AUTO_INCREMENT:

  • Использование в качестве первичных ключей: Столбец AUTO_INCREMENT может использоваться в качестве первичного ключа для обеспечения уникального ID каждой строки и упрощения запросов и управления данными.
  • Соединение таблиц: Когда несколько таблиц соединяются, столбец AUTO_INCREMENT может использоваться в качестве Join Key, что может ускорить запросы по сравнению с использованием столбца типа данных STRING, например, UUID.
  • Подсчет количества различных значений в столбце с высокой кардинальностью: Столбец AUTO_INCREMENT может использоваться для представления столбца уникальных значений в словаре. По сравнению с прямым подсчетом различных значений STRING, подсчет различных целочисленных значений столбца AUTO_INCREMENT иногда может улучшить скорость запроса в несколько раз или даже в десятки раз.

Вам нужно указать столбец AUTO_INCREMENT в операторе CREATE TABLE. Типами данных столбца AUTO_INCREMENT должен быть BIGINT. Значение для столбца AUTO_INCREMENT может быть присвоено неявно или указано явно. Оно начинается с 1 и увеличивается на 1 для каждой новой строки.

Основные операции

Указание столбца AUTO_INCREMENT при создании таблицы

Создайте таблицу с именем test_tbl1 с двумя столбцами, id и number. Укажите столбец number как столбец AUTO_INCREMENT.

CREATE TABLE test_tbl1
(
id BIGINT NOT NULL,
number BIGINT NOT NULL AUTO_INCREMENT
)
PRIMARY KEY (id)
DISTRIBUTED BY HASH(id)
PROPERTIES("replicated_storage" = "true");

Присвоение значений для столбца AUTO_INCREMENT

Неявное присвоение значений

Когда вы загружаете данные в таблицу Selena, вам не нужно указывать значения для столбца AUTO_INCREMENT. Selena автоматически присваивает уникальные целочисленные значения для этого столбца и вставляет их в таблицу.

INSERT INTO test_tbl1 (id) VALUES (1);
INSERT INTO test_tbl1 (id) VALUES (2);
INSERT INTO test_tbl1 (id) VALUES (3),(4),(5);

Просмотр данных в таблице.

mysql > SELECT * FROM test_tbl1 ORDER BY id;
+------+--------+
| id | number |
+------+--------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+------+--------+
5 rows in set (0.02 sec)

Когда вы загружаете данные в таблицу Selena, вы также можете указать значения как DEFAULT для столбца AUTO_INCREMENT. Selena автоматически присваивает уникальные целочисленные значения для этого столбца и вставляет их в таблицу.

INSERT INTO test_tbl1 (id, number) VALUES (6, DEFAULT);

Просмотр данных в таблице.

mysql > SELECT * FROM test_tbl1 ORDER BY id;
+------+--------+
| id | number |
+------+--------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
+------+--------+
6 rows in set (0.02 sec)

В реальном использовании следующий результат может быть возвращен при просмотре данных в таблице. Это происходит потому, что Selena не может гарантировать, что значения для столбца AUTO_INCREMENT строго монотонны. Но Selena может гарантировать, что значения примерно увеличиваются в хронологическом порядке. Для получения дополнительной информации см. Монотонность.

mysql > SELECT * FROM test_tbl1 ORDER BY id;
+------+--------+
| id | number |
+------+--------+
| 1 | 1 |
| 2 | 100001 |
| 3 | 200001 |
| 4 | 200002 |
| 5 | 200003 |
| 6 | 200004 |
+------+--------+
6 rows in set (0.01 sec)

Явное указание значений

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

INSERT INTO test_tbl1 (id, number) VALUES (7, 100);

-- просмотр данных в таблице.

mysql > SELECT * FROM test_tbl1 ORDER BY id;
+------+--------+
| id | number |
+------+--------+
| 1 | 1 |
| 2 | 100001 |
| 3 | 200001 |
| 4 | 200002 |
| 5 | 200003 |
| 6 | 200004 |
| 7 | 100 |
+------+--------+
7 rows in set (0.01 sec)

Более того, явное указание значений не влияет на последующие значения, генерируемые Selena для вновь вставленных строк данных.

INSERT INTO test_tbl1 (id) VALUES (8);

-- просмотр данных в таблице.

mysql > SELECT * FROM test_tbl1 ORDER BY id;
+------+--------+
| id | number |
+------+--------+
| 1 | 1 |
| 2 | 100001 |
| 3 | 200001 |
| 4 | 200002 |
| 5 | 200003 |
| 6 | 200004 |
| 7 | 100 |
| 8 | 2 |
+------+--------+
8 rows in set (0.01 sec)

ПРИМЕЧАНИЕ

Мы рекомендуем не использовать неявно присвоенные значения и явно указанные значения для столбца AUTO_INCREMENT одновременно. Потому что указанные значения могут быть такими же, как значения, сгенерированные Selena, что нарушает глобальную уникальность автоинкрементных ID.

Основные функции

Уникальность

В общем случае Selena гарантирует, что значения для столбца AUTO_INCREMENT глобально уникальны в таблице. Мы рекомендуем не присваивать неявно и явно указывать значения для столбца AUTO_INCREMENT одновременно. Если вы это сделаете, это может нарушить глобальную уникальность автоинкрементных ID. Вот простой пример: Создайте таблицу с именем test_tbl2 с двумя столбцами, id и number. Укажите столбец number как столбец AUTO_INCREMENT.

CREATE TABLE test_tbl2
(
id BIGINT NOT NULL,
number BIGINT NOT NULL AUTO_INCREMENT
)
PRIMARY KEY (id)
DISTRIBUTED BY HASH(id)
PROPERTIES("replicated_storage" = "true");

Неявно присвойте и явно укажите значения для столбца AUTO_INCREMENT number в таблице test_tbl2.

INSERT INTO test_tbl2 (id, number) VALUES (1, DEFAULT);
INSERT INTO test_tbl2 (id, number) VALUES (2, 2);
INSERT INTO test_tbl2 (id) VALUES (3);

Запросите таблицу test_tbl2.

mysql > SELECT * FROM test_tbl2 ORDER BY id;
+------+--------+
| id | number |
+------+--------+
| 1 | 1 |
| 2 | 2 |
| 3 | 100001 |
+------+--------+
3 rows in set (0.08 sec)

Монотонность

Для улучшения производительности выделения автоинкрементных ID, BE кэшируют некоторые автоинкрементные ID локально. В этой ситуации Selena не может гарантировать, что значения для столбца AUTO_INCREMENT строго монотонны. Можно гарантировать только то, что значения примерно увеличиваются в хронологическом порядке.

ПРИМЕЧАНИЕ

Количество автоинкрементных ID, кэшируемых BE, определяется динамическим параметром FE auto_increment_cache_size, который по умолчанию равен 100,000. Вы можете изменить значение, используя ADMIN SET FRONTEND CONFIG ("auto_increment_cache_size" = "xxx");

Например, кластер Selena имеет один узел FE и два узла BE. Создайте таблицу с именем test_tbl3 и вставьте пять строк данных следующим образом:

CREATE TABLE test_tbl3
(
id BIGINT NOT NULL,
number BIGINT NOT NULL AUTO_INCREMENT
)
PRIMARY KEY (id)
DISTRIBUTED BY HASH(id)
PROPERTIES("replicated_storage" = "true");

INSERT INTO test_tbl3 VALUES (1, DEFAULT);
INSERT INTO test_tbl3 VALUES (2, DEFAULT);
INSERT INTO test_tbl3 VALUES (3, DEFAULT);
INSERT INTO test_tbl3 VALUES (4, DEFAULT);
INSERT INTO test_tbl3 VALUES (5, DEFAULT);

Автоинкрементные ID в таблице test_tbl3 не увеличиваются монотонно, потому что два узла BE кэшируют автоинкрементные ID, [1, 100000] и [100001, 200000] соответственно. Когда данные загружаются с использованием нескольких операторов INSERT, данные отправляются на разные узлы BE, которые выделяют автоинкрементные ID независимо. Поэтому нельзя гарантировать, что автоинкрементные ID строго монотонны.

mysql > SELECT * FROM test_tbl3 ORDER BY id;
+------+--------+
| id | number |
+------+--------+
| 1 | 1 |
| 2 | 100001 |
| 3 | 200001 |
| 4 | 2 |
| 5 | 100002 |
+------+--------+
5 rows in set (0.07 sec)

Частичные обновления и столбец AUTO_INCREMENT

В этом разделе объясняется, как обновить только несколько указанных столбцов в таблице, содержащей столбец AUTO_INCREMENT.

ПРИМЕЧАНИЕ

В настоящее время только таблицы с Primary Key поддерживают частичные обновления.

Столбец AUTO_INCREMENT является первичным ключом

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

  1. Создайте таблицу test_tbl4 в базе данных example_db и вставьте одну строку данных.

    -- Создать таблицу.
    CREATE TABLE test_tbl4
    (
    id BIGINT AUTO_INCREMENT,
    name BIGINT NOT NULL,
    job1 BIGINT NOT NULL,
    job2 BIGINT NOT NULL
    )
    PRIMARY KEY (id, name)
    DISTRIBUTED BY HASH(id)
    PROPERTIES("replicated_storage" = "true");

    -- Подготовленные данные.
    mysql > INSERT INTO test_tbl4 (id, name, job1, job2) VALUES (0, 0, 1, 1);
    Query OK, 1 row affected (0.04 sec)
    {'label':'insert_6af28e77-7d2b-11ed-af6e-02424283676b', 'status':'VISIBLE', 'txnId':'152'}

    -- Запросить таблицу.
    mysql > SELECT * FROM test_tbl4 ORDER BY id;
    +------+------+------+------+
    | id | name | job1 | job2 |
    +------+------+------+------+
    | 0 | 0 | 1 | 1 |
    +------+------+------+------+
    1 row in set (0.01 sec)
  2. Подготовьте CSV-файл my_data4.csv для обновления таблицы test_tbl4. CSV-файл включает значения для столбца AUTO_INCREMENT и не включает значения для столбца job1. Первичный ключ первой строки уже существует в таблице test_tbl4, в то время как первичный ключ второй строки не существует в таблице.

    0,0,99
    1,1,99
  3. Запустите задачу Stream Load и используйте CSV-файл для обновления таблицы test_tbl4.

    curl --location-trusted -u <username>:<password> -H "label:1" \
    -H "column_separator:," \
    -H "partial_update:true" \
    -H "columns:id,name,job2" \
    -T my_data4.csv -XPUT \
    http://<fe_host>:<fe_http_port>/api/example_db/test_tbl4/_stream_load
  4. Запросите обновленную таблицу. Первая строка данных уже существует в таблице test_tbl4, и значение для столбца job1 остается неизменным. Вторая строка данных вновь вставлена, и поскольку значение по умолчанию для столбца job1 не указано, фреймворк частичного обновления непосредственно устанавливает значение для этого столбца в 0.

    mysql > SELECT * FROM test_tbl4 ORDER BY id;
    +------+------+------+------+
    | id | name | job1 | job2 |
    +------+------+------+------+
    | 0 | 0 | 1 | 99 |
    | 1 | 1 | 0 | 99 |
    +------+------+------+------+
    2 rows in set (0.01 sec)

Столбец AUTO_INCREMENT не является первичным ключом

Если столбец AUTO_INCREMENT не является первичным ключом или частью первичного ключа, и автоинкрементные ID не предоставлены в задаче Stream Load, происходят следующие ситуации:

  • Если строка уже существует в таблице, Selena не обновляет автоинкрементный ID.
  • Если строка вновь загружается в таблицу, Selena генерирует новый автоинкрементный ID.

Эта функция может использоваться для построения словарной таблицы для быстрого вычисления различных значений STRING.

  1. В базе данных example_db создайте таблицу test_tbl5 и укажите столбец job1 как столбец AUTO_INCREMENT и вставьте строку данных в таблицу test_tbl5.

    -- Создать таблицу.
    CREATE TABLE test_tbl5
    (
    id BIGINT NOT NULL,
    name BIGINT NOT NULL,
    job1 BIGINT NOT NULL AUTO_INCREMENT,
    job2 BIGINT NOT NULL
    )
    PRIMARY KEY (id, name)
    DISTRIBUTED BY HASH(id)
    PROPERTIES("replicated_storage" = "true");

    -- Подготовить данные.
    mysql > INSERT INTO test_tbl5 VALUES (0, 0, -1, -1);
    Query OK, 1 row affected (0.04 sec)
    {'label':'insert_458d9487-80f6-11ed-ae56-aa528ccd0ebf', 'status':'VISIBLE', 'txnId':'94'}

    -- Запросить таблицу.
    mysql > SELECT * FROM test_tbl5 ORDER BY id;
    +------+------+------+------+
    | id | name | job1 | job2 |
    +------+------+------+------+
    | 0 | 0 | -1 | -1 |
    +------+------+------+------+
    1 row in set (0.01 sec)
  2. Подготовьте CSV-файл my_data5.csv для обновления таблицы test_tbl5. CSV-файл не содержит значений для столбца AUTO_INCREMENT job1. Первичный ключ первой строки уже существует в таблице, в то время как первичные ключи второй и третьей строк не существуют.

    0,0,99
    1,1,99
    2,2,99
  3. Запустите задачу Stream Load для загрузки данных из CSV-файла в таблицу test_tbl5.

    curl --location-trusted -u <username>:<password> -H "label:2" \
    -H "column_separator:," \
    -H "partial_update:true" \
    -H "columns: id,name,job2" \
    -T my_data5.csv -XPUT \
    http://<fe_host>:<fe_http_port>/api/example_db/test_tbl5/_stream_load
  4. Запросите обновленную таблицу. Первая строка данных уже существует в таблице test_tbl5, поэтому столбец AUTO_INCREMENT job1 сохраняет свое исходное значение. Вторая и третья строки данных вновь вставлены, поэтому Selena генерирует новые значения для столбца AUTO_INCREMENT job1.

    mysql > SELECT * FROM test_tbl5 ORDER BY id;
    +------+------+--------+------+
    | id | name | job1 | job2 |
    +------+------+--------+------+
    | 0 | 0 | -1 | 99 |
    | 1 | 1 | 1 | 99 |
    | 2 | 2 | 100001 | 99 |
    +------+------+--------+------+
    3 rows in set (0.01 sec)

Ограничения

  • При создании таблицы со столбцом AUTO_INCREMENT необходимо установить 'replicated_storage' = 'true', чтобы гарантировать, что все реплики имеют одинаковые автоинкрементные ID.

  • Каждая таблица может иметь только один столбец AUTO_INCREMENT.

  • Тип данных столбца AUTO_INCREMENT должен быть BIGINT.

  • Столбец AUTO_INCREMENT должен быть NOT NULL и не иметь значения по умолчанию.

  • Вы можете удалять данные из таблицы с Primary Key со столбцом AUTO_INCREMENT. Однако, если столбец AUTO_INCREMENT не является первичным ключом или частью первичного ключа, вам нужно учитывать следующие ограничения при удалении данных в следующих сценариях:

    • Во время операции DELETE также существует задача загрузки для частичных обновлений, которая содержит только операции UPSERT. Если операции UPSERT и DELETE затрагивают одну и ту же строку данных, и операция UPSERT выполняется после операции DELETE, операция UPSERT может не вступить в силу.
    • Существует задача загрузки для частичных обновлений, которая включает несколько операций UPSERT и DELETE для одной и той же строки данных. Если определенная операция UPSERT выполняется после операции DELETE, операция UPSERT может не вступить в силу.
  • Добавление атрибута AUTO_INCREMENT с помощью ALTER TABLE не поддерживается.

  • Начиная с версии 3.1, режим shared-data Selena поддерживает атрибут AUTO_INCREMENT.

  • Selena не поддерживает указание начального значения и размера шага для столбца AUTO_INCREMENT.

Ключевые слова

AUTO_INCREMENT, AUTO INCREMENT