前言
本篇博客学习数据库的详细建表语句,数据库数据类型以及约束条件。
详细建表语句
在介绍建表语句之前需要了解一下存储引擎。
存储引擎
MySQL 支持的存储引擎有以下几种:
以后我们使用的就只有 InnoDB 引擎,可以看到默认情况下存储引擎就是 InnoDB,建立一个表的时候,可以看看在文件夹里发生了什么。
mysql> create table t1(id int, name char);
建表成功后在文件夹里多了两个文件:
- t1.frm
- t1.ibd
frm是 frame 的缩写是表示该表的数据结构,而 ibd 表示 InnoDB data 表示存储的是 InnoDB 引擎的数据。
存储引擎就相当于一个用来存取数据的软件。
指定以某种存储引擎建表
create table t2(id int name char)engine=memory;
建表语句
创建表的完整语法,中括号里面的表示可选参数。
create table 表名(
字段1 数据类型[(宽度) 约束条件],
字段2 数据类型[(宽度) 约束条件],
字段3 数据类型[(宽度) 约束条件]);
最后一个字段后面不能加逗号,否则会报错。
类型:使用限制字段必须以什么样的数据类型传值
约束条件:约束条件是在类型之外添加一种额外的限制。
注意
- 在同一张表中,字段名不能相同;
- 宽度和约束条件可选,字段名和类型是必须的;
- 最后一个字段后不加逗号。
数据类型
整型:int、tinyint、bigint等
整型默认是有符号的,可以通过约束条件改变(unsigned);
mysql> create table t3(x tinyint unsigned);
可选参数里面的宽度只有整型表示的是显示宽度,其他的都表示存储限制。
mysql> create table t4(x int(8) unsigned zerofill);
显示时不够八位的使用0填充,如果超过八位正常显示。
如果不指定限制宽度会有默认值:
mysql> create table t5(id int unsigned);
如果是有符号的整型,则会比无符号的多一位,因为要显示正负号。
mysql> create table t6(id int);
强调:对于整型来说,数据类型后的宽度并不是存储限制,而是显示限制。所以在创建表示,如果字段采用的是整型类型,完全无需指定显示宽度,默认的显示宽度,足够显示完整当初存放的数据。
浮点型:float、double、decimal等
float 4字节
double 8字节
decimal 不固定
mysql> create table t7(num float(m,d));
m 表示总长度 d 表示小数部分长度
长度表示的是字符长度而不是数据存储范围。
各个类型的最大长度
float (255,30)
double (255,30)
decimal (65,30)
区别
float 与 double 的精度不同,都是不准确的小数,decimal 准确的小数不会丢失精度
具体使用哪种类型得需要使用场景判断
float 满足大部分使用场景,decimal 适合银行系统,科学研究。
括号中 m 和 d 的值,可以限制数据存储范围,与整型不同
重点:记住 m 和 d 的含义。
字符型
常用两种
char 定长字符串
varchar 可变长度字符串
注意:字符串中,长度指定的是数据的字符长度,与字节没有关系,在创建时 varchar 必须指定,char 有默认值。
不同点:
char 类型在取数据时,根据长度来获取,不关心真实数据长度
无论数据有多长,占用的空间是固定的,造成了一定空间浪费。
varchar 类型在取数据时,先获取数据长度,在根据长度获取真实数据时也关心真实数据长度,先存储长度需要一个字节,在存储真实数据不会浪费空间,但是由于需要计算数据的长度,所以存取速度会比定长慢。
相同点:
括号中的数字,都是表示存储最大字符长度。
char 使用频率更高。
mysql 会在存储数据时自动将数据末尾的空格去掉,如果必须要存空格,需要修改 sql_mode 增加PAD_CHAR_TO_FULL_LENGTH 意思是把空格当做有效数据。
由于自动去除空格这个机制,在使用等于符号和 like 时有区别:
select * from t1 where name = 'yh';
会自动去除空格
select * from t1 where name like 'yh';
like 用于模糊匹配,使用%表示0或任意个字符
使用_表示一个任意字符。
日期类型
year
time
date
datetime
timestamp
Timestamp 特点是可以给 null 自动输入当前时间
当这条记录被修改了会自动更新当前时间
集合与枚举类型
枚举
enum 可以指定一堆字符串的值,在插入数据时
数据必须在堆字符串中的其中一个(‘’男的‘’,‘’女的‘’)多选一
集合
set 可以指定一堆字符串的值 再插入数据时
数据必须这堆字符串中的其中一个(‘’男的‘’,‘’女的‘’)多选一
共同点:数据都是字符串类型
约束条件
是一种对数据的限制。
约束的作用?
为了保证数据的正确性,完整性
例如要存出密码 char(20) 只限制了类型和长度,无法保证数据的正确性。
额外的约束
语法:
创建时指定约束
create table 表名称(字段名 类型(长度) 约束名称1,约束名称n,...)
后期修改的方式添加 约束
alter table 表名称 modify 字段名 类型(长度) 约束名称1 约束名称n,...
NOT NULL 非空约束 限制该字段的值不能为空
UNIQUE 唯一性约束 限制该字段的值是唯一的不能出现重复
DEFAULT 默认值约束 如果插入数据时没有指定该字段的值则使用默认值
PRIMARY KEY 主键约束 限制该字段 不能为空 并且是唯一的 可以唯一标识一条数据 *****
FOREIGN KEY 外键约束 用来指向另一个表的主键
每个表都应该有一个主键,需要唯一标识,否则可能出现完全相同的两个数据,无法区分 UNIQUE 不能重复,但是可以为空,这样的话不能唯一标识。
UNIQUE NOT NULL 不能为空且唯一 可以唯一标识一条数据,书写顺序无所谓。
UNIQUE NOT NULL 与主键的区别
UNIQUE NOT NULL 不能被其他表引用(不能作为其他表的外键)
UNIQUE NOT NULL 约束 一个表中可以有多个,但是主键只能有一个。
索引:用于加速查询
InnoDB 中索引是树形结构
为了提高查询效率,InnoDB 会找一个不为空且惟一的字段作为主键
如果表中不存在这样的字段,会自动帮你建一个隐藏逐渐字段,但是无法提升查询效率。
只要是使用 InnoDB,就应该为每个表指定一个非空且唯一的字段,InnoDB 组织数据时,首先使用主键,如果没有主键,找一个非空且惟一的字段,如果没有那就会建一个隐藏字段。
多字段联合主键:不常用
当一个表中,由于业务需求没有一个非空且惟一的字段时,我们可以建一个新的字段专门作为主键,管理主键的值挺麻烦,需要记录上一次的主键值,MySQL 使用 auto_increment 自动增长,auto_increment 只能用于整型字段,并且该字段必须具备索引。所以主键都会加上auto_increment。
手动修改自动增长计数
alter teble 表名 auto_increment 新值;
注意:如果新的值小于当前最大值是无效的。
insert 语句
mysql> insert into 表名 values(值1,值n,...)
要求值得顺序个数必须与表字段完全对应
另一种写法:
mysql> insert into 表名(字段名,字段名n,...) values(值1,值n,...)
可以选择性插入某些字段,要求值得顺序必须与表名后面声明的字段一致。
SQL_MODE
查看数据库的模式
mysql> show variables like '%mode%';
在最后一行的 sql_mode 有个值为NO_ENGINE_SUBSTITUTION意思为非严格模式,作用是在如果你存储的数据类型超过限制条件了也不会报错反而会存储限制条件的边界大小,比如 tinyint,如果是非严格模式,你存储一个大于255的数据,不会保错会存储为255。
mysql> create table t0(id tinyint);
修改为严格模式
mysql> set global sql_mode='strict_trans_tables';
设置完成后,需要重新连接才会生效。
修改为严格模式后如果插入的值超过数据类型的界限后就会报错。