约束条件

default默认值
# 插入数据的时候可以指定字段
create table t1(id int,name char(16));
insert t1(name id) values('egon',1);

create table t2(id int,name char(16),gender enum('male','female','others')default 'male');
unique唯一
# 单列唯一
create table t3(id int unique,name char(16));
insert t3 values(1,'egon'),(1,'jason');
insert t3 values(1,'egon'),(2,'jason');

# 联合唯一
ip和port 单个都可以重复,但是加载一起必须是唯一的
create table t4(id int,ip char(16),port int,unique(ip,port));
insert t4 values(1,'127.0.0.1','8080');
insert t4 values(2,'127.0.0.1','8081');
insert t4 values(3,'127.0.0.2','8080');
insert t4 values(4,'127.0.0.1','8080'); #报错
primary key主键
1,单单从约束效果上来看primary key 等价于 not null + unique非空且唯一!!!
create table t5(id int primary key);
insert t5 values(null); # 报错
insert t5 values(1),(1); #报错
insert t5 values(1),(2); 
2,它除了有约束效果之外,它还是innodb存储引擎组织数据的依据
innodb存储引擎在创建表的时候必须要有primary key
因为它类似于书的目录,能够帮助提示查询效率并且也是建表的依据
# 1,一张表中有且只有一个主键,如果你没有设置主键,那么他会从上往下搜索直到遇到一个非空且唯一的字段将它自动升级为主键
create table t6(id int,name char(16),age int not all unique,addr char(32) not null unique);
# 2,如果表中没有主键也没有其他任何的非空且唯一字段,那么innodb会采用自己内部提供的一个隐藏字段作为主键,隐藏意味着你无法使用它,就无法提示查询速度
# 3,一张表中通常都应该有一个主键字段,并且通常将id/uid/sid字段作为主键
#单个字段主键
create table t5(id int primary key,name char(16));
# 联合主键(了解)
create table t4(id int,ip char(16),port int,primary key(ip,port));
···也就意味着以后我们在创建表的时候id字段一定要加primary key
auto_increment自增
当编号特别多的时候 人为的去维护太麻烦
create table t8(id int primary key auto_increment,name char(16));
insert t8(name) values('egon'),('lili'),('jason');
# 注意auto_increment通常加在key主键上 不能给普通字段加

结论

以后在创建表的id(数据的唯一标识id,uid,sid)字段的时候
id int primary key auto_increment

补充:

delete from 在删除表中数据的时候,主键的自增不会停止
truncate t1 清空表数据并且重置主键

表与表之间建立关系

定义一张员工表,表中有很多字段
id name gender dep_name dep_desc
# 1 该表的组织结构不是很清晰(可忽视)
# 2 浪费硬盘空间(可忽视)
# 3 数据的扩展性极差(无法忽视)
#    如何优化?(类似于将所有的代码写在了一个py文件中)
拆分表

外键

外键就是用来帮助我们建立表与表之间关系的
foregin key

表与表的关系

一对多
判断表与表之间关系的时候,前期不熟悉的情况下,一定要换位思考,分别站在2张表的角度考虑
员工表与部门表为例
先站在员工表,思考一个员工能否对应多个部门(一条员工数据能否对应多条部门数据) 不能!
再站在部门表,思考一个部门能否对应多个员工(一个部门数据能否对应多条员工数据) 能!
得出结论:员工表与部门表是单向的一对多,所以关系就是一对多(不能说多对一,也没有多对一)
1,一对多表关系 外键字段在多的一方
2,在创建表的时候,一定要先建被关联表
3,在录入数据的时候,也必须先录入被关联表
foregin key
# sql语句建立表关系、
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));
insert dep(dep_name,dep_desc)values('sb教学部','教书育人'),('外交部','多人外交'),('nb技术部','技术能力有限部门');
insert emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('kevin',3);
# 修改emp 里面的dep_id字段或者dep表里面的id字段
update dep set id=200 where id = 2; 不行
# 删除dep表里面的数据
delete from dep; 不行
# 1 先删除教学部对应的员工数据,之后再删除部门; 操作台频繁
# 2 真正做到数据之间有关系;更新、删除同步
```
级联更新、删除
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)
on update cascade   # 同步更新
on delete cascade   # 同步删除
);
多对多
图书表和作者表
 create table book(
 id int primary key auto_increment,
 title varchar(32),
 price int,
 author_id int,
 foregin key(author_id) references author(id)
 on update cascade 
 on delete cascade);
 
 create table author(
 id int primary key auto_increment,
 name varchar(32),
 age int,
 book_id int,
 foreign key(book_id) references book(id)
 on update cascade
 on delete cascade);
 """
 按照上述的方式创建,一个都别想成功;
 其实我们只是想记录书籍和作者的关系,针对多对多字段表关系,不能在2张原有的表中创建外键,需要你单独再开设一张,专门用来存储2张表数据之间的关系
 """
 create table book(
 id int primary key auto_increment,
 title varchar(32),
 price int);
 
 create table author(
 id int primary key auto_increment,
 name varchar(32),
 age int);
 
 create table book2author(
  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,
 );
一对一
id name age addr phone hobby email.....
如果一个表的字段特别多,每次查询又不是所有的字段都能用到,将表一分为二
一对一 外键字段建在任意一方都可以,但是推荐建在查询频率比较高的表中
create table authordetail(
id int primary key auto_increment,
phone int,
addr varchar(64));

create table author(
id int primary key auto_increment,
name varchar(32),
age int,
authordetail_id int unique,
foreign key(book_id) references book(id)
on update cascade
on delete cascade);

修改表

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 旧表; # 其不能复制主键、外键..
create table new_dep2 select * from dep where id>3; #可以添加条件