在讲 MySQL 中数据表的增删改查之前,我们先需要创建表。创建表的过程中需要制定表字段的类型,字段的约束以及表的存储引擎等。所以非常有必要先介绍些MySQL的基础语法知识。
字符集:字符的集合,常见的字符集有ASCLL、GBK和Unicode等;
校验规则:当前字符集内,字符之间大小的比较规则。
数值型#
1. 数值类型
类型 | 字节 | 最小值 | 最大值 |
---|---|---|---|
TYNYINT | 1 | -128/0 | 127/255 |
SMALLINT | 2 | -32768/0 | 32767/65535 |
MEDIUMINT | 3 | -8388608/0 | 8388607/16777215 |
INT | 4 | -2147483648/0 | 2147483647/4294967295 |
BIGINT | 8 | 很大... | 很大... |
INT(M) UNSIGNED ZEROFILL
可以这样定义数值类型。其中M,表示显示宽度,显示宽度不限制数值的范围。配合zerofill来使用,可以在小于显示宽度的位数前增加0。ZEROFILL 自动为unsigned。Unsigned 表示无符号,只表示正数。
2. 小数类型
单精度(不推荐使用)
FLOAT(M,D) UNSIGNED ZEROFILL
双精度
DOUBLE(M,D) UNSIGNED ZEROFILL
其中M表示总的位数(包括小数位数),D表示小数位数。M,D可以控制保存的范围。比如DOUBLE(10,2)可以表示 -99999999.99 到 99999999.99。
定点数(金额,科学数据推荐使用这个类型)
DECIMAL(M,D) UNSIGNED ZEROFILL
其中M表示总的位数,D表示小数位数。此M,D可以控制保存的范围。M,D省略,默认为10,0;
日期型#
可以考虑使用long类型来存储,也就是时间戳。
或者使用datetime(或timestamp)类型来存储。但是这两个类型有个问题:datetime不包含时区的概念,也就是你传'2019-09-08 12:56:34',它存储的就是这个值。timestamp虽然包含时区的概念,但是它的取值范围比较小(1970-01-01 00:00:01 -- 2038-01-19 03:14:07),有些情况不够用。
所以会有上面的建议,使用long类型存时间戳。
字符串型和二进制#
选择数据类型的建议#
当选择字段类型时,应该遵循下面几个原则:
MySQL中列约束一般用来保证数据库表数据的正确性和完整性。主键约束#
主键:可以唯一标识一条记录的一列或者多列的组合。主键具有以下特点:
每个表只能定义一个主键;
任意两行都不具有相同的主键值;
每一行都必须具有一个主键值(主键列不允许NULL值);
主键列中的值不允许修改或更新;
主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)。
-- 添加主键
create table tbl_user
(
user_id int primary key,
user_name varchar(20)
);
create table tbl_user
(
user_id int,
user_name varchar(20),
primary key(user_id)
);
alter table tbl_user add primary key(user_id,user_name);
ALTER TABLE tbl_test1 ADD CONSTRAINT pk_tbl_test1 PRIMARY KEY(id);
-- 删除主键(假如主键列具有auto_increment属性,需要先删除自增长属性,再删除主键)
ALTER TABLE TABLE_NAME DROP PRIMARY KEY;
外键约束#
外键(FK,foreign key):如果一个A表的字段指向另一个B表的主键,则此字段就为A表的外键。用于表示表之间的关系。存在外键的表,称之为从表(子表),外键指向的表,称之为主表(父表)。外键只被innodb存储引擎所支持。其他引擎是不支持的。一个表可以存在一个或者多个外键。
外键的默认作用有两点:
外键的定制有三种约束模式:
-- 添加外键
create table tbl_user
(
user_id int primary key,
user_name varchar(20),
class_id int,
CONSTRAINT fk_tbl_user foreign key(class_id) references tbl_class(class_id)
)
alter table tbl_user add CONSTRAINT fk_tbl_user foreign key(class_id) references tbl_class(class_id);
-- 删除外键
alter table tbl_user drop foreign key fk_tbl_user;
唯一性约束#
唯一性约束可以确保一列或者多列不出现重复值。
Unique和Primary Key的区别:
-- 创建唯一性约束
CREATE TABLE tbl_test2
(
id INT,
name1 VARCHAR(20),
nick_name VARCHAR(20),
age INT,
CONSTRAINT unique_tbl_test2_name UNIQUE(name1,nick_name)
)
alter table tbl_test2 add constraint unique_tbl_test2_name UNIQUE(name1,nick_name);
-- 删除唯一性约束(从下面的语法我们可以看出唯一性约束其实是个索引)
alter table tbl_test2 drop index unique_tbl_test2_name
检查约束#
检查约束用于检查数据库表中某些字段时候符合条件。
-- 创建检查约束
CREATE TABLE tbl_test3
(
id INT,
name1 VARCHAR(20),
nick_name VARCHAR(20),
age INT,
CONSTRAINT check_tbl_test3 CHECK(age>20 AND age<40)
)
alter table table_test3 add constraint check_tbl_test3 check(age>20 and age<40);
-- 删除检查约束
alter table tbl_test3 drop constraint check_tbl_test3
默认值约束#
插入一条记录时没有给这个字段赋值,如果建表时设置了默认值,系统就会给这个字段赋默认值。
-- 添加默认值
CREATE TABLE tbl_test4
(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT 'wuming',
age INT
)
ALTER TABLE tbl_test4 MODIFY COLUMN age INT DEFAULT 20;
-- 删除默认值(删除age字段的默认值)
ALTER TABLE tbl_test4 CHANGE COLUMN age age INT DEFAULT NULL;
非空约束#
-- 添加非空约束
CREATE TABLE tbl_test5
(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
age INT
)
ALTER TABLE tbl_test5 MODIFY COLUMN age INT NOT NULL;
-- 删除非空约束
ALTER TABLE tbl_test5 MODIFY COLUMN age INT NULL;
自动增长约束#
该列上必须有索引,not null,只能存在一个自动增长的列。通常定义在主索引(主键)字段上。
通常 自动增长是从1开始递增,但是可以通过修改表属性,更改初始值。表属性 auto_increment=x;(如果比已存在的小,则会从已有的最大值新记录)
存储引擎可以理解为表的存储结构,每种存储引擎都支持不同的特性。MySQL支持插件式的存储引擎,可以为每张数据表指定不同的存储引擎。常用的存储引擎有以下几种:
我们也可以使用下面命令查看当前数据库支持哪些存储引擎:
-- 查看支持的存储引擎
show engines;
下面对最常用的三种存储引擎做下简单介绍:
所以我们应该根据应用的具体需求选择合适的存储引擎,而不是不加思考的都选择默认存储引擎(INNODB)。
如果要提供提交、回滚和恢复的事务安全(ACID兼容)能力,并要求实现并发控制,InnoDB是一个很好的选择。如果数据表主要用来插入和查询记录,则MyISAM引擎提供较高的处理效率。如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存的MEMORY引擎中,MySQL中使用该引擎作为临时表,存放查询的中间结果。如果只有INSERT和SELECT操作,可以选择Archive引擎,Archive存储引擎支持高并发的插入操作,但是本身并不是事务安全的。Archive存储引擎非常适合存储归档数据,如记录日志信息可以使用Archive引擎。
表设计原则:
范式是指数据库设计规范。一共存在6个级别的范式,1NF,2NF,3NF,4NF,5NF,6NF。要求是从低到高逐渐递增。关系型数据库必须满足1NF,通常满足到3NF就可以了。