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

Изменение данных через загрузку

Таблицы с Primary Key, предоставляемые Selena, позволяют вносить изменения в данные таблиц Selena, выполняя задачи Stream Load, Broker Load или Routine Load. Эти изменения данных включают вставки, обновления и удаления. Однако таблицы с Primary Key не поддерживают изменение данных с использованием Spark Load или INSERT.

Selena также поддерживает частичные обновления и условные обновления.

Вы можете загружать данные в таблицы Selena только как пользователь, имеющий привилегию INSERT на эти таблицы Selena. Если у вас нет привилегии INSERT, следуйте инструкциям в разделе GRANT, чтобы предоставить привилегию INSERT пользователю, которого вы используете для подключения к вашему cluster Selena. Синтаксис: GRANT INSERT ON TABLE <table_name> IN DATABASE <database_name> TO { ROLE <role_name> | USER <user_identity>}.

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

ПРИМЕЧАНИЕ

Для данных CSV вы можете использовать строку UTF-8, такую как запятая (,), табуляция или вертикальная черта (|), длиной не более 50 байт в качестве текстового разделителя.

Реализация

Таблицы с Primary Key, предоставляемые Selena, поддерживают операции UPSERT и DELETE и не различают операции INSERT от операций UPDATE.

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

ПРИМЕЧАНИЕ

При создании таблицы вам не нужно добавлять столбец с именем __op в эту таблицу.

Метод определения поля __op зависит от выбранного вами метода загрузки:

  • Если вы выбираете Stream Load, определите поле __op с помощью параметра columns.

  • Если вы выбираете Broker Load, определите поле __op с помощью предложения SET.

  • Если вы выбираете Routine Load, определите поле __op с помощью столбца COLUMNS.

Вы можете решить, добавлять ли поле __op, в зависимости от изменений данных, которые вы хотите внести. Если вы не добавляете поле __op, тип операции по умолчанию — UPSERT. Основные сценарии изменения данных следующие:

  • Если файл данных, который вы хотите загрузить, включает только операции UPSERT, вам не нужно добавлять поле __op.

  • Если файл данных, который вы хотите загрузить, включает только операции DELETE, вы должны добавить поле __op и указать тип операции как DELETE.

  • Если файл данных, который вы хотите загрузить, включает как операции UPSERT, так и DELETE, вы должны добавить поле __op и убедиться, что файл данных содержит столбец со значениями 0 или 1. Значение 0 указывает на операцию UPSERT, а значение 1 указывает на операцию DELETE.

Примечания по использованию

  • Убедитесь, что каждая строка в вашем файле данных имеет одинаковое количество столбцов.

  • Столбцы, в которые вносятся изменения данных, должны включать столбец первичного ключа.

Базовые операции

В этом разделе приведены примеры того, как вносить изменения в данные таблицы Selena через загрузку. Для получения подробного синтаксиса и описания параметров см. STREAM LOAD, BROKER LOAD и CREATE ROUTINE LOAD.

UPSERT

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

ПРИМЕЧАНИЕ

Если вы добавляете поле __op:

  • Вы можете указать тип операции как UPSERT.

  • Вы можете оставить поле __op пустым, поскольку тип операции по умолчанию — UPSERT.

Примеры данных

  1. Подготовьте файл данных.

    a. Создайте CSV-файл с именем example1.csv в вашей локальной файловой системе. Файл состоит из трёх столбцов, которые представляют идентификатор пользователя, имя пользователя и оценку пользователя соответственно.

    101,Lily,100
    102,Rose,100

    b. Опубликуйте данные example1.csv в topic1 вашего cluster Kafka.

  2. Подготовьте таблицу Selena.

    a. Создайте таблицу с Primary Key с именем table1 в вашей базе данных Selena test_db. Таблица состоит из трёх столбцов: id, name и score, из которых id является первичным ключом.

    CREATE TABLE `table1`
    (
    `id` int(11) NOT NULL COMMENT "user ID",
    `name` varchar(65533) NOT NULL COMMENT "user name",
    `score` int(11) NOT NULL COMMENT "user score"
    )
    ENGINE=OLAP
    PRIMARY KEY(`id`)
    DISTRIBUTED BY HASH(`id`);

    ПРИМЕЧАНИЕ

    Начиная с версии v1.5.2, Selena может автоматически устанавливать количество bucket (BUCKETS) при создании таблицы или добавлении partition. Вам больше не нужно вручную устанавливать количество bucket. Для получения подробной информации см. установка количества bucket.

    b. Вставьте запись в table1.

    INSERT INTO table1 VALUES
    (101, 'Lily',80);

