创建表的完整语法和基本数据类型
创建表的完整语法
语法:
create table 表名(
字段名1 类型[(宽度) 约束条件],
字段名2 类型[(宽度) 约束条件],
字段名3 类型[(宽度) 约束条件]
);
解释
类型:使用限制字段必须以什么样的数据类型传值
约束条件:是在类型之外添加一种额外的限制
注意:
- 在同一张表中,字段名是不能相同
- 宽度和约束条件可选
- 字段名和类型是必须的
4.最后一个字段不能加逗号
基本数据类型
1.整形:tinyint,int,bigint
1#tinyint默认为有符号
2MariaDB [db1]> create table t1(x tinyint); #默认为有符号,即数字前有正负号
3#设置无符号tinyint
4MariaDB [db1]> create table t2(x tinyint unsigned);
5======用zerofill测试整数类型的显示宽度--使用0填充=============
6MariaDB [db1]> create table t7(x int(3) zerofill);
注意:
为该类型指定宽度时,仅仅只是指定查询结果的显示宽度,与存储范围无关,存储范围如下
其实我们完全没必要为整数类型指定显示宽度,使用默认的就可以了
默认的显示宽度,都是在最大值的基础上加1
2.浮点型
1#三种浮点型,精度依次升高,一般使用float即可。
2FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]#单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。m最大值为255,d最大值为30
3DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]# 双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。m最大值为255,d最大值为30
4decimal[(m[,d])] [unsigned] [zerofill]#准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。
3.字符类型
1.分类:char(定长,简单粗暴,浪费空间,存取速度快)
varchar(变长,精准,节省空间,存取速度慢)
注意:char和varchar括号内的参数指的都是字符的长度
1create table t12(x char(4));超出4个字符则报错,不够用空格补全
2create table t13(y varchar(4));超出4个字符报错,不够4个则有几个存几个
3set global sql_mode = 'PAD_CHAR_TO_FULL_LIENGTH'#取数据时,保留尾部空格
** 注意:**
针对char类型,mysql在存储时会将数据用空格补全存放到硬盘中
但会在读出结果时自动去掉末尾的空格,因为末尾的空格在以下场景中是无用
mysql> select * from t14 where name="lxx"; # name字段明确地等于一个值,该值后填充空格是没有用的
mysql> select * from t14 where name like "lxx"; # name字段模糊匹配一个值,该值后填充空格是有用的
varchar真的比char节省空间吗?
Value | char(4) | Storage Required | varchar(4) | Storage Required |
---|---|---|---|---|
'' | '四个空格' | 4 bytes | '' | 1bytes |
'ab' | 'ab ' | 4 bytes | 'ab' | 3bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5bytes |
'abcdef' | 'abcd' | 4 bytes | 'abcd' | 5bytes |
varchar并不是什么时候都比char节省空间,所以推荐使用char
1测试前了解两个函数
2length:查看字节数
3char_length:查看字符数
1mysql> create table t1(x char(5),y varchar(5));
2Query OK, 0 rows affected (0.26 sec)
1#char存5个字符,而varchar存4个字符
2mysql> insert into t1 values('你瞅啥 ','你瞅啥 ');
3Query OK, 1 row affected (0.05 sec)
4
1mysql> SET sql_mode='';
2Query OK, 0 rows affected, 1 warning (0.00 sec)
在检索时char很不要脸地将自己浪费的2个字符给删掉了,装的好像自己没浪费过空间一样,而varchar很老实,存了多少,就显示多少
1mysql> select x,char_length(x),y,char_length(y) from t1;
2+-----------+----------------+------------+----------------+
3| x | char_length(x) | y | char_length(y) |
4+-----------+----------------+------------+----------------+
5| 你瞅啥 | 3 | 你瞅啥 | 4 |
6+-----------+----------------+------------+----------------+
71 row in set (0.00 sec)
1#略施小计,让char现出原形
2mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
3Query OK, 0 rows affected (0.00 sec)
1#这下子char原形毕露了......
2mysql> select x,char_length(x),y,char_length(y) from t1;
3+-------------+----------------+------------+----------------+
4| x | char_length(x) | y | char_length(y) |
5+-------------+----------------+------------+----------------+
6| 你瞅啥 | 5 | 你瞅啥 | 4 |
7+-------------+----------------+------------+----------------+
81 row in set (0.00 sec)
1#char类型:3个中文字符+2个空格=11Bytes
2#varchar类型:3个中文字符+1个空格=10Bytes
3mysql> select x,length(x),y,length(y) from t1;
4+-------------+-----------+------------+-----------+
5| x | length(x) | y | length(y) |
6+-------------+-----------+------------+-----------+
7| 你瞅啥 | 11 | 你瞅啥 | 10 |
8+-------------+-----------+------------+-----------+
91 row in set (0.00 sec)
4.日期类型
============注意啦,注意啦,注意啦===========
- 单独插入时间时,需要以字符串的形式,按照对应的格式插入
- 插入年份时,尽量使用4位值
- 插入两位年份时,<=69,以20开头,比如50, 结果2050
=70,以19开头,比如71,结果1971
1YEAR
2 YYYY(1901/2155)
3DATE
4 YYYY-MM-DD(1000-01-01/9999-12-31)
5TIME
6 HH:MM:SS('-838:59:59'/'838:59:59')
7DATETIME
8 YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 Y)
9TIMESTAMP
10 YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)
1MariaDB [db1]> create table student(
2 -> id int,
3 -> name varchar(20),
4 -> born_year year,#无论year指定何种宽度,最后都默认是year(4)
5 -> birth date,
6 -> class_time time,
7 -> reg_time datetime);
8MariaDB [db1]> insert into student values
9 -> (1,'alex',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"),
10 -> (2,'egon',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"),
11 -> (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13");
datetime 和 timestamp的区别
在实际应用的很多场景中,MySQL的这两种日期类型都能够满足我们的需要,存储精度都为秒,但在某些情况下,会展现出他们各自的优劣。下面就来总结一下两种日期类型的区别。
1.DATETIME的日期范围是1001——9999年,TIMESTAMP的时间范围是1970——2038年。
2.DATETIME存储时间与时区无关,TIMESTAMP存储时间与时区有关,显示的值也依赖于时区。在mysql服务器,操作系统以及客户端连接都有时区的设置。
3.DATETIME使用8字节的存储空间,TIMESTAMP的存储空间为4字节。因此,TIMESTAMP比DATETIME的空间利用率更高。
4.DATETIME的默认值为null;TIMESTAMP的字段默认不为空(not null),默认值为当前时间(CURRENT_TIMESTAMP),如果不做特殊处理,并且update语句中没有指定该列的更新值,则默认更新为当前时间。
5.枚举和集合类型字段的值只能在给定范围中选择,如单选框,多选框
枚举 enum
单选
只能在给定的范围内选一个值,如性别 sex 男male/女female
1CREATE TABLE shirts (name VARCHAR(40),size ENUM('x-small', 'small', 'medium', 'large', 'x-large'));
2INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
集合 set
多选
在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3…)
1CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
2INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
1#综合示例
2MariaDB [db1]> create table consumer(
3 -> name varchar(50),
4 -> sex enum('male','female'),
5 -> level enum('vip1','vip2','vip3','vip4','vip5'), #在指定范围内,多选一
6 -> hobby set('play','music','read','study') #在指定范围内,多选多
7 -> );
8MariaDB [db1]> insert into consumer values
9 -> ('egon','male','vip5','read,study'),
10 -> ('alex','female','vip1','girl');
11MariaDB [db1]> select * from consumer;
12+------+--------+-------+------------+
13| name | sex | level | hobby |
14+------+--------+-------+------------+
15| egon | male | vip5 | read,study |
16| alex | female | vip1 | |
17+------+--------+-------+------------+
18
补充sql_mode
1# 查看sql_mode
2mysql> show variables like "%sql_mode%";
3+----------------------------+---------------------+
4| Variable_name | Value |
5+----------------------------+---------------------+
6| binlogging_impossible_mode | IGNORE_ERROR |
7| block_encryption_mode | aes-128-ecb |
8| gtid_mode | OFF |
9| innodb_autoinc_lock_mode | 1 |
10| innodb_strict_mode | OFF |
11| pseudo_slave_mode | OFF |
12| slave_exec_mode | STRICT |
13| sql_mode | STRICT_TRANS_TABLES |
14+----------------------------+---------------------+
158 rows in set (0.00 sec)
16
1#修改sql_mode为严格模式:在该模式下,如果插入的数据超过限制,则会立即报错
2mysql> set global sql_mode="strict_trans_tables";