MYSQL 在哪里存储 "UPDATE CURRENT_TIMESTAMP" 的逻辑
Where does MYSQL store logic for "UPDATE CURRENT_TIMESTAMP"
我通常会从 PHP 更新时间戳列,但我刚刚意识到这可以在 MySQL DBMS 级别完成。因此,我通过用于数据库管理员的 SQLYog 找到并测试了以下代码:
CREATE TABLE `TestLastUpdate` (
`ID` INT NULL,
`Name` VARCHAR(50) NULL,
`Address` VARCHAR(50) NULL,
`LastUpdate` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
COMMENT='Last Update'
;
table 已按预期创建,每次更新字段时 LastUpdate 都会更改。
但是我在 table 信息中找不到任何东西来显示它的存储位置(据我所知,current_timestamp() 通常用于插入),也不是由创建的触发器或事件此代码。
那么这个逻辑存储在哪里?我想还有一些其他 table 属性(除了外键、索引) MySQL 保留但 SQLYog 不显示?
您可以在 INFORMATION_SCHEMA:
中看到时间戳列的这些属性
mysql> create table test.mytable (id serial primary key, ts timestamp default current_timestamp on update current_timestamp);
mysql> select table_name, column_name, column_default, extra from information_schema.columns where table_name='mytable';
+------------+-------------+-------------------+-----------------------------+
| table_name | column_name | column_default | extra |
+------------+-------------+-------------------+-----------------------------+
| mytable | id | NULL | auto_increment |
| mytable | ts | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+-------------+-------------------+-----------------------------+
在 8.0 之前的 MySQL 中,所有 table 元数据都在与您的 table.
对应的 .frm
文件中
$ ls -l /usr/local/var/mysql/test
total 256
-rw-r----- 1 bkarwin admin 67 Jun 16 10:04 db.opt
-rw-r----- 1 bkarwin admin 8582 Jul 1 07:05 mytable.frm
-rw-r----- 1 bkarwin admin 114688 Jul 1 07:05 mytable.ibd
在 .frm
文件中,有一个名为 unireg_check
的位域,用于存储列的属性。其中一些位是:
- TIMESTAMP_DN_FIELD - 列已定义
DEFAULT CURRENT_TIMESTAMP
- TIMESTAMP_UN_FIELD - 列已定义
ON UPDATE CURRENT_TIMESTAMP
- TIMESTAMP_DNUN_FIELD - 该列是
定义了两个属性
- NONE - 该列未定义任何属性
如何使用这些位?这深埋在 MySQL 源代码中。都是特例代码。
https://github.com/mysql/mysql-server/blob/5.7/sql/sql_table.cc#L7822-L7844
/*
Set CURRENT_TIMESTAMP as default/update value based on
the unireg_check value.
*/
if ((def->sql_type == MYSQL_TYPE_DATETIME ||
def->sql_type == MYSQL_TYPE_TIMESTAMP)
&& (def->unireg_check != Field::NONE))
{
Item_func_now_local *now = new (thd->mem_root) Item_func_now_local(0);
if (!now)
DBUG_RETURN(true);
if (def->unireg_check == Field::TIMESTAMP_DN_FIELD)
default_value= now;
else if (def->unireg_check == Field::TIMESTAMP_UN_FIELD)
update_value= now;
else if (def->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
{
update_value= now;
default_value= now;
}
}
这是前工程总监 Stewart Smith 的 post 描述 .frm
文件的用法:https://planet.mysql.com/entry/?id=17539
您可能想知道,“什么是 unireg?”它是由 MySQL 的创始人 Michael Widenius 开发的数据库管理系统。 Unireg 的历史可以追溯到 1979 年(参见 https://exadel.com/news/old-reliable-mysql-history/)。 .frm
文件的设计借用了旧 Unireg 项目的代码,根据 Stewart 的博客,unireg_check
位域中甚至有一些位在 MySQL 中未使用但被使用由 Unireg.
在某些方面,MySQL — 就像很多软件一样 — 就像一座建立在罗马城堡废墟地基上的摩天大楼。
我通常会从 PHP 更新时间戳列,但我刚刚意识到这可以在 MySQL DBMS 级别完成。因此,我通过用于数据库管理员的 SQLYog 找到并测试了以下代码:
CREATE TABLE `TestLastUpdate` (
`ID` INT NULL,
`Name` VARCHAR(50) NULL,
`Address` VARCHAR(50) NULL,
`LastUpdate` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
COMMENT='Last Update'
;
table 已按预期创建,每次更新字段时 LastUpdate 都会更改。
但是我在 table 信息中找不到任何东西来显示它的存储位置(据我所知,current_timestamp() 通常用于插入),也不是由创建的触发器或事件此代码。
那么这个逻辑存储在哪里?我想还有一些其他 table 属性(除了外键、索引) MySQL 保留但 SQLYog 不显示?
您可以在 INFORMATION_SCHEMA:
中看到时间戳列的这些属性mysql> create table test.mytable (id serial primary key, ts timestamp default current_timestamp on update current_timestamp);
mysql> select table_name, column_name, column_default, extra from information_schema.columns where table_name='mytable';
+------------+-------------+-------------------+-----------------------------+
| table_name | column_name | column_default | extra |
+------------+-------------+-------------------+-----------------------------+
| mytable | id | NULL | auto_increment |
| mytable | ts | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+-------------+-------------------+-----------------------------+
在 8.0 之前的 MySQL 中,所有 table 元数据都在与您的 table.
对应的.frm
文件中
$ ls -l /usr/local/var/mysql/test
total 256
-rw-r----- 1 bkarwin admin 67 Jun 16 10:04 db.opt
-rw-r----- 1 bkarwin admin 8582 Jul 1 07:05 mytable.frm
-rw-r----- 1 bkarwin admin 114688 Jul 1 07:05 mytable.ibd
在 .frm
文件中,有一个名为 unireg_check
的位域,用于存储列的属性。其中一些位是:
- TIMESTAMP_DN_FIELD - 列已定义
DEFAULT CURRENT_TIMESTAMP
- TIMESTAMP_UN_FIELD - 列已定义
ON UPDATE CURRENT_TIMESTAMP
- TIMESTAMP_DNUN_FIELD - 该列是 定义了两个属性
- NONE - 该列未定义任何属性
如何使用这些位?这深埋在 MySQL 源代码中。都是特例代码。
https://github.com/mysql/mysql-server/blob/5.7/sql/sql_table.cc#L7822-L7844
/* Set CURRENT_TIMESTAMP as default/update value based on the unireg_check value. */ if ((def->sql_type == MYSQL_TYPE_DATETIME || def->sql_type == MYSQL_TYPE_TIMESTAMP) && (def->unireg_check != Field::NONE)) { Item_func_now_local *now = new (thd->mem_root) Item_func_now_local(0); if (!now) DBUG_RETURN(true); if (def->unireg_check == Field::TIMESTAMP_DN_FIELD) default_value= now; else if (def->unireg_check == Field::TIMESTAMP_UN_FIELD) update_value= now; else if (def->unireg_check == Field::TIMESTAMP_DNUN_FIELD) { update_value= now; default_value= now; } }
这是前工程总监 Stewart Smith 的 post 描述 .frm
文件的用法:https://planet.mysql.com/entry/?id=17539
您可能想知道,“什么是 unireg?”它是由 MySQL 的创始人 Michael Widenius 开发的数据库管理系统。 Unireg 的历史可以追溯到 1979 年(参见 https://exadel.com/news/old-reliable-mysql-history/)。 .frm
文件的设计借用了旧 Unireg 项目的代码,根据 Stewart 的博客,unireg_check
位域中甚至有一些位在 MySQL 中未使用但被使用由 Unireg.
在某些方面,MySQL — 就像很多软件一样 — 就像一座建立在罗马城堡废墟地基上的摩天大楼。