Загрузка данных

Запустите задачу загрузки, чтобы обновить запись с id равным 101 из example1.csv в table1 и вставить запись с id равным 102 из example1.csv в table1.

  • Запустите задачу Stream Load.

    • Если вы не хотите включать поле __op, выполните следующую команду:

      curl --location-trusted -u <username>:<password> \
      -H "Expect:100-continue" \
      -H "label:label1" \
      -H "column_separator:," \
      -T example1.csv -XPUT \
      http://<fe_host>:<fe_http_port>/api/test_db/table1/_stream_load
    • Если вы хотите включить поле __op, выполните следующую команду:

      curl --location-trusted -u <username>:<password> \
      -H "Expect:100-continue" \
      -H "label:label2" \
      -H "column_separator:," \
      -H "columns:__op ='upsert'" \
      -T example1.csv -XPUT \
      http://<fe_host>:<fe_http_port>/api/test_db/table1/_stream_load
  • Запустите задачу Broker Load.

    • Если вы не хотите включать поле __op, выполните следующую команду:

      LOAD LABEL test_db.label1
      (
      data infile("hdfs://<hdfs_host>:<hdfs_port>/example1.csv")
      into table table1
      columns terminated by ","
      format as "csv"
      )
      WITH BROKER;
    • Если вы хотите включить поле __op, выполните следующую команду:

      LOAD LABEL test_db.label2
      (
      data infile("hdfs://<hdfs_host>:<hdfs_port>/example1.csv")
      into table table1
      columns terminated by ","
      format as "csv"
      set (__op = 'upsert')
      )
      WITH BROKER;
  • Запустите задачу Routine Load.

    • Если вы не хотите включать поле __op, выполните следующую команду:

      CREATE ROUTINE LOAD test_db.table1 ON table1
      COLUMNS TERMINATED BY ",",
      COLUMNS (id, name, score)
      PROPERTIES
      (
      "desired_concurrent_number" = "3",
      "max_batch_interval" = "20",
      "max_batch_rows"= "250000",
      "max_error_number" = "1000"
      )
      FROM KAFKA
      (
      "kafka_broker_list" ="<kafka_broker_host>:<kafka_broker_port>",
      "kafka_topic" = "test1",
      "property.kafka_default_offsets" ="OFFSET_BEGINNING"
      );
    • Если вы хотите включить поле __op, выполните следующую команду:

      CREATE ROUTINE LOAD test_db.table1 ON table1
      COLUMNS TERMINATED BY ",",
      COLUMNS (id, name, score, __op ='upsert')
      PROPERTIES
      (
      "desired_concurrent_number" = "3",
      "max_batch_interval" = "20",
      "max_batch_rows"= "250000",
      "max_error_number" = "1000"
      )
      FROM KAFKA
      (
      "kafka_broker_list" ="<kafka_broker_host>:<kafka_broker_port>",
      "kafka_topic" = "test1",
      "property.kafka_default_offsets" ="OFFSET_BEGINNING"
      );

Запрос данных

После завершения загрузки запросите данные table1, чтобы убедиться, что загрузка прошла успешно:

SELECT * FROM table1;
+------+------+-------+
| id | name | score |
+------+------+-------+
| 101 | Lily | 100 |
| 102 | Rose | 100 |
+------+------+-------+
2 rows in set (0.02 sec)

Как показано в результате запроса выше, запись с id равным 101 из example1.csv была обновлена в table1, а запись с id равным 102 из example1.csv была вставлена в table1.

DELETE

Если файл данных, который вы хотите загрузить, включает только операции DELETE, вы должны добавить поле __op и указать тип операции как DELETE.

