约束条件补充
补充知识点:插入数据的时候可以指定字段
createtable t1(
id int,
name char(16)
);
insert into t1(name,id) values('jason',1) # 在t1里面的name和id字段插入‘jason’和1
1、defaul 设置默认值
create table t2(
id int,
name char(16),
gender enum('male','female','others') default 'male');
insert into t2(id,name) values(1,'jason');
insert into t2 values(2,'egon','female');
2、unique 设置唯一值
# unique
单列唯一
create table t3(
id int unique, #将id字段的数据类型设置成不可重复
name char(16)
);
测试:
insert into t3 values(1,'js'),(1,'eg'); #报错
insert into t3 values(1,'js'),(2,'eg');
#unique
联合唯一
比如:ip和port
单个可以重复,但是加在一起必须是唯一的。就是联合唯一。
create table t4(
id int,
ip char(16),
port int,
unique(ip,port) # 将id和端口的组合值设置成不可重复
)
测试:
insert into t4 values(1,'127.0.0.1',8080);
insert into t4 values(2,'127.0.0.1',8081);
insert into t4 values(3,'127.0.0.2',8080);
insert into t4 values(1,'127.0.0.1',8080); #报错
3、primary key 主键
1、单从约束效果上来看primary key 等价与not null+unique ==》非空且唯一
create table t5(id int primary key); #将id字段设置为主键
insert into t5 values(null); #报错
insert into t5 values(1),(1); #报错
insert into t5 values(1),(2);
2、除了有约束效果外 还是innodb存储引擎组织数据的依据,innodb存储引擎在创建表的时候必须要有primary key,因为他类似于书的目录 能够帮助提示查询效率 并且也是建表的依据。
#1 一张表中,有且只有一个主键,如果你没有设置主键 那么会从上往下搜索直到遇到一个非空且唯一的字段将他自动升级为主键。
create table t6(
id int,
name char(16),
age int not null unique,
addr char(32) not null unique
);
#2 如果表中没有主键也没有其他任何的非空且唯一字段 那么innodb会采用自己内部提供的一个隐藏字段为主键,你无法使用到他。且没有明确定义的主键可能会导致查询速度下降,因为InnoDB需要通过隐藏字段进行索引扫描和数据访问。
#3 一张表中都应该有一个主键字段 并且通常将id、uid、sid字段作为主键
#单个字段主键
create table t5(
id int primary key,
name char(16)
)
#联合主键(多个字段加起来组成一个主件)
create table t7(
id int,
ip char(16),
port int,
primary key(ip,port)
);
4、auto_increment 自增
auto_increment是专门给主键服务的,当编号特别多的时候,会自动,以自增的方式添加id号。
create table t8(
id int primary key auto_increment,
name char(16)
);
测试
insert into t8(name) values('jason'),('egon'),('kevin');
以后在创建表的id(数据的唯一标识)字段的时候可以添加:
id int primary key auto_increment
# 注意auto_increment只能加在主键上,不能给普通字段加
测试:
create table t9(
id int primary key auto_increment,
name char(16),
cid int auto_incremeent
);#报错
#注意,id内部是自增的,如果把原有的表上的数据清空之后的话,再去自增,就不会刷新id号了,而是根据之前的ID继续自增。
delete from t8;
insert into t8(name) values('js')
最终的输出结果是 id:4,name:js
delete from 在删除表中的数据的时候 主键的自增不会停止
truncate t8; 清空表数据并且重置主键
表与表之间建关系(约束)(重点)
外键:外键就是用来帮助我们建立表与表之间关系的特殊字段。
foregin key
表关系:
1、一对多关系
以员工表为例,在创建表关系之前需要先确定是单向的一对多还是多向的一对多。
(分析表关系)
1、一对多表关系 外键字段建在多的一方
2、在创建表的时候要先创建被关联表
3、 在录入数据的时候也要先录入被关联表
#创建部门表
create table dep(
id int primary key auto_increment, #设置主键
dep_name char(16),
dep_desc char(32)
);
#创建员工表
create table emp(
id int primary key auto_increment, #设置主键
name char(16),
gender enum('male','female','others') default 'male', #设置默认值
dep_id int,
foreign key(dep_id) references dep(id) # 声明dep_id是一个外键字段 ,与dep表的id字段关联
on update cascade # 联级更新:更新就同步更新
on delete cascade # 联级删除:删除就同步删除
);
2、多对多关系
针对多对多字段表关系 不能在两张原有的表中创建连接,需要你再开一张单独的表来创建连接:媒介表
#创建书名
create table book(
id int primary key auto_increment,
title varchar(32),
price int,
author_id int
);
#创建作者名
create table author(
id int primary key auto_increment,
name varchar(32),
age int,
book_id int
);
针对多对多字段表关系 不能在两张原有的表中创建连接,需要你再开一张单独的表来创建连接:
媒介表
#创建媒介表
create table book2author(
id int primary key auto_increment,
author_id int,
book_id int,
froeign key(author_id) references author(id)
on update cascade
on delete cascade,
froeign key(book_id) references book(id)
on update cascade
on delete cascade
);
#添加数据
insert into book(title,price) values('jpm',6666),('lzzy',9966),('tpt',6666);
insert into author(name
,age) values('jason',18),('egon',73);
#建立关系
insert into book2author(author_id,book_id) values(1,1),(1,2),(2,3);
3、一对一关系
id name age addr phone hobby email.....
如果一个表的字段特别多,每次查询又不是所有的字段都能用得到。
可以将表一分为二
如:
用户表:
id name age
用户详情表:
id addr phone hobby email....
一对一 外键字段建在任意一方都可以,但推荐建在查询频率比较多的地方。需要注意的是,要加上unique以保证连接的唯一性
#创建用户详情表
create table authordetail(
id int primary key auto_increment,
phone int,
addr varchar(64)
);
#创建用户表
create table author2(
id int primary key auto_increment,
name varchar(32),
age int,
authordetail_id int unique,
foreign key(authordetail_id) references author(id)
on update cascade
on delete cascade
);
#添加数据
insert into authordetail values(111,'上海'),(222,'广东');
insert into author2(name,age) values('js',18),('eg',28);
补充:
表与表建立关系的话可以通过2种方式建立关系:
1、通过外键建立方式
2、自己通过sql语句逻辑层上面建立关系
delete from emp where id=1
delete from dep where id=1
#就是存手打,其实没有关系,但是我每次删emp id的时候都会吧dep的id也删除,那就也关系了。
创建外键会消耗一定的资源,并且增加了表与表之间的耦合度。
在实际项目中,如果表特别多,其实可以不做任何外键处理。
直接通过sq1语句来建立逻辑层面上的关系到底用不用外键取决于实际项目需求。
修改表:
# mysql不区分大小写
1、修改表名
alter table 表名 rename 新表名;
2、增加字段
alter table 表名 add 字段名 字段类型(宽度) 约束条件;
#默认是在表的尾部增加
alter table 表名 add 字段名 字段类型(宽度) 约束条件 first;
alter table 表名 add 字段名 字段类型(宽度) 约束条件 after 字段名字;
3、删除字段
alter table 表名 drop 字段名;
4、修改字段
alter table 表名 modify 字段名 字段类型(宽度)约束条件;
alter table 表名 change 旧字段名 新字段名 字段类型(宽度)约束条件;
复制表:
我们 sql语句查询的结果其实也是一张虚拟表
create table 新表名 select *from 旧表名; # 不能复制 键、索引...,只能复制表结构和数据,配置不能复制。