Where does MYSQL store logic for "UPDATE CURRENT_TIMESTAMP"


我通常会更新PHP的时间戳列,但刚刚意识到这可以在MySQL DBMS级别进行。因此,我通过用于DB Admin的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'
;
  

该表是按预期创建的,并且每次更新字段时都会更改。

但是,我找不到表中的任何内容来显示该存储的位置(我知道可以正常插入的current_timestamp()),该代码创建的触发器或事件既不是。

那么,这种逻辑存储在哪里?我想还有一些其他表格属性(Aside Extern Keys,索引),但哪些SQLyog不显示?


您可以在信息_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中,所有表格元数据都在.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 - the column is defined DEFAULT CURRENT_TIMESTAMP
  • TIMESTAMP_UN_FIELD - the column is defined ON UPDATE CURRENT_TIMESTAMP
  • TIMESTAMP_DNUN_FIELD - the column is defined with both attributes
  • NONE - the column is defined with neither attribute

这些位如何使用?这被埋葬在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)的帖子,描述了.frm文件:https://planet.mysql.com/entry/?id=17539

You might be wondering, "what is unireg?" It's a database management system developed by Michael Widenius, who is the founder of MySQL. Unireg dates back to 1979 (see https://exadel.com/news/old-reliable-mysql-history/). The design of the .frm文件借入旧的Unireg项目中的代码,根据Stewart的博客,甚至还有一些unireg_check在MySQL中未使用但被Unireg使用的位。

在某些方面,MySQL(就像许多软件一样)就像是在一座被毁坏的罗马城堡的基础上建立的摩天大楼。


Where does MYSQL store logic for "UPDATE CURRENT_TIMESTAMP"的相关文章

随机推荐