Примеры данных

  1. Подготовьте файл данных.

    a. Создайте CSV-файл с именем example2.csv в вашей локальной файловой системе. Файл состоит из трёх столбцов, которые представляют идентификатор пользователя, имя пользователя и оценку пользователя соответственно.

    101,Jack,100

    b. Опубликуйте данные example2.csv в topic2 вашего cluster Kafka.

  2. Подготовьте таблицу Selena.

    a. Создайте таблицу с Primary Key с именем table2 в вашей базе данных Selena test_db. Таблица состоит из трёх столбцов: id, name и score, из которых id является первичным ключом.

    CREATE TABLE `table2`
    (
    `id` int(11) NOT NULL COMMENT "user ID",
    `name` varchar(65533) NOT NULL COMMENT "user name",
    `score` int(11) NOT NULL COMMENT "user score"
    )
    ENGINE=OLAP
    PRIMARY KEY(`id`)
    DISTRIBUTED BY HASH(`id`);

    ПРИМЕЧАНИЕ

    Начиная с версии v1.5.2, Selena может автоматически устанавливать количество bucket (BUCKETS) при создании таблицы или добавлении partition. Вам больше не нужно вручную устанавливать количество bucket. Для получения подробной информации см. установка количества bucket.

    b. Вставьте две записи в table2.

    INSERT INTO table2 VALUES
    (101, 'Jack', 100),
    (102, 'Bob', 90);

Загрузка данных

Запустите задачу загрузки, чтобы удалить запись с id равным 101 из example2.csv из table2.

  • Запустите задачу Stream Load.

    curl --location-trusted -u <username>:<password> \
    -H "Expect:100-continue" \
    -H "label:label3" \
    -H "column_separator:," \
    -H "columns:__op='delete'" \
    -T example2.csv -XPUT \
    http://<fe_host>:<fe_http_port>/api/test_db/table2/_stream_load
  • Запустите задачу Broker Load.

    LOAD LABEL test_db.label3
    (
    data infile("hdfs://<hdfs_host>:<hdfs_port>/example2.csv")
    into table table2
    columns terminated by ","
    format as "csv"
    set (__op = 'delete')
    )
    WITH BROKER;
  • Запустите задачу Routine Load.

    CREATE ROUTINE LOAD test_db.table2 ON table2
    COLUMNS(id, name, score, __op = 'delete')
    PROPERTIES
    (
    "desired_concurrent_number" = "3",
    "max_batch_interval" = "20",
    "max_batch_rows"= "250000",
    "max_error_number" = "1000"
    )
    FROM KAFKA
    (
    "kafka_broker_list" ="<kafka_broker_host>:<kafka_broker_port>",
    "kafka_topic" = "test2",
    "property.kafka_default_offsets" ="OFFSET_BEGINNING"
    );

Запрос данных

После завершения загрузки запросите данные table2, чтобы убедиться, что загрузка прошла успешно:

SELECT * FROM table2;
+------+------+-------+
| id | name | score |
+------+------+-------+
| 102 | Bob | 90 |
+------+------+-------+
1 row in set (0.00 sec)

Как показано в результате запроса выше, запись с id равным 101 из example2.csv была удалена из table2.

UPSERT и DELETE

Если файл данных, который вы хотите загрузить, включает как операции UPSERT, так и DELETE, вы должны добавить поле __op и убедиться, что файл данных содержит столбец со значениями 0 или 1. Значение 0 указывает на операцию UPSERT, а значение 1 указывает на операцию DELETE.

Примеры данных

  1. Подготовьте файл данных.

    a. Создайте CSV-файл с именем example3.csv в вашей локальной файловой системе. Файл состоит из четырёх столбцов, которые представляют идентификатор пользователя, имя пользователя, оценку пользователя и тип операции соответственно.

    101,Tom,100,1
    102,Sam,70,0
    103,Stan,80,0

    b. Опубликуйте данные example3.csv в topic3 вашего cluster Kafka.

  2. Подготовьте таблицу Selena.

    a. Создайте таблицу с Primary Key с именем table3 в вашей базе данных Selena test_db. Таблица состоит из трёх столбцов: id, name и score, из которых id является первичным ключом.

    CREATE TABLE `table3`
    (
    `id` int(11) NOT NULL COMMENT "user ID",
    `name` varchar(65533) NOT NULL COMMENT "user name",
    `score` int(11) NOT NULL COMMENT "user score"
    )
    ENGINE=OLAP
    PRIMARY KEY(`id`)
    DISTRIBUTED BY HASH(`id`);

    ПРИМЕЧАНИЕ

    Начиная с версии v1.5.2, Selena может автоматически устанавливать количество bucket (BUCKETS) при создании таблицы или добавлении partition. Вам больше не нужно вручную устанавливать количество bucket. Для получения подробной информации см. установка количества bucket.

    b. Вставьте две записи в table3.

    INSERT INTO table3 VALUES
    (101, 'Tom', 100),
    (102, 'Sam', 90);

