目录
5.1 MySQL数据类型介绍
MySQL支持多种数据类型,主要 有数值类型、日期类型和字符串类型。
数值数据类型:包括整数类型TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT;浮点小数数据类型FLOAT和DOUBLE,定点小数类型DECIMAL
日期/时间类型:包括YEAR、TIME、DATE、DATETIME、TIMESTAMP
字符串类型:包括CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM、SET。字符串类型又分为文本字符串和二进制字符串。
5.1.1 整数类型
CREATE TABLE tmp1
(
x TINYINT(4),
y SMALLINT,
z MEDIUMINT,
m INT,
n BIGINT
);
-- 这里的数字11表示该数据类型指定的显示宽度,指定能够显示的数值中数字的个数。
-- 显示宽度和数据类型的取值范围是无关的,显示宽度只是知名MySQL最大可能显示的数字个数,
-- 数值的位数小于指定的宽度时会由空格填充;如果出入了大于显示宽度的值,只要该值不超过该类型整数的
-- 取值范围,数值依然可以插入,而且能够显示出来
如果在定义表结构时不指定显示的宽度,则系统为每一中类型指定默认的宽度值。可以用DESC查看表的结构,以查看默认的显示宽度。
5.1.2 浮点数类型和顶点数类型
浮点数和定点数都可以用(M,N)表示,其中M成为精度,表示总共的位数;N称为标度,是表示小数的位数。定点小数(DECIMAL)类型不同于浮点数,它是以字符串存放的。DECIMAL(M,D),其有效第取值范围是由M和D决定的。如果 改变M而固定D,则其取值范围将随M的变大而变大。DECIMAL的存储控件并不是固定的,而由其精度M决定,占用M+2个字节。
不论是定点还是浮点数,如果用户指定的精度小于实际的数值精度,则进行四舍五入处理。
CREATE TABLE tmp2
(
x FLOAT(5,1),
y DOUBLE(5,1),
z DECIMAL(5,1)
);
INSERT INTO tmp2 VALUES (5.12, 5.15, 5.123);
插入时,三个数值都会进行四舍五入,但是只有DECIMAL会提示警告。使用以下语句查看警告信息。
SHOW WARNINGS;
FLOAT和DOUBLE在不指定精度时,默认会按照实际的精度(由计算机硬件决定),DECIMAL如不指定精度,默认为(10,0)
5.1.3 日期与时间类型
- YEAR
YEAR类型时一个单字节类型用于表示年,在存储时只需要1个字节。可以使用以下格式指定YEAR值:
- 以四位字符串或者4为数字格式表示:范围'1901'-'2155'。输入格式为 ‘YYYY’ 或YYYY。
- 以两位字符串格式表示:范围‘00’-‘99’。其中‘00’-‘69’和‘70’-‘99’范围的值分别被转换到2000-2069和1970-1999。‘0’和‘00’的作用相同。插入超过范围的值将会被转换为2000.
- 以两位数字表示:范围1-99。1-69和70-99范围的值分别被转换为2001-2069和1970-1999范围的YEAR值。注意这里0值将被转换为0000,而不是2000
CREATE TABLE tmp3
(
y YEAR
);
INSERT INTO tmp3 values (2010), ('2010');
INSERT INTO tmp3 values ('2166');
DELETE FROM tmp3;
INSERT INTO tmp3 values('0'),('00'),('77'),('10');
SELECT * FROM tmp3;
DELETE FROM tmp3;
INSERT INTO tmp3 values(0),(78),(11);
SELECT * FROM tmp3;
- TIME
TIME类型用于只需要时间信息的值,在存储时需要3个字节。格式为‘HH:MKM:SS’。TIME类型的取值范围-838:59:59 -- 838:59:59。小时部分会如此大的原因时TIME类型不仅可以用于表示一天的时间,还可能时某个时间过去的时间或这两个事件之间的事件间隔。
- ‘D HH:MM:SS’格式的字符串。还可以使用下面任何一种“非样额的语法”:‘HH:MM:SS’、'HH:MM'、‘D HH:MM’、‘D HH’、‘SS’。这里D表示日,可以取0-34之间的值。在插入数据库时,D被转换为小时保存,格式为【D*24 + HH】
- ‘HHMMSS’格式的、没有 间隔符的字符串或者HHMMSS格式的数值,鉴定格式有意义的时间。例如:‘101112’被理解为‘10:11:12’,但‘109712’时不合法的,存储时将变为00:00:00
- TIME值的简写:如果没有冒号,假定最右边两位表示秒。(MySQL解释TIME值为过去的时间而不是当天的时间)。‘1112’和1112被解析为00:11:12;‘12’和12被解析为00:00:12。相反,TIME值中如果使用冒号,则被看作当天的时间。‘11:12’被解析为11:12:00
CREATE TABLE tmp4( t TIME );
INSERT INTO tmp4 values('10:05:05 '), ('23:23'), ('2 10:10'), ('3 02'),('10');
SELECT * FROM tmp4;
DELETE FROM tmp4;
INSERT INTO tmp4 values('101112'),(111213),( '0');
INSERT INTO tmp4 values ( 107010);
SELECT * FROM tmp4;
DELETE FROM tmp4;
INSERT INTO tmp4 values (CURRENT_TIME) ,(NOW());
SELECT * FROM tmp4;
- DATE
DATE类型用在只取日期值时,没有时间部分,在存储时需要三个字节。日期格式为‘YYYY-MM-DD’。
- 以‘YYYY-MM-DD’或‘YYYYMMDD’
- 以'YY-MM-DD'或‘YYMMDD’。年份的‘00-69’转换为‘2000-2069’;‘70-99’转换为‘1970-1999’
- 以YY-MM-DD或YYMMDD。年份的00-69转换为2000-2069;70-99转换为1970-1999
- CURRENT_DATE或者NOW()插入当前系统日期
CREATE TABLE tmp5(d DATE);
INSERT INTO tmp5 values('1998-08-08'),('19980808'),('20101010');
SELECT * FROM tmp5;
DELETE FROM tmp5;
INSERT INTO tmp5 values ('99-09-09'),( '990909'), ('000101') ,('111111');
SELECT * FROM tmp5;
DELETE FROM tmp5;
INSERT INTO tmp5 values (99-09-09),(990909), ( 000101) ,( 111111);
SELECT * FROM tmp5;
DELETE FROM tmp5;
INSERT INTO tmp5 values( CURRENT_DATE() ),( NOW() );
SELECT * FROM tmp5;
-- CURRENT_DATE只返回当前日期值,不包括时间部分;
-- NOW()函数返回日期和时间值,在保存到数据库时,只保留了其日期部分
-- MySQL允许“不严格”语法:任何标点符号都可以用作日期部分之间的间隔符。
-- 例如,’98-11-31’、’98.11.31’、’98/11/31’和’98@11@31’是等价的
- DATETIME
- 以‘YYYY-MM-DD HH:MM:SS’或YYYYMMDD HHMMSS
- 以‘YY-MM-DD HH:MM:SS’或YYMMDD HHMMSS
- 以YYYYMMDDHHMMSS’或YYYYMMDDHHMMSS
CREATE TABLE tmp6( dt DATETIME );
INSERT INTO tmp6 values('1998-08-08 08:08:08'),('19980808080808'),('20101010101010');
INSERT INTO tmp6 values('99-09-09 09:09:09'),('990909090909'),('101010101010');
INSERT INTO tmp6 values(19990909090909), (101010101010);
INSERT INTO tmp6 values( NOW() );
- TIMESTAMP
TIMESTAMP存储的时UTC时间,检索时按照当前时区的不同,显示的时间值是不同的。
CREATE TABLE tmp7( ts TIMESTAMP);
INSERT INTO tmp7 values ('19950101010101'),
('950505050505'),
('1996-02-02 02:02:02'),
('97@03@03 03@03@03'),
(121212121212),
( NOW() );
【修改当前时区】
INSERT INTO tmp7 values( NOW() );
SELECT * FROM tmp7;
SET time_zone='+10:00';
SELECT * FROM tmp7;
5.1.4 文本字符串类型
CHAR和VARCHAR
CHAR(M)为固定长度字符串,在定义时指定字符串列长。当保存时在右侧填充空格以达到指定的长度。最大存储255个字符。当检索时,尾部的空格将被删除
VARCHAR(M)是长度可变的字符串,M表示最大列长度。M的取值范围是0-65535.VARCHAR的最大实际长度由最大的行的大小和使用的字符集确定,而其实际占用的控件为字符串的实际长度加1. VARCHAR在值保存和检索时尾部的空格仍保留。
CREATE TABLE tmp8(ch CHAR(4), vch VARCHAR(4));
INSERT INTO tmp8 VALUES('ab ', 'ab ');
SELECT CONCAT('(', ch, ')'), CONCAT('(',vch,')') FROM tmp8;
TEXT
TEXT列保存非二进制字符串,如文章内容、评论等。当保存或查询TEXT列的值时,不删除尾部的空格。TEXT分为TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。不同的TEXT类型的存储控件和数据长度不同。
ENUM
ENUM时一个字符串对象,其值为表创建时在列规定中枚举一列值。ENUM类型的字符按在取值时,只能在指定的枚举列表中取,而且一次只能取一个。如果创建的成员中有空格,其尾部的空格将自动删除。ENUM值在内部用整数表示,每个枚举值均有一个索引值:列表值所允许的成员值从1开始编号,MySQL存储的就是这个索引编号。枚举最多可以有65535个元素。
CREATE TABLE tmp9( enm ENUM('first','second','third') );
INSERT INTO tmp9 values('first'),('second') ,('third') , (NULL);
SELECT enm, enm+0 FROM tmp9;
CREATE TABLE tmp10 (soc INT, level enum('excellent', 'good','bad') );
INSERT INTO tmp10 values(70,'good'), (90,1),(75,2),(50,3);
INSERT INTO tmp10 values (100,'best');
SELECT * FROM tmp10;
SET
SET是一个字符串对象,可以有零或多个值,SET列最大可以有64个成员,其值为表创建时规定的一列值。值顶包括多个SET成员的SET列值是,各成员之间用逗号间隔。
与ENUM类型相同,SET值在内部用整数表示,列表中每一个值都有一个索引编号。当创建表时,SET成员值的尾部空格将自动被删除。但与ENUM类型不同的是,ENUM类型字段只能从定义的列值中选择一个值插入,而SET类型的列科从定义的列值中选择多个字符的联合。
如果插入SET字段中列值有重复,则MySQL自动删除重复的值;插入SET字段的值顺序并不重要,MySQL会在存入数据库时,按照定义的顺序显示;如果插入了不正确的值,默认情况下,MySQL将忽视这些值,并给出警告。
CREATE TABLE tmp11 ( s SET('a', 'b', 'c', 'd'));
INSERT INTO tmp11 values('a'),( 'a,b,a'),('c,a,d');
INSERT INTO tmp11 values ('a,x,b,y');
5.15 二进制字符串
BIT
BIT类型时位字段类型。M表示每个值的位数,范围为1-64.如果M被省略,默认格式为1.如果为BIT(M)列分配的值的长度小于M位,在值的左边用0填充。
CREATE TABLE tmp12( b BIT(4) );
INSERT INTO tmp12 VALUES(2), (9), (15);
SELECT BIN(b+0) FROM tmp12;
-- b+0表示将二进制的结果转换为对应的数字的值,BIN() 函数将数字转换为二进制
BINARY与VARBINARY
CREATE TABLE tmp13(b binary(3), vb varbinary(30));
INSERT INTO tmp13 VALUES(5,5);
SELECT length(b), length(vb) FROM tmp13;
SELECT b,vb,b = '5', b='5\0\0',vb='5',vb = '5\0\0' FROM tmp13;
BLOB
5.3 常见运算符
5.3.1 运算符概述
- 算术运算符
- 比较运算符
- 逻辑运算符
- 位操作运算符
5.3.2 算术运算符
CREATE TABLE tmp14 ( num INT);
INSERT INTO tmp14 value(64);
SELECT num, num+10, num-3+5, num+5-3, num+36.5 FROM tmp14;
SELECT num, num *2, num /2, num/3, num%3 FROM tmp14;
SELECT num, num / 0, num %0 FROM tmp14;
-- 除法运算中的除数不能为0,如果被0除,则返回结果为NULL
5.3.3 比较运算符
SELECT 1=0, '2'=2, 2=2,'0.02'=0, 'b'='b', (1+3) = (2+2),NULL=NULL;
SELECT 1<=>0, '2'<=>2, 2<=>2,'0.02'<=>0, 'b'<=>'b', (1+3) <=> (2+1),NULL<=>NULL;
SELECT 'good'<>'god', 1<>2, 4!=4, 5.5!=5, (1+3)!=(2+1),NULL<>NULL;
SELECT 'good'<='god', 1<=2, 4<=4, 5.5<=5, (1+3) <= (2+1),NULL<=NULL;
SELECT 'good'<'god', 1<2, 4<4, 5.5<5, (1+3) < (2+1),NULL<NULL;
SELECT 'good'>='god', 1>=2, 4>=4, 5.5>=5, (1+3) >= (2+1),NULL>=NULL;
SELECT 'good'>'god', 1>2, 4>4, 5.5>5, (1+3) > (2+1),NULL>NULL;
SELECT NULL IS NULL, ISNULL(NULL),ISNULL(10), 10 IS NOT NULL;
SELECT 4 BETWEEN 4 AND 6, 4 BETWEEN 4 AND 6,12 BETWEEN 9 AND 10;
SELECT 'x' BETWEEN 'f' AND 'g', 'b' BETWEEN 'a' AND 'c';
SELECT least(2,0), least(20.0,3.0,100.5), least('a','c','b'),least(10,NULL);
SELECT greatest(2,0), greatest(20.0,3.0,100.5), greatest('a','c','b'),greatest(10,NULL);
SELECT 2 IN (1,3,5,'thks'), 'thks' IN (1,3,5,'thks');
SELECT NULL IN (1,3,5,'thks'),10 IN (1,3,NULL,'thks');
SELECT 'stud' LIKE 'stud', 'stud' LIKE 'stu_','stud' LIKE '%d','stud' LIKE 't_ _ _', 's' LIKE NULL;
SELECT 'ssky' REGEXP '^s', 'ssky' REGEXP 'y$', 'ssky' REGEXP '.sky', 'ssky' REGEXP '[ab]';
5.3.4 逻辑运算符
SELECT NOT 10, NOT (1-1), NOT -5, NOT NULL, NOT 1 + 1;
SELECT !10, !(1-1), !-5, ! NULL, ! 1 + 1;
SELECT 1 AND -1,1 AND 0,1 AND NULL, 0 AND NULL;
SELECT 1 && -1,1 && 0,1 && NULL, 0 && NULL;
SELECT 1 OR -1 OR 0, 1 OR 2,1 OR NULL, 0 OR NULL, NULL OR NULL;
SELECT 1 || -1 || 0, 1 || 2,1 || NULL, 0 || NULL, NULL || NULL;
SELECT 1 XOR 1, 0 XOR 0, 1 XOR 0, 1 XOR NULL, 1 XOR 1 XOR 1;
SELECT 1 XOR 1, 0 XOR 0, 1 XOR 0, 1 XOR NULL, 1 XOR 1 XOR 1;
5.3.5 位运算符
SELECT 10 | 15, 9 | 4 | 2;
SELECT 10 & 15, 9 &4& 2;
SELECT 10 ^ 15, 1 ^0, 1 ^ 1;
SELECT 1<<2, 4<<2;
SELECT 1>>1, 16>>2;
SELECT 5 & ~1;