时间戳字段仅在 MariaDB 中插入时结合 'LOAD DATA LOCAL INFILE' 数据加载

Timestamp field only on insert in MariaDB, combined with 'LOAD DATA LOCAL INFILE' data load

我希望 MySQL table 中的时间戳字段仅在插入时设置,而不是在更新时设置。 table 是这样创建的:

CREATE TABLE `test_insert_timestamp` (
  `key` integer NOT NULL,
  `value` integer NOT NULL,
  `insert_timestamp` timestamp DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`key`)
);

加载数据用这句话(需要用到LOAD DATA LOCAL INFILE):

LOAD DATA LOCAL INFILE 
   "inserts_test_timestamp1.txt"
REPLACE
INTO TABLE 
    `test_insert_timestamp`
FIELDS TERMINATED BY ';'

注意:不管为什么,我都需要使用 REPLACE 选项。 inserts_test_timestamp**1**.txt 的内容是:

1;2
3;4

我有另一个文件 inserts_test_timestamp**2**.txt 是:

3;4
5;6

我不会的是:

  1. 如果我加载文件 inserts_test_timestamp**1**.txt 则字段 insert_timestamp 被设置(代码没问题)

  2. 如果我加载 inserts_test_timestamp**2**.txt,记录 (3;4) 不更改字段 insert_timestamp 已经设置,但记录 (5;6) 设置新的 insert_timestamp.

但没办法。两条记录都带有相同值的时间戳,而不是旧时间戳左 (3;4)。

我正在开发 MariaDB 5.5.52 数据库 CentOS 7.3 版本。认为 MariaDB 版本很重要,但我无法更改。

您可以将过程分为两步:

MariaDB [_]> DROP TABLE IF EXISTS
    ->   `temp_test_insert_timestamp`,
    ->   `test_insert_timestamp`;
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> CREATE TABLE IF NOT EXISTS `test_insert_timestamp` (
    ->   `key` integer NOT NULL,
    ->   `value` integer NOT NULL,
    ->   `insert_timestamp` timestamp DEFAULT CURRENT_TIMESTAMP,
    ->   PRIMARY KEY (`key`)
    -> );
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> CREATE TABLE IF NOT EXISTS `temp_test_insert_timestamp` (
    ->   `key` integer NOT NULL,
    ->   `value` integer NOT NULL,
    ->   `insert_timestamp` timestamp DEFAULT CURRENT_TIMESTAMP,
    ->   PRIMARY KEY (`key`)
    -> );
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> LOAD DATA LOCAL INFILE '/path/to/file/inserts_test_timestamp1.txt'
    -> INTO TABLE `test_insert_timestamp`
    -> FIELDS TERMINATED BY ';'
    -> (`key`, `value`);
Query OK, 2 rows affected (0.00 sec)                 
Records: 2  Deleted: 0  Skipped: 0  Warnings: 0

MariaDB [_]> SELECT
    ->   `key`,
    ->   `value`,
    ->   `insert_timestamp`
    -> FROM
    ->   `test_insert_timestamp`;
+-----+-------+---------------------+
| key | value | insert_timestamp    |
+-----+-------+---------------------+
|   1 |     2 | 2018-03-20 00:49:38 |
|   3 |     4 | 2018-03-20 00:49:38 |
+-----+-------+---------------------+
2 rows in set (0.00 sec)

MariaDB [_]> DO SLEEP(5);
Query OK, 0 rows affected (5.00 sec)

MariaDB [_]> LOAD DATA LOCAL INFILE '/path/to/file/inserts_test_timestamp2.txt'
    -> INTO TABLE `temp_test_insert_timestamp`
    -> FIELDS TERMINATED BY ';'
    -> (`key`, `value`);
Query OK, 2 rows affected (0.00 sec)                 
Records: 2  Deleted: 0  Skipped: 0  Warnings: 0

MariaDB [_]> SELECT
    ->   `key`,
    ->   `value`,
    ->   `insert_timestamp`
    -> FROM
    ->   `temp_test_insert_timestamp`;
+-----+-------+---------------------+
| key | value | insert_timestamp    |
+-----+-------+---------------------+
|   3 |     4 | 2018-03-20 00:49:43 |
|   5 |     6 | 2018-03-20 00:49:43 |
+-----+-------+---------------------+
2 rows in set (0.00 sec)

MariaDB [_]> REPLACE INTO `test_insert_timestamp`
    -> SELECT
    ->   `ttit`.`key`,
    ->   `ttit`.`value`,
    ->   `tit`.`insert_timestamp`
    -> FROM
    ->   `temp_test_insert_timestamp` `ttit`
    ->   LEFT JOIN `test_insert_timestamp` `tit`
    ->   ON `ttit`.`key` = `tit`.`key`;
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

MariaDB [_]> SELECT
    ->   `key`,
    ->   `value`,
    ->   `insert_timestamp`
    -> FROM
    ->   `test_insert_timestamp`;
+-----+-------+---------------------+
| key | value | insert_timestamp    |
+-----+-------+---------------------+
|   1 |     2 | 2018-03-20 00:49:38 |
|   3 |     4 | 2018-03-20 00:49:38 |
|   5 |     6 | 2018-03-20 00:49:43 |
+-----+-------+---------------------+
3 rows in set (0.00 sec)

MariaDB [_]> TRUNCATE TABLE `temp_test_insert_timestamp`;
Query OK, 0 rows affected (0.00 sec)

我在这个post中实现了解决方案:MySQL LOAD DATA INFILE with ON DUPLICATE KEY UPDATE

这个解决方案不仅可以让我得到 insert_timestamp,还可以让我得到一个带有 update_timestamp:

的字段
# --- Create temporary table ---
CREATE TEMPORARY TABLE temporary_table LIKE test_insert_timestamp;

# --- Delete index to speed up
DROP INDEX `PRIMARY` ON temporary_table;
DROP INDEX `STAMP_INDEX` ON temporary_table;

# --- Load data in temporary table
LOAD DATA LOCAL INFILE "./inserts_test_timestamp1.txt"
INTO TABLE temporary_table
FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"'
IGNORE 1 LINES
SET
        insert_timestamp = CURRENT_TIMESTAMP(),
        update_timestamp = NULL
;

# --- Insert data in temporary table ---
INSERT INTO test_insert_timestamp
SELECT * FROM temporary_table
ON DUPLICATE KEY UPDATE
   update_timestamp = CURRENT_TIMESTAMP();

# --- Drop temporary
DROP TEMPORARY TABLE temporary_table;

感谢帮助!