Загрузка данных

Запустите задачу загрузки, чтобы удалить запись с id равным 101 из example3.csv из table3, обновить запись с id равным 102 из example3.csv в table3 и вставить запись с id равным 103 из example3.csv в table3.

  • Запустите задачу Stream Load:

    curl --location-trusted -u <username>:<password> \
    -H "Expect:100-continue" \
    -H "label:label4" \
    -H "column_separator:," \
    -H "columns: id, name, score, temp, __op = temp" \
    -T example3.csv -XPUT \
    http://<fe_host>:<fe_http_port>/api/test_db/table3/_stream_load

    ПРИМЕЧАНИЕ

    В приведённом выше примере четвёртый столбец, представляющий тип операции в example3.csv, временно называется temp, и поле __op сопоставляется со столбцом temp с помощью параметра columns. Таким образом, Selena может решить, выполнять ли операцию UPSERT или DELETE, в зависимости от того, равно ли значение в четвёртом столбце example3.csv 0 или 1.

  • Запустите задачу Broker Load:

    LOAD LABEL test_db.label4
    (
    data infile("hdfs://<hdfs_host>:<hdfs_port>/example1.csv")
    into table table1
    columns terminated by ","
    format as "csv"
    (id, name, score, temp)
    set (__op=temp)
    )
    WITH BROKER;
  • Запустите задачу Routine Load:

    CREATE ROUTINE LOAD test_db.table3 ON table3
    COLUMNS(id, name, score, temp, __op = temp)
    PROPERTIES
    (
    "desired_concurrent_number" = "3",
    "max_batch_interval" = "20",
    "max_batch_rows"= "250000",
    "max_error_number" = "1000"
    )
    FROM KAFKA
    (
    "kafka_broker_list" = "<kafka_broker_host>:<kafka_broker_port>",
    "kafka_topic" = "test3",
    "property.kafka_default_offsets" = "OFFSET_BEGINNING"
    );

Запрос данных

После завершения загрузки запросите данные table3, чтобы убедиться, что загрузка прошла успешно:

SELECT * FROM table3;
+------+------+-------+
| id | name | score |
+------+------+-------+
| 102 | Sam | 70 |
| 103 | Stan | 80 |
+------+------+-------+
2 rows in set (0.01 sec)

Как показано в результате запроса выше, запись с id равным 101 из example3.csv была удалена из table3, запись с id равным 102 из example3.csv была обновлена в table3, а запись с id равным 103 из example3.csv была вставлена в table3.

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

Таблицы с Primary Key также поддерживают частичные обновления и предоставляют два режима частичных обновлений — строчный режим и колоночный режим — для различных сценариев обновления данных. Эти два режима частичных обновлений могут минимизировать накладные расходы на частичные обновления, насколько это возможно, гарантируя при этом производительность запросов и обеспечивая обновления в реальном времени. Строчный режим более подходит для сценариев обновления в реальном времени, включающих множество столбцов и небольшие пакеты. Колоночный режим подходит для сценариев пакетной обработки обновлений, включающих несколько столбцов и большое количество строк.

ВНИМАНИЕ

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

В этом разделе используется CSV в качестве примера для описания того, как выполнять частичные обновления.

