Перейти к основному содержимому

AUTO_INCREMENT

Начиная с версии 1.5.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 не поддерживается.

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

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

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

AUTO_INCREMENT, AUTO INCREMENT