约束条件
PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录
FOREIGN KEY (FK) 标识该字段为该表的外键
NOT NULL 标识该字段不能为空
UNIQUE KEY (UK) 标识该字段的值是唯一的
AUTO_INCREMENT 标识该字段的值自动增长(整数类型,而且为主键)
DEFAULT 为该字段设置默认值
UNSIGNED 无符号
ZEROFILL 使用0填充
Not null
当数据库表的某个字段不希望设置为空时(NULL),则在该字段上加上 “NOT NULL” 约束条件,保证所有记录中该字段都有值。若该字段为空,则数据库会报错。非空约束用于确保当前列的值不为空值,非空约束只能出现在表对象的列上。
create table user(
id int,
name char(16)
);
insert into user values(1,null); 可以修改
插入数据可以在表名后面指定插入数据对应的字段
alter table user modify name char(16) not null;
insert into user(name,id) values(null,2); 报错
取消非空约束
alter table user modify name char(16) null;
Default
当数据库表中插入一条新纪录时,如果没有为某个字段赋值,那么数据库系统就会自动为这个字段插入默认值。
create table student(
id int,
name char(16) not null,
gender enum('male','female','others') default 'male'
);
insert into student(id,name) values(1,'liwow'); 成功
Unique
当数据库表中的某个字段上的内容不允许重复时,则可以使用 UK 约束进行设置。即可保证数据库表中的值不重复。唯一约束是指定 table 的列或列组合不能重复,保证数据的唯一性。唯一约束不允许出现重复的值,但是可以为多个 null。
同一个表可以有多个唯一约束,多个列组合的约束。在创建唯一约束时,如果不给唯一约束名称,就默认和列名相同。唯一约束不仅可以在一个表内创建,而且可以同时多表创建组合唯一约束。
单列唯一
create table user1(
id int unique,
name char(16)
);
insert into user1 values(1,'linwow'),(1,'wowlin') 报错
insert into user1 values(1,'linwow'),(2,'wowlin') 成功
联合唯一
create table server(
id int,
ip char(16),
port int,
unique(ip,port)
)
insert into server values(1,'127.0.0.1',8080);
insert into server values(2,'127.0.0.1',8080); 报错
insert into server values(1,'127.0.0.1',8081);
Auto_increment
Auto_increment 是 MySQL 唯一扩展的完整性约束,当为数据库表中插入新纪录时,字段上的值会自动生成唯一的 ID。在具体设置 AUTO_INCREMENT 约束时,一个数据库表中只能有一个字段使用该约束,该字段的数据类型必须是整数类型。
create table test(
id int auto_increment,
name char(16)
);
Primary key
单从约束角度来说primary key就等价于not null unique
create table t1(id int primary key);
desc t1;
insert into t11 values(1),(1); 报错
insert into t11 values(1),(2);
除了约束之外,它还是innodb引擎组织数据的依据,提升查询效率
一张表中必须有且只有一个主键,如果你没有设置主键,那么会从上到下搜索直到遇到一个非空且唯一的字段自动将其设置为主键
如果表里面没有指定任何的可以设置为主键的字段,那么innodb会采用自己默认的一个隐藏字段作为主键,隐藏意味着你在查询的时候无法根据这个主键字段加速查询了
索引:类似于书的目录,没有主键就相当于一页一页翻着查
create table t2(
id int,
name char(16),
age int not null unique,
addr char(16) not null unique
)engine=innodb;
desc t2;
mysql> desc t2;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(16) | YES | | NULL | |
| age | int(11) | NO | PRI | NULL | |
| addr | char(16) | NO | UNI | NULL | |
+-------+----------+------+-----+---------+-------+
联合主键:多个字段联合起来作为表的一个主键,本质还是一个主键
create table t3(
ip char(16),
port int,
primary key(ip,port)
);
desc t3;
mysql> desc t3;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| ip | char(16) | NO | PRI | NULL | |
| port | int(11) | NO | PRI | NULL | |
+-------+----------+------+-----+---------+-------+
主键id作为数据的编号,每次最好能自动递增
create table t4(
id int primary key auto_increment,
name char(16)
);
insert into t4(name) values('linwow'),('linwow'),('linwow'); id字段自动从1开始递增
mysql> select * from t4;
+----+--------+
| id | name |
+----+--------+
| 1 | linwow |
| 2 | linwow |
| 3 | linwow |
+----+--------+
注意:auto_increment通常都是加在主键上,并且只能给设置为key的字段加
Foreign key
# 定义一张部门员工表
id name gender dep_name dep_desc
1 teacher1 male 教学部 教书育人
2 teacher2 male 外交部 漂泊游荡
3 teacher3 male 教学部 教书育人
4 teacher4 male 教学部 教书育人
5 teacher5 female 技术部 技术能力有限部门
将所有的数据都放在一张表内产生的弊端:
1.表的组织结构不清晰
2.浪费存储空间
3.可扩展性极差(修改某一个部门的信息的时候要对表内多个地方进行修改)
如何查找表与表之间的关系:
以员工和部门表为例。查找表关系需要做到换位思考(站在两边去找表关系)
先站在员工表:
找员工表的多条数据能否对应部门表的一条数据
翻译:
多个员工能否属于一个部门
可以!之后不能直接下结论,还需要站在部门表的角度再确认关系
再站在部门表:
找部门表的多条数据能否对应员工表的一条数据
翻译:
多个部门能否有同一个员工
不可以!只有站在两边表的角度都分析过了,才能够下结论
**结论:**员工表单向多对一部门表
一对多关系
1、在创建表时,先建被关联的表dep,才能建关联表emp
create table dep(
id int primary key auto_increment,
dep_name char(10),
dep_comment char(60)
);
create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female') not null default 'male',
dep_id int,
foreign key(dep_id) references dep(id)
);
2、在插入记录时,必须先插被关联的表dep,才能插关联表emp
insert into dep(dep_name,dep_comment) values
('教学部','辅导学生学习,教授课程'),
('外交部','形象大使'),
('技术部','技术能力有限部门');
insert into emp(name,gender,dep_id) values
('teacher1','male',1),
('teacher2','male',2),
('teacher3','male',1),
('teacher4','male',1),
('teacher5','female',3);
3.更新于删除都需要考虑到关联于被关联的关系>>>同步更新与同步删除
create table dep(
id int primary key auto_increment,
dep_name char(10),
dep_comment char(60)
);
create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female') not null default 'male',
dep_id int,
foreign key(dep_id) references dep(id)
on update cascade
on delete cascade
);
insert into dep(dep_name,dep_comment) values
('教学部','辅导学生学习,教授课程'),
('外交部','形象大使'),
('技术部','技术能力有限部门');
insert into emp(name,gender,dep_id) values
('teacher1','male',1),
('teacher2','male',2),
('teacher3','male',1),
('teacher4','male',1),
('teacher5','female',3);
多对多
图书表与作者表之间的关系
仍然站在两张表的角度:
1.站在图书表:一本书可不可以有多个作者,可以!那就是书多对一作者
2.站在作者表:一个作者可不可以写多本书,可以!那就是作者多对一书
双方都能一条数据对应对方多条记录,这种关系就是多对多!
先来想如何创建表?图书表需要有一个外键关联作者,作者也需要有一个外键字段关联图书。问题来了,先创建谁都不合适!如何解决?
建立第三张表,该表中有一个字段fk左表的id,还有一个字段是fk右表的id
create table author(
id int primary key auto_increment,
name char(16)
);
create table book(
id int primary key auto_increment,
bname char(16),
price int
);
insert into author(name) values
('egon'),
('alex'),
('wxx')
;
insert into book(bname,price) values
('python从入门到入土',200),
('葵花宝典切割到精通',800),
('九阴真经',500),
('九阳神功',100)
;
create table author2book(
id int primary key auto_increment,
author_id int,
book_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);
insert into author2book(author_id,book_id) values
(1,3),
(1,4),
(2,2),
(2,4),
(3,1),
(3,2),
(3,3),
(3,4);
一对一
左表的一条记录唯一对应右表的一条记录,反之也一样
create table customer(
id int primary key auto_increment,
name char(20) not null,
qq char(10) not null,
phone char(16) not null
);
create table student(
id int primary key auto_increment,
class_name char(20) not null,
customer_id int unique, 该字段一定要是唯一的
foreign key(customer_id) references customer(id) 外键的字段一定要保证unique
on delete cascade
on update cascade
);
三种外键关系都是用foreign key,区别在于如何使用以及其他条件限制即可做出三种关系