Примеры данных

  1. Подготовьте файл данных.

    a. Создайте CSV-файл с именем example4.csv в вашей локальной файловой системе. Файл состоит из двух столбцов, которые представляют идентификатор пользователя и имя пользователя соответственно.

    101,Lily
    102,Rose
    103,Alice

    b. Опубликуйте данные example4.csv в topic4 вашего cluster Kafka.

  2. Подготовьте таблицу Selena.

    a. Создайте таблицу с Primary Key с именем table4 в вашей базе данных Selena test_db. Таблица состоит из трёх столбцов: id, name и score, из которых id является первичным ключом.

    CREATE TABLE `table4`
    (
    `id` int(11) NOT NULL COMMENT "user ID",
    `name` varchar(65533) NOT NULL COMMENT "user name",
    `score` int(11) NOT NULL COMMENT "user score"
    )
    ENGINE=OLAP
    PRIMARY KEY(`id`)
    DISTRIBUTED BY HASH(`id`);

    ПРИМЕЧАНИЕ

    Начиная с версии v1.5.2, Selena может автоматически устанавливать количество bucket (BUCKETS) при создании таблицы или добавлении partition. Вам больше не нужно вручную устанавливать количество bucket. Для получения подробной информации см. установка количества bucket.

    b. Вставьте запись в table4.

    INSERT INTO table4 VALUES
    (101, 'Tom',80);

Загрузка данных

Запустите загрузку для обновления данных в двух столбцах example4.csv в столбцы id и name таблицы table4.

  • Запустите задачу Stream Load:

    curl --location-trusted -u <username>:<password> \
    -H "Expect:100-continue" \
    -H "label:label7" -H "column_separator:," \
    -H "partial_update:true" \
    -H "columns:id,name" \
    -T example4.csv -XPUT \
    http://<fe_host>:<fe_http_port>/api/test_db/table4/_stream_load

    ПРИМЕЧАНИЕ

    Если вы выбираете Stream Load, вы должны установить параметр partial_update в значение true, чтобы включить функцию частичного обновления. По умолчанию используются частичные обновления в строчном режиме. Если вам нужно выполнить частичные обновления в колоночном режиме, вам нужно установить partial_update_mode в значение column. Кроме того, вы должны использовать параметр columns, чтобы указать столбцы, которые вы хотите обновить.

  • Запустите задачу Broker Load:

    LOAD LABEL test_db.table4
    (
    data infile("hdfs://<hdfs_host>:<hdfs_port>/example4.csv")
    into table table4
    format as "csv"
    (id, name)
    )
    WITH BROKER
    PROPERTIES
    (
    "partial_update" = "true"
    );

    ПРИМЕЧАНИЕ

    Если вы выбираете Broker Load, вы должны установить параметр partial_update в значение true, чтобы включить функцию частичного обновления. По умолчанию используются частичные обновления в строчном режиме. Если вам нужно выполнить частичные обновления в колоночном режиме, вам нужно установить partial_update_mode в значение column. Кроме того, вы должны использовать параметр column_list, чтобы указать столбцы, которые вы хотите обновить.

  • Запустите задачу Routine Load:

    CREATE ROUTINE LOAD test_db.table4 on table4
    COLUMNS (id, name),
    COLUMNS TERMINATED BY ','
    PROPERTIES
    (
    "partial_update" = "true"
    )
    FROM KAFKA
    (
    "kafka_broker_list" ="<kafka_broker_host>:<kafka_broker_port>",
    "kafka_topic" = "test4",
    "property.kafka_default_offsets" ="OFFSET_BEGINNING"
    );

    ПРИМЕЧАНИЕ

    • Если вы выбираете Routine Load, вы должны установить параметр partial_update в значение true, чтобы включить функцию частичного обновления. Кроме того, вы должны использовать параметр COLUMNS, чтобы указать столбцы, которые вы хотите обновить.
    • Routine Load поддерживает только частичные обновления в строчном режиме и не поддерживает частичные обновления в колоночном режиме.

Запрос данных

После завершения загрузки запросите данные table4, чтобы убедиться, что загрузка прошла успешно:

SELECT * FROM table4;
+------+-------+-------+
| id | name | score |
+------+-------+-------+
| 102 | Rose | 0 |
| 101 | Lily | 80 |
| 103 | Alice | 0 |
+------+-------+-------+
3 rows in set (0.01 sec)

Как показано в результате запроса выше, запись с id равным 101 из example4.csv была обновлена в table4, а записи с id равными 102 и 103 из example4.csv были вставлены в table4.

Условные обновления

Начиная с Selena v1.5.2, таблицы с Primary Key поддерживают условные обновления. Вы можете указать столбец, не являющийся первичным ключом, в качестве условия для определения того, могут ли обновления вступить в силу. Таким образом, обновление от исходной записи к целевой записи вступает в силу только тогда, когда запись исходных данных имеет значение большее или равное значению записи целевых данных в указанном столбце.

