MariaDB 5.5 create table default value 需要注意的事项

MariaDB 5.5 create table default value 需要注意的事项

  • 主要是时间戳datestamp和varchar的默认值的问题
    • 1. 时间戳datestamp-ERROR 1293(HY000)
    • 2. 扩展——5.5的日期格式
    • 3. varchar设置默认值报错 ERROR 1064 (42000)
    • 4. centOS 7 使用MariaDB的注意事项
    • 5. centOS 7 安装新版本的MariaDB

主要是时间戳datestamp和varchar的默认值的问题

本地开发环境用的是mysql 8.0.17,而服务器因为使用的是centOS 7,所以默认装的DB是MariaDB 5.5.因此让我发现在建表时候,两个版本之间的巨大差异。本次仅针对ERROR 1293 (HY000)和1064 (42000)这两个错误。

1. 时间戳datestamp-ERROR 1293(HY000)

首先,需求是:有几个字段是需要记录时间的,但是为了防止为空,所以给了默认值,默认值是当前系统的时间。上代码:

drop table  IF EXISTS test.`t_test`;
CREATE TABLE test.`t_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`firstLoginTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`lastLoginTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;

上述语句建表失败
上面的建表语句,在我本地的环境(mysql 8.0.17)是可以完美运行的,并且测试了插入空数据,默认值确实是当前时间。这里请注意,我对于createTime,firstLoginTimelastLoginTime这三个字段,都是设置的timestamp,并且默认值都是CURRENT_TIMESTAMP。然后使用该语句到服务器(centOS 7)上面的环境运行(MariaDB 5.5)运行,直接报错,建表失败。
错误信息:
ERROR 1293 (HY000) at line 6 in file: 'test.sql': Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

单纯分析错误提示,大概意思是,你只能给一个TIMESTAMP类型的列赋值CURRENT_TIMESTAMP
测试1:去掉三个default值

use test;
drop table  IF EXISTS test.`t_test`;
CREATE TABLE test.`t_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`createTime` timestamp NOT NULL,
`firstLoginTime` timestamp NOT NULL,
`lastLoginTime` timestamp NOT NULL ,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; 

可以成功建表。

  1. 测试插入数据insert into test.t_test (id) values(1);
    结果:

     +----+---------------------+---------------------+---------------------+
     | id | createTime          | firstLoginTime      | lastLoginTime       |
     +----+---------------------+---------------------+---------------------+
     |  1 | 2020-04-20 13:53:33 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
     +----+---------------------+---------------------+---------------------+
     1 row in set (0.00 sec)
    

可以知道,对于timestamp类型的,加入你不传值,那么第一个这个类型的字段,会默认为当前系统时间。但是还有两个字段并未满足我的需求,因此还需测试。
2. 测试插入数据insert into test.t_test (id,createTime,firstLoginTime,lastLoginTime) values(2,null,null,null);
结果:

+----+---------------------+---------------------+---------------------+
| id | createTime          | firstLoginTime      | lastLoginTime       |
+----+---------------------+---------------------+---------------------+
|  1 | 2020-04-20 13:53:33 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
|  2 | 2020-04-20 17:56:23 | 2020-04-20 17:56:23 | 2020-04-20 17:56:23 |
+----+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)

这次完全满足需求,也就是说,我们只需要设置传进去的entity类的相应属性为null,就可以实现表里面的数据是当前时间。当然,前提肯定是你设置了timestamp还有not null。
此时已经满足了需求,但是探索精神我们在测试一下,给一个default值为now()
测试2:两个default值,一个CURRENT_TIMESTAMP,一个now()

use test;
drop table  IF EXISTS test.`t_test`;
CREATE TABLE test.`t_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`firstLoginTime` timestamp NOT NULL DEFAULT NOW(),
`lastLoginTime` timestamp NOT NULL ,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;

失败:ERROR 1293 (HY000) at line 5 in file: 'test.sql': Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
可见,5.5版本的mariaDB,对于timestamp类型,确实仅支持一个default值,但是讨巧,还是可以完成设置默认值为当前时间的.那就是设置为NOT NULL,但是VALUES里面传NULL进去,这个时候timestamp会自动取当前时间。

2. 扩展——5.5的日期格式

MariaDB 5.5 create table default value 需要注意的事项_第1张图片
从上面的图表可以看出,在5.5的时候,仅有timestamp是支持默认值的。如果是datetime,是不支持的。而在5.6以及往后的版本,是支持的。

3. varchar设置默认值报错 ERROR 1064 (42000)

其实是对上面需求的衍生——使用date_format()格式化日期并设为默认值

接我自己的需求,一开始自己没对timestamp去细研究,就直接转换思路,既然datetime或者timestamp不接受我设置默认值,那么我直接把当前时间转化为字符串然后赋值给varchar

CREATE TABLE `t_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`runningTime` bigint(20) DEFAULT '0' COMMENT 'device running time',
  `firstLoginTime` varchar(255) NOT NULL DEFAULT (`date_format`(now(), '%Y-%m-%d %T')) comment 'device first login server time',
  `lastLoginTime` varchar(255) NOT NULL DEFAULT (`date_format`(now(), '%Y-%m-%d %T')) comment 'device last login server time',
  `lastOfflineTime` varchar(255) NOT NULL DEFAULT (`date_format`(now(), '%Y-%m-%d %T')) comment 'device last offline from server time',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;

首先提示,将日期转换为字符串存到DB里面,并不是一个很明智的做法
暂时的我并未理解上面的提示的问题,但是我在stack overflow上面问问题的话,有位大佬是这样告诫我的。
stack overflow
上面的建表语句依然是会报错的,但仅限于MariaDB 10.2.1版本一下
错误:ERROR 1064 (42000) at line 27 in file: 'initEmgrTable_rel.sql': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(date_format(now(), '%Y-%m-%d %T')),lastLoginTimevarchar(255) NOT NULL D' at line 34

可以看出,错误是出在默认值那里。我做过测试,直接改成default '11111111',可以把字段的默认值设置为1111111,而改为default ('11111111')则依然会报这个错误。也就是说,并非date_format这个函数出错了。
varchar支持默认值,但是仅支持simple的值,如果你是类似子查询的赋值,那么无论是多么简单的查询,都是不支持的。而这种情况一直到MariaDB 10.2.1往后,才被修改。

4. centOS 7 使用MariaDB的注意事项

  1. 当你未进行任何配置,直接使用yum安装的话,默认会给你装5.5
    yum -y list maria*
    可用版本
    从上图可以看出来,当你未对mariaDB进行配置的话,你无论装哪个版本,都是5.5.x的版本。所以你就无法避免我上面遇到的那两个问题。

5. centOS 7 安装新版本的MariaDB

配置MariaDB更高版本的操作,我推荐看看这位仁兄的博客,我感觉写的很明白,别人的写的不甚清楚。CentOS 7安装高版本MariaDB
唯一需要补充的就是,如果你不想安装这位博主hahahafree MariaDB 10.4的话,可以修改这里
MariaDB 5.5 create table default value 需要注意的事项_第2张图片
只需要把这里的10.4改成你想要装的版本就行了,后面的centos7-amd64可以改也可以不改,建议不改。
可以看一下阿里的源:
MariaDB 5.5 create table default value 需要注意的事项_第3张图片
可以看到阿里的源里面是直接5.5和10.0往上的,你想要修改的版本一定要在这些里面,才能正确装进去

你可能感兴趣的:(DB,mysql,java,数据库,mariadb)