5-5 数据库笔记整理
今日内容概要
约束条件
表与表之间的完整语法大全
复制表
一、约束条件
default默认值
#补充知识点,插入数据的时候可以指定字段 create table t1( id int, name char(16) ); insert into t1(name,id) values('jason',1); 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');
unique 唯一
#单列唯一 create table t3( id int unique, name char(16) ); insert into t3 values(1,'jason'),(1,'egon'); insert into t3 values(1,'jason'),(2,'egon'); #联合唯一 ip 和 port 单个都可以重复但是加载一起必须是唯一的 create table t4( id int, ip char(16), port int, unique(ip,port) ); 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(4,'127.0.0.1,8080); 会报错
primary key主键
1、单单从约束效果上来看primary key等价于not null + unique 非空且唯一! create table t5(id int primary key); insert into t5 values(null); 会报错 insert into t5 values(1),(1); 会报错 insert into t5 values(1),(2); 2、它除了有约束效果之外还是innodb存储引擎组织数据的依据 innodb存储引擎在创建表的时候必须要有primary key 因为它类似于书的目录,能够帮助提示查询效率并且也是建表的依据 #一张表中只有一个主键,如果没有设置主键,那么会从上往下搜索直到找到一个非空且唯一的字段将它自动升级为主键 create table t6( id int, name char(16), age int not null unique, addr char(32) not null unique ); #如果表中没有主键也没有其他任何的非空且唯一字段 ,那么innodb会采用自己内部提供的一个隐藏字段 作为主键,隐藏意味着你无法使用到它,就无法提示查询速度 #一张表中通常都应该有一个主键字段,并且通常将id/uid/sid字段作为主键 #单个字段主键 create table t5( id int primary key name char(16) ); #联合主键(多个字段联合起来作为表的主键,本质还是一个主键) create table t7( 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 into t8(name) values('jason'),('egon'),(kevin'); #注意auto_increment通常都是加在主键上的不能给普通字段 加 create table t9( id int primary key auto_increment, name char(16), cid int auto_incrment ); 会报错以
以后在创建表的id(数据的唯一标识id、uid、sid)字段的时候
id int primary key auto_increment
#补充 delete from t1 删除表中数据后 主键的自增不会停止 truncate t1 清空表数据并且重置主键
表与表之间建关系
定义一张员工表,表中有很多字段 id name gender dep_name dep_desc 1、该表的组织结构不是很清晰 2、浪费硬盘空间 3、数据的扩展性极差 如何优化? 将员工表拆分 员工表和部门表
外键
外键就是用来帮助我们建立表与表之间关系的 foreign key
表与表之间最多只有四种关系 一对多关系 在mysql的关系中没有多对一一说 一对多,多对一都叫一对多! 多对多关系 一对一关系 没有关系
判断表与表之间关系的时候,换位思考,分别站在两张表的解度考虑 员工表与部门表为例 先站在员工表 思考一个员工能否对应多个部门(一条员工数据能否对应多条部门数据) 不能!!! 再站在部门表 思考一个部门能否对应多个员工(一个部门数据能否对应多条员工数据) 能!!! 得出结论 员工表与部门表示单向的一对 多 所以表示关系就是一对 多 foreign key 1 一对多表关系 外键字段建在多的一方 2 在创建的时候 一定要建被关联表 3 在录入数据的时候也必须先录入被关联表 #sql语句建立表关系 create table dep( id int primary key auto_increment, dep_name char(16), dep_desc cahr(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 into dep(dep_name,dep_desc) values('sb教学部','教书育人'),('外交部','多人外交‘),(’nb技术部‘,‘技术能力有限部门’); insert into emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('kevin',3); #修改dep表里面的id字段 update dep set id=200 where id=2; 不行 #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 ); insert into dep(dep_name,dep_desc) values('教学部’,‘教书育人’),(‘外交部’,‘多人外交’),(‘技术部’,‘技术能力有限部门’; insert into emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('kevin',3);
update dep set id=2;
delete from dep where id=1;
多对多
#图书表和作者表 针对多对多字段表关系,不能在两张原有的表中创建外键,需要单独再开设一张,专门用来存储两张表数据之间的关系 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 book1author( 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 如果一个表的字段特别多,每次查询又不是所有的字段都能用得到 将表一分为二 用户表 用户表 id name age 用户详情表 id addr phone hobby email 站在用户表 一个用户能否对应多个用户详情 不能 站在详情表 一个详情能否属于多个用户 不能 结论:单向的一对多都不能成立,那么这个时候两者之间的表关系就是一对一,或者没有关系 一对一外键字段 建在任意一方都中以,但是推荐查询频率比较高的表中 create table authordatail( id int primary key auto_increment, phone int, add varchar(64) ); create table author( id int primary key auto_increment, name varchar(32), age int, authordetail_id int unique, foreign key(authordetail_id) references authorde on update cascade on delete cascade );
总结 表关系的建立需要用到foreign key 一对多 外键字段建在多的一方 多对多 自己开设第三张存储 一对一 建在任意一方都可以,但是推荐建在查询频率较高的表中
修改表
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;