Функция условного обновления предназначена для решения проблемы неупорядоченности данных. Если исходные данные неупорядочены, вы можете использовать эту функцию, чтобы гарантировать, что новые данные не будут перезаписаны старыми данными.

ВНИМАНИЕ

  • Вы не можете указать разные столбцы в качестве условий обновления для одной и той же партии данных.
  • Операции DELETE не поддерживают условные обновления.
  • В версиях ранее v1.5.2 частичные обновления и условные обновления не могут использоваться одновременно. Начиная с версии v1.5.2, Selena поддерживает использование частичных обновлений вместе с условными обновлениями.

Примеры данных

  1. Подготовьте файл данных.

    a. Создайте CSV-файл с именем example5.csv в вашей локальной файловой системе. Файл состоит из трёх столбцов, которые представляют идентификатор пользователя, версию и оценку пользователя соответственно.

    101,1,100
    102,3,100

    b. Опубликуйте данные example5.csv в topic5 вашего cluster Kafka.

  2. Подготовьте таблицу Selena.

    a. Создайте таблицу с Primary Key с именем table5 в вашей базе данных Selena test_db. Таблица состоит из трёх столбцов: id, version и score, из которых id является первичным ключом.

    CREATE TABLE `table5`
    (
    `id` int(11) NOT NULL COMMENT "user ID",
    `version` int NOT NULL COMMENT "version",
    `score` int(11) NOT NULL COMMENT "user score"
    )
    ENGINE=OLAP
    PRIMARY KEY(`id`) DISTRIBUTED BY HASH(`id`);

    ПРИМЕЧАНИЕ

    Начиная с версии v1.5.2, Selena может автоматически устанавливать количество bucket (BUCKETS) при создании таблицы или добавлении partition. Вам больше не нужно вручную устанавливать количество bucket. Для получения подробной информации см. установка количества bucket.

    b. Вставьте запись в table5.

    INSERT INTO table5 VALUES
    (101, 2, 80),
    (102, 2, 90);

Загрузка данных

Запустите загрузку для обновления записей с значениями id равными 101 и 102 соответственно из example5.csv в table5 и укажите, что обновления вступают в силу только тогда, когда значение version в каждой из двух записей больше или равно их текущим значениям version.

  • Запустите задачу Stream Load:

    curl --location-trusted -u <username>:<password> \
    -H "Expect:100-continue" \
    -H "label:label10" \
    -H "column_separator:," \
    -H "merge_condition:version" \
    -T example5.csv -XPUT \
    http://<fe_host>:<fe_http_port>/api/test_db/table5/_stream_load
  • Запустите задачу Insert Load:

    INSERT INTO test_db.table5 properties("merge_condition" = "version")
    VALUES (101, 2, 70), (102, 3, 100);
  • Запустите задачу Routine Load:

    CREATE ROUTINE LOAD test_db.table5 on table5
    COLUMNS (id, version, score),
    COLUMNS TERMINATED BY ','
    PROPERTIES
    (
    "merge_condition" = "version"
    )
    FROM KAFKA
    (
    "kafka_broker_list" ="<kafka_broker_host>:<kafka_broker_port>",
    "kafka_topic" = "topic5",
    "property.kafka_default_offsets" ="OFFSET_BEGINNING"
    );
  • Запустите задачу Broker Load:

    LOAD LABEL test_db.table5
    ( DATA INFILE ("s3://xxx.csv")
    INTO TABLE table5 COLUMNS TERMINATED BY "," FORMAT AS "CSV"
    )
    WITH BROKER
    PROPERTIES
    (
    "merge_condition" = "version"
    );

Запрос данных

После завершения загрузки запросите данные table5, чтобы убедиться, что загрузка прошла успешно:

SELECT * FROM table5;
+------+------+-------+
| id | version | score |
+------+------+-------+
| 101 | 2 | 80 |
| 102 | 3 | 100 |
+------+------+-------+
2 rows in set (0.02 sec)

Как показано в результате запроса выше, запись с id равным 101 из example5.csv не была обновлена в table5, а запись с id равным 102 из example5.csv была вставлена в table5.