一,类型概述
类型
|
具体类型
|
整数类型
|
TINYINT, SMALLINT, MEDIUMINT, INT(或INTEGER), BIGINT
|
浮点类型
|
FLOAT, DOUBLE
|
定点数类型
|
DECIMAL
|
位类型
|
BIT
|
日期类型
|
YEAR, TIME, DATE, DATETIME, TIMESTAMP
|
字符串类型
|
CHAR, VARCHAR,
|
文本类型
|
TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT
|
枚举类型
|
ENUM
|
集合类型
|
SET
|
二进制字符串类型
|
BINARY, VARBINARY, TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB |
JSON类型
|
JSON对象, JSON数组
|
空间数据类型
|
单值类型:GEOMETRY, POINT, LINESTRING, POLYGON
集合类型:MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION
|
常见数据类型的属性:
MySQL关键字
|
含义
|
NULL
|
数据列可包含NULL值
|
NOT NULL
|
数据列不允许包含NULL值
|
DEFAULT
|
默认值
|
PRIMARY KEY
|
主键
|
AUTO_INCREMENT
|
自动递增
|
UNSIGNED |
无符号
|
CHARACTER SET name
|
指定一个字符集
|
二,整型数据类型
整型数据类型一共有5种,包括YINYINT, SMALLINT, MEDIUMINT, INT(INTEGER)和BIGINT
整数类型
|
字节
|
有符号数取值范围
|
无符号数取值范围
|
TINYINT |
1
|
-128 ~ 127
|
0 ~ 255
|
SMALLINT
|
2
|
-32768 ~ 32767
|
0 ~ 65535
|
MEDIUMINT
|
3
|
-8388608 ~ 8388607
|
0 ~ 16777215
|
INT, INTEGER
|
4
|
-2147483648〜2147483647
|
0〜4294967295
|
BIGINT
|
8
|
-9223372036854775808〜9223372036854775807
|
0〜18446744073709551615
|
在具体的赋值过程中,数值最大不能超过数据类型的最大取值范围,最小不能超过数据类型的最小取值范围
演示表:
//创建一个表
CREATE TABLE inttest(
tinyint1 TINYINT,
smallint1 SMALLINT,
mediumint1 MEDIUMINT,
int12 INT,
bigint1 BIGINT
)
例1:超出取值范围
//对字段进行赋值(超出取值范围)
INSERT INTO inttest(tinyint1) VALUES(128);
//错误信息
> 1264 - Out of range value for column 'tinyint1' at row 1
一,整数类型可选属性
可选属性主要有三个:
- M显示宽度
- UNSIGNED无符号
- ZEROFULL填充
一,M显示宽度
M的概念:表示显示宽度,它的取值范围是(0,255)
如:int(5) 它的显示宽度就是为5,当数值小于5时在数字前面需要用字符填满宽度。该项填充功能需要配合"ZEROFILL"使用,表示用"0"填满宽度,否则指定显示宽度无效
显示宽度与类型可以存储的取值范围无关,当数值超过了显示宽度但没有超过类型范围不会对插入数据造成影响
注:在Mysql5.7之前,在建表时如果不指定显示宽度,那么显示宽度和类型最大值的宽度一致。但在MySQL8.0.17开始,整数数据类型不推荐使用宽度属性,也不会有默认宽度
CREATE TABLE inttest(
tinyint1 TINYINT,
smallint1 SMALLINT,
mediumint1 MEDIUMINT,
int12 INT,
bigint1 BIGINT
)
例1:
//建一个对比表
CREATE TABLE inttest1(
int10 INT,
int11 INT(5),
int12 INT(5) ZEROFILL
)
//插入数据
INSERT INTO inttest1 VALUES(123,123,123),(123456,123456,123456)
//查看数据
SELECT * FROM inttest1;
二,UNSIGNED无符号
无符号取值范围没有负数且正数范围比有符号大
例:
//创建表
CREATE TABLE inttest2(
int10 TINYINT,
int11 TINYINT UNSIGNED
)
//插入数据
INSERT INTO inttest2 VALUES(127,244)
//查看
SELECT * FROM inttest2;
三,ZEROFILL填充
ZEROFILL:0填充(如果某列是ZEROFILL,那么Mysql会自动为当前列添加UNSIGNED属性),如果指定了ZEROFILL只是表示不够M位时,用0在左边填充,如果超过M位,只有不超过数据存储范围即可
注意:
- int(M),这个M显示宽度跟所占的存储空间并无关系,如果超过M位,只有不超过数据存储范围即可
- M显示宽度必须要和UNSIGNED ZEROFILL属性一起使用才有意义
二,应用场景和选择
应用场景:
- TINTINT:一般用于枚举类型,比如:系统设定取值范围很小且固定的场景
- SMALLINT:可以用于较小范围的统计数据,比如:统计工厂的固定资产库存数量等
- MEDIUMINT:用于较大整数的计算,比如:车站每日的客浏览
- INT(INTEGER):取值范围足够大,一般情况下不必考虑超限问题,用的场景也最多,比如:商品编号
- BIGINT:只有当处理特别巨大的整数才会用到,比如:双十一的交易量,大型门户网站点击量,证券公司衍生品等
如何选择?
在评估用那种数据类型的时候,必须要考虑存储空间和可靠性的平衡问题:
- 存储空间:用占用字节数较少的整数类型来节省存储空间
- 可靠性:不要为了节省空间,选择的类型取值范围太小,一旦超过取值范围,就可能引起系统错误,可靠性很低
例:商品编号采用的数据类型是SMALLINT。在起初的时候,商品较少的时候不会有什么大问题,但假如这个商铺扩大化经营商品急剧增加,那么就有可能超过SMALLINT的范围
在实际生产中系统故障产生的成本远远超过增加几个字段产生的成本,因此需要特别注意
在进行类型评估时不仅要在当前阶段做考虑,还要做一个长远的计划,避免出现滞后性问题。在避免系统故障的前提下才考虑节省存储空间的问题
三,浮点和定点数据类型
浮点数和定点数类型的特点是可以处理小数,可以把整数看成小数的一个特例。因此浮点数和定点数的使用场景比整数大多了
一,浮点数据类型
Mysql支持的浮点数类型:
- FLOAT:表示单精度浮点数
- DOUBLE:表示双精度浮点数
类型
|
有符号取值范围
|
无符号取值范围
|
占用字节数
|
FLOAT
|
(-3.402823466E+38, -1.175494351E-38), 0,(1.175494351 E-38, 3.402823466351 E+38)
|
0, (1.175494351 E-38,3.402823466 E+38)
|
4
|
DOUBLE
|
(-1.7976931348623157E+308,2.2250738585072014E-308), 0,(2.2250738585072014E-308,1.7976931348623157E+308) |
0, (2.2250738585072014E-308,1.7976931348623157E+308) |
8
|
FLOAT比DOUBLE的区别:FLOAT占用的字节更少存储的范围也越小,DOUBLE反之
问题:为什么浮点数类型的无符号数值取值范围,只相当于有符号数取值范围的一半,也就只相当于有符号数取值范围大于零的部分?
Mysql存储浮点数的格式位:符号(S)、尾数(M)、阶码(E)。因此,无论有没有符号,Mysql的浮点数都会存储表示符号的部分。因此所谓无符号取值范围,其实就是有符号的取值范围正数的部分。
一,数据精度说明
MySQL允许使用非标准语法(其他数据库未必支持,因此如果涉及数据迁移,则最好不要这么用):FLOAT(M,D)或DOUBLE(M,D)
- 这里M称为精度,D为标度
- (M,D)中M=整数位+小数位
- D=小数位 (D<=M<=255,0<=D<=30)
例如:FLOAT(5,2)的一列的范围为 -999.99 ~ 999.99,如果超过这个范围就会报错
FLOAT和DOUBLE类型在不指定(M,D)时,默认会按照实际的精度(由硬件和操作系统决定)来显示
注:浮点类型,也可以加UNSIGNED,但是不会改变数据的范围,例如:FLOAT(3,2) UNSIGNED仍然只能表示0-9.99
不管是否显式设置了精度(M,D),这里Mysql的处理方案如下:
1,如果存储时,整数部分超出了范围,Mysql就会报错
2,如果存储时,小数部分超出范围,就分以下情况
- 若四舍五入后,整数部分没有超出,则只警告,但能成功操作
- 若四舍五入后,整数部分超出,则直接报错
例:
//建 表
CREATE TABLE floattest(
float1 FLOAT(4,2)
)
//正确插入数据
INSERT INTO floattest VALUES (23.12),(23.2478);
//错误插入数据
INSERT INTO floattest VALUES (232.12),(99.9981);
二,数据的精度误差问题
浮点类型有一个缺陷,就是不精准,所以在很多场景下就不能使用浮点型
例:0.23+0.51+0.71=1.45,但提供MySQL计算就有问题
//1,测试创建表
mysql> CREATE TABLE floattest1(
-> float1 FLOAT,
-> double1 DOUBLE);
Query OK, 0 rows affected (0.00 sec)
//2,插入值
mysql> INSERT INTO floattest1 VALUES(0.23,0.23),(0.51,0.51),(0.71,0.71);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
//3,将float列进行累加
mysql> SELECT SUM(float1) FROM floattest1;
+--------------------+
| SUM(float1) |
+--------------------+
| 1.4499999731779099 |
+--------------------+
1 row in set (0.00 sec)
//4,将double列进行累加
mysql> SELECT SUM(double1) FROM floattest1;
+--------------------+
| SUM(double1) |
+--------------------+
| 1.4499999731779099 |
+--------------------+
1 row in set (0.00 sec)
累加的结果都有精度问题?虽然误差很小,但假如需要做判断那么就会有很大问题
Mysql对浮点类的误差问题原因在与对浮点类型的存储方式上:
MySQL用4个字节存储FLOAT,用8个字节来存储DOUBLE类型数据。无论那个在底层都是采用二进制的方式来存储的。比如6.625,用二进制表示就是1001.101,或者表示成1.001101*2^3。如果尾数不是0或5(比如9.624),你就无法用一个二进制数来精准表达。进而,就只好在取值允许范围之内进行四舍五入
在具体使用中,如果用到浮点数,要特别注意误差问题。因为浮点数是不准确的,所以要避免使用"="来判断两个数是否相等。同时,在一些对精度要求较高的项目中,千万不能使用浮点数,不如会导致严重的结果错误。一般对精度要求高就使用定点数DECIMAL
二,定点数据类型
MySQL中定点数类型只有DECIMAL一种类型
数据类型
|
字节数
|
含义
|
DECIMAL(M,D),DEC,NUMERIC
|
M+2字节
|
有效范围由M和D决定
|
使用DECIMAL(M,D)的方式表示高精度小数,其中,M被称为精度,D被称为标度
-
0<= M <=65
-
0<=D<=30
-
M > D
例如:DECIMAL(5,2)的类型,表示该列取值范围-999.99 ~ 999.99
DECIMAL(M,D)的最大取值范围与DOUBLE类型一样,但是有效的数据范围是由M和D决定的。DECIMAL的存储空间并不是固定的,由精度值M决定,总共占用的存储空间为M+2个字节。也就是说,在一些精度要求不高的场景下,比起占用同样字节的定点数,浮点数表达的数值范围可以更大一些
定点数在MySQL内部是以字符串的形式进行存储,在就决定它比浮点类型更精准
当DECIMAL类型不指定精度和标度时,其默认为DECIMAL(10,0)。当数据的精度超过了定点数类型的精度范围,MySQL同样会进行四舍五入处理
例:
mysql> CREATE TABLE floattest2(
-> decimal1 DECIMAL,
-> decimal2 DECIMAL(5,2));
Query OK, 0 rows affected (0.00 sec)
//查看表结构
mysql> desc floattest2;
+----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------+------+-----+---------+-------+
| decimal1 | decimal(10,0) | YES | | NULL | |
| decimal2 | decimal(5,2) | YES | | NULL | |
+----------+---------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
//插入数据
mysql> INSERT INTO floattest2 VALUES(13.123,122.361);
Query OK, 1 row affected, 2 warnings (0.00 sec)
mysql> SELECT * FROM floattest2;
+----------+----------+
| decimal1 | decimal2 |
+----------+----------+
| 13 | 122.36 |
+----------+----------+
1 row in set (0.00 sec)
浮点数和定点数的对比:
- 浮点数相对于定点数的优点是在长度一定的情况下,浮点类型取值范围更大,但是不精准。它适用于需要取值范围大,又可以容忍微小的误差的科学计算场景(如:分子建模,流体力学等)
- 定点数类型取值范围相对小,但是精准,没有误差,适合于精度要求极高的场景(如:金融等)
由于DECIMAL数据类型精准性,在项目中,除了极小数(比如商品编号)用到整数类型外,其他的数值都用DECIMAL,原因在于这个项目所在的行业是零售行业,要求精准
四,位数据类型
位类型存储的是二进制值
二进制字符串类型
|
长度
|
长度范围
|
占用空间
|
BIT(M)
|
M
|
1<= M <= 64
|
约为(M+7)/8个字节
|
BIT类型,如果没有指定(M),默认是1位,这个1位,表示只能存储1位的二进制数(1<=M<=64)
例:
mysql> CREATE TABLE bintest(
-> bin11 BIT,
-> bin12 BIT(5),
-> bin13 BIT(64));
Query OK, 0 rows affected (0.00 sec)
mysql> desc bintest;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| bin11 | bit(1) | YES | | NULL | |
| bin12 | bit(5) | YES | | NULL | |
| bin13 | bit(64) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> INSERT INTO bintest VALUES(1,8,19);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT BIN(bin11),BIN(bin12),BIN(bin13) FROM bintest;
+------------+------------+------------+
| BIN(bin11) | BIN(bin12) | BIN(bin13) |
+------------+------------+------------+
| 1 | 1000 | 10011 |
+------------+------------+------------+
1 row in set (0.00 sec)
五,日期和时间类型
MySQL有多种表示日期和时间的数据类型,不同版本可能有差异,MySQL8.0版本支持的日期和时间类型主要有:YEAR类型,TIME类型,DATE类型,DATETIME类型和TIMESTRMP类型
- YEAR类型通常表示年
- DATE类型通常用于表示年,月,日
- TIME类型通常表示时,分,秒
- DATETIME类型通常用于年,月,日,时,分,秒
- TIMESTAMP类型通常表示带时区的年,月,日,时,分,秒
类型
|
名称
|
字节
|
日期格式
|
最小值 |
最大值
|
YEAR
|
年
|
1
|
YYYY或YY
|
1901
|
2155
|
TIME
|
时间
|
3
|
HH:MM:SS
|
-838:59:59
|
838:59:59
|
DATE
|
日期
|
3
|
YYYY-MM-DD
|
1000-01-01
|
9999-12-03
|
DATETIME
|
日期时间
|
8
|
YYYY-MM-DD HH:MM:SS
|
1000-01-01 00:00:00
|
9999-12-31 23:59:59
|
TIMESTAMP
|
日期时间
|
4
|
YYYY-MM-DD HH-MM-SS
|
1970-01-01 00:00:00 UTC
|
2038-01-19 03:14:07 UTC
|
这些时间类型表示的内容、占用的字节数都要不同,在实际的需求中要灵活选择
为什么时间类型TIME的取值范围不是-23:59:59 ~ 23:59:59?原因在于Mysql设计TIME类型时,不光表示一天之内的时间,而且可以用来表示一个时间间隔,这个时间间隔可以超出24小时
一,YEAR类型
YEAR类型用来表示年份,在所有的日期时间类型中所占的存储空间最小
在MySQL中,YEAR有两种存储格式:
1,以4位字符串或数字格式表示YEAR类型,其格式为YYYY,最小值为1901,最大值为2155
2,以2为字符串格式表示YEAR类型,最小值为00,最大值99
- 当取值为01到69时,表示2001到2069
- 当取值为70到99时,表示1970到1999
- 当取值整数的0或00添加时,那么就是0000年
- 当取值是日期/字符串的'0'添加的话,是2000年
注:从Mysql5.5.27开始,2位格式的YEAR已经不推荐使用。YEAR默认格式是"YYYY",没必要写成YEAR(4),从MySQL8.0.19开始,不推荐使用指定显示宽度的YEAR(4)数据类型
例:
mysql> use mysqltest;
Database changed
mysql> CREATE TABLE yeartest(
-> year1 YEAR,
-> year2 YEAR(4));
Query OK, 0 rows affected (0.00 sec)
mysql> DESC yeartest;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| year1 | year(4) | YES | | NULL | |
| year2 | year(4) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
//插入元素
mysql> INSERT INTO yeartest VALUES("2030","23"),("1983","83");
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
//查看表
mysql> SELECT * FROM yeartest;
+-------+-------+
| year1 | year2 |
+-------+-------+
| 2030 | 2023 |
| 1983 | 1983 |
+-------+-------+
2 rows in set (0.00 sec)
//超出范围
mysql> INSERT INTO yeartest VALUES("2177","83");
ERROR 1264 (22003): Out of range value for column 'year1' at row 2
二,DATE类型
DATE类型表示日期,没有时间部分,格为"YYYY-MM-DD",其中,YYYY表示年份,MM表示月份,DD表示日期。需要3个字节的存储空间。在向DATE类型的字段插入数据同样有一定的格式条件
- 以YYYY-MM-DD格式或者YYYYMMDD格式表示日期,其中最小取值为1000-01-01,最大取值为9999-12-03。YYYYMMDD格式在底层会被转化为YYYY-MM-DD格式
- 以YY-MM-DD格式或YYMMDD格式表示的字符串日期,此格式中,年份为两位时同样满足YEAR的格式条件,当年份取值位00到69时,会被转化位2000到2069;但年份取值位70到99时,会被转化1970到1999
- 使用CUURRENT_DATE()或NOW()函数,会插入当前的系统时间
例:
mysql> CREATE TABLE datatest(
-> data11 DATE);
Query OK, 0 rows affected (0.05 sec)
mysql> DESC datatest;
+--------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------+------+-----+---------+-------+
| data11 | date | YES | | NULL | |
+--------+------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> INSERT INTO datatest VALUES("2000-12-13"),("00-12-13"),("001213"),(CURRENT_DATE()),(NOW());
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM datatest;
+------------+
| data11 |
+------------+
| 2000-12-13 |
| 2000-12-13 |
| 2000-12-13 |
| 2022-06-24 |
| 2022-06-24 |
+------------+
5 rows in set (0.00 sec)
三,TIME类型
TIME类型用来表示时间,不包含日期部分,在MySQL中,需要3个字节的存储空间来存储TIME类型的数据,可以使用"HH:MM:SS"格式来表示TIME类型,其中,HH表示小时,MM表示分钟,SS表示秒
在MySQL中,向TIME类型的字段插入数据时,也可以使用几种不同的格式:
1,带冒号的字符串
- 'D HH:MM:SS'
- 'HH:MM:SS'
- 'D HH:MM'
- 'D HH'
D:表示天,最小值位0,最大值为34。如果使用带有D格式的字符串插入TIME类型字段中,计算格式:D*24+HH。当使用带有冒号并且不带D的字符串表示时间时,表示当天时间,比如:12:10表示12:10:00,而不是00:12:10
2,不带冒号的字符串或者数字
如果插入一个合法的字符串或者数字,MySQL在存储数据时,会将其自动转化为00:00:00进行存储。比如:1210,表示00:12:10,而不是12:10:00
3,使用CURRENT_TIME()或NOW,可以插入当前系统时间
例:
mysql> CREATE TABLE timetest(
-> time11 TIME);
Query OK, 0 rows affected (0.02 sec)
mysql> DESC timetest;
+--------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------+------+-----+---------+-------+
| time11 | time | YES | | NULL | |
+--------+------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> INSERT INTO timetest VALUES ("2 4:45:12"),("4:45:12"),("4:45"),(44512),("44512"),(445);
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM timetest;
+----------+
| time11 |
+----------+
| 52:45:12 |
| 04:45:12 |
| 04:45:00 |
| 04:45:12 |
| 04:45:12 |
| 00:04:45 |
+----------+
6 rows in set (0.00 sec)
四,DATETIME类型
DATETIME类型在所有的日期时间类型中占用的存储空间最大,总共需要8个字节的存储空间。在格式上它就是DATE和TIME的结合体,可以表示为"YYYY-MM-DD HH-MM-SS"
在向DATETIME类型的字段插入数据时,同样需要满足一定的格式条件:
1,以YYYY-MM-DD HH-MM-SS格式或者YYYYMMDDHHMMSS格式的字符串插入DATETIME类型的字段时,最小值为1000-01-01 00:00:00,最大值为9999-12-03 23:59:59
2,以YY-MM-DD HH:MM:SS格式或者YYMMDDHHMMSS格式,两位数的年份规则符号YEAR规则,00到69时,会被转化位2000到2069,年份取值位70到99时,会被转化1970到1999
例:
mysql> CREATE TABLE datetimetest(
-> datetime11 DATETIME);
Query OK, 0 rows affected (0.00 sec)
mysql> desc datetimetest;
+------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| datetime11 | datetime | YES | | NULL | |
+------------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> INSERT INTO datetimetest VALUES("2003-12-12 12:45:54"),("00-12-14 12:12:51"),(NOW()),(CURRENT_DATE());
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM datetimetest;
+---------------------+
| datetime11 |
+---------------------+
| 2003-12-12 12:45:54 |
| 2000-12-14 12:12:51 |
| 2022-06-24 20:03:14 |
| 2022-06-24 00:00:00 |
+---------------------+
4 rows in set (0.00 sec)
DATETIME在使用中是最多的
五,TIMESTAMP类型
TIMESTAMP类型也可以表示日期时间,其显示格式与DATETIME类型相同,都是YYYY-MM-DD HH:MM:SS,需要4个字节的存储空间,但是TIMESTAMP存储的时间范围比DATETIME要小很多
TIMESTAMP存储时间的范围:
- 起始时间:"1970-01-01 00:00:01"UTC
- 终止时间:"2038-01-19 03:14:07"UTC
注:UTC为时间标准时间
例:
mysql> CREATE TABLE timestamptest(
-> timestamp11 TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO timestamptest VALUES(NOW()),("2000-11-05 12:1:55");
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> DESC timestamptest;
+-------------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------+------+-----+-------------------+-----------------------------+
| timestamp11 | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+-----------+------+-----+-------------------+-----------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM timestamptest;
+---------------------+
| timestamp11 |
+---------------------+
| 2022-06-24 20:16:21 |
| 2000-11-05 12:01:55 |
+---------------------+
2 rows in set (0.00 sec)
六,TIMESTAMP和DATETIME的区别
区别:
- TIMESTAMP存储空间比较小,表示的日期时间范围也比较小
- 底层存储不同,TIMESTAMP底层存储的是毫秒值,距离1970-1-1 0:0:0的毫秒值
- 两个日期比较大小或日期计算时,TIMESTAMP更方便更快
- TIMESTAMP存储的时间和时区有关,TIMESTAMP会根据用户的时区不同,显示不同的结果,而DATETIME则只能反映出插入时当地的时区,其他时区的用户查看就会有误差
例:
mysql> CREATE TABLE temp_time(
-> d1 DATETIME,
-> d2 TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)
//插入数据
mysql> INSERT INTO temp_time VALUES("2022-6-24 20:32:55","2022-6-24 20:32:55");
Query OK, 1 row affected (0.00 sec)
//查看结果
mysql> SELECT * FROM temp_time;
+---------------------+---------------------+
| d1 | d2 |
+---------------------+---------------------+
| 2022-06-24 20:32:55 | 2022-06-24 20:32:55 |
+---------------------+---------------------+
1 row in set (0.00 sec)
//修改时区为东九区
mysql> SET time_zone = '+9:00';
Query OK, 0 rows affected (0.00 sec)
//再次查看,发现TIMESTAMP改变了
mysql> SELECT * FROM temp_time;
+---------------------+---------------------+
| d1 | d2 |
+---------------------+---------------------+
| 2022-06-24 20:32:55 | 2022-06-24 21:32:55 |
+---------------------+---------------------+
1 row in set (0.00 sec)
TIMESTAMP存储数据的时候需要对当前时间所在的时区进行转换,查询数据的时候再将时间转换回当前时区,因此。使用TIMESTAMP存储的同一个时间值,再不同的时区查询时会显示不同的时间
七,开发经验
再生产中用的最多的时间日期类型就是DATETIME
虽然MySQL也支持YEAR(年),TIME(时间),DATE(日期),以及TIMESTAMP类型,但是周期实际项目中,尽量用DATETIME类型,因为这个数据类型包括了完整的日期时间信息,取值范围也最大,使用也方便。假如用YEAR和TIME分开存储就比较复杂
一般注册时间,商品发布时间,不建议使用DATETIME存储。而是使用时间戳,因为DATETIME虽然直观但不方便计算
一般通过日期函数的UNIX_TIMESTAMP()获取时间戳:
mysql> SELECT UNIX_TIMESTAMP();
+------------------+
| UNIX_TIMESTAMP() |
+------------------+
| 1656074657 |
+------------------+
1 row in set (0.00 sec)
Comments | NOTHING
Warning: Undefined variable $return_smiles in /www/wwwroot/wql_luoqin_ltd/wp-content/themes/Sakura/functions.php on line 1109