字段约束条件,表与表之间的关系

发布时间 2023-04-06 16:16:05作者: 无敌大帅逼

约束条件

1.无符号,零填充(unsigned,zerofill)

unsigned
	id int unsigned  #只能存正数
zerofill
	id int(5) zerofill #如果输入的不满5位的话就用0填充

2.非空(not null)

create table t1(
	id int,
 	name varchar(16)
);
insert into t1(id) values(1); # 1  null
insert into t1(name) values('jason');  # null  jason
insert into t1(name,id) values('kevin',2); #kevin  2
# ps:所有字段类型不加约束条件的情况下默认都可以为空
    

    
create table t2(
	id int,
 	name varchar(16) not null #不能输入为空
);
insert into t2(id) values(1);  #报错
insert into t2(name) values('jason');
insert into t2 values(1,'');  #只要给了值,不管是什么,就算你有值
insert into t2 values(2,null);  #报错 null是关键字

3.默认值(default)

create table t3(
	id int default 666,
	name varchar(16) default '匿名'
);
insert into t3(id) values(1);  #1对应的name为匿名
insert into t3(name) values('jason');  #jason对应的id为666
insert into t3 values(2,'kevin');
#经常配合非空一起用
#ps:性别  默认男性

4.唯一值(unique)

'''单列唯一'''
create table t4(
	id int unique,
	name varchar(32) unique
);
insert into t4 values(1,'jason'),(2,'jason'); #报错  name不能重复



'''联合唯一'''
create table t5(
	id int,
 	ip varchar(32),
 	port int,
 	unique(ip,port) #ip 或者 port有一个重复没关系,但是不能全部一样
);
insert into t5 values(1,'127.0.0.1',8080),(2,'127.0.0.1',8081),(3,'127.0.0.2',8080);  #True
insert into t5 values(4,'127.0.0.1',8080);  #False

5.主键(primary key)

#从约束条件来看,它相当于not null unique—————>非空且唯一
'主键可以加快查询速度!!因为主键本质上也是一种索引'
#InnoDB存储引擎规定一张表至少要有一个主键,你会发现,我们之前创建表的时候,并没有主键,但是,也创建成功了,为什么呢?
'InnoDB存储引擎内部有一个隐藏的字段,作为了主键,我们看不到,并且,这个隐藏的主键不能加快查询速度,就是因为InnoDB存储引擎建表就是有主键来构成的,加这个隐藏的字段作为主键,仅仅是为了把表创建成果.'

'所以以后我们创建表的时候,都要创建一个主键字段,一般我们都给表中的id字段添加主键'
id--->(uid,cid ,sid,....id)
#如何给字段添加主键
id int  primary key

create table t8 (
    	id int primary key,  # 这个id字段就已经有了主键的特性
        name varchar(32)
    );

6.自增(auto_increment)

该约束条件不能单独出现 并且一张表中只能出现一次 主要就是配合主键一起用
create table t9(
	id int primary key auto_increment,
 	name varchar(32)
);
"""
自增特性
	1.自增不会因为数据的删除而回退 永远自增往前
	2.如果自己设置了更大的数 则之后按照更大的往前自增
	
	3.如果想重置某张表的主键值 可以使用
		truncate t9;  清空表数据并重置主键
"""

7.补充一些其他SQL语句

语法:
1. 修改表名
      ALTER TABLE 表名 RENAME 新表名;
2. 增加字段
      ALTER TABLE 表名 ADD 字段名  数据类型 [完整性约束条件…],'添加在末尾'
      ALTER TABLE 表名 ADD 字段名  数据类型 [完整性约束条件…]  FIRST;'将add的字段名添加在第一位'
      ALTER TABLE 表名 ADD 字段名  数据类型 [完整性约束条件…]  AFTER 字段名; '添加到该字段名后面'
3. 删除字段
      ALTER TABLE 表名 
                          DROP 字段名;
4. 修改字段  # modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
      ALTER TABLE 表名  MODIFY  字段名 数据类型 [完整性约束条件…];
      ALTER TABLE 表名  CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];

外键

外键前戏

# 外键前戏
	创建一张员工表
    	id name age	dep_name dep_desc
"""
缺陷
1.表的重点不清晰				可以忽略
	到底是员工表还是部门表
2.表中相关字段一直在重复存储		可以忽略
	浪费存储空间
3.表的扩展性极差,牵一发而动全身   不能忽略
"""
	解决方式
    	将上述一张表拆分成两张表
        	emp与dep
  		# 上述三个缺陷全部解决
"""
带来了一个小问题 表与表之间的数据没有对应关系了
"""

外键字段>>>:部门编号
    其实就是用来标识表与表之间的数据关系
    # 简单的理解为该字段可以让你去到其他表中查找数据

表与表之间建立关系

表关系、数据关系其实意思是一样的 知识说法上有区分

关系总共有四种
	一对多
  	多对多
 	一对一
 	没有关系
  
关系的判断可以采用'换位思考'原则

一对多关系

以员工和部门表为例
    	先站在员工表的基础之上
        	问:一个员工信息能否对应多个部门信息
            答:不可以
        再站在部门表的基础之上
        	问:一个部门信息能否对应多个员工信息
            答:可以
        结论:一个可以一个不可以 那么表关系就是"一对多"
            员工表是多 部门表是一
        """
        针对一对多的表关系 外键字段建在多的一方
        """
        # 表关系没有'多对一'一说 都是'一对多'
 # 在创建外键关系的时候,先创建出来基础字段,
'
使用SQL语句建立真正意义上的表关系 可以先创建不含外键字段的基本表
之后再添加外键字段'
	create table emp(
		id int primary key auto_increment,
		name varchar(32),
		age int,
		dep_id int,
		foreign key(dep_id) references dep(id)
		on update cascade  # 级联更新
    	on delete cascade  # 级联删除
	);
	create table dep(
		id int primary key auto_increment,
		dep_name varchar(32),
		dep_desc varchar(254)
	);
1.在创建表的时候 需要先创建被关联表(没有外键字段的表)

2.在插入新数据的时候 应该先确保被关联表中有数据

3.在插入新数据的时候 外键字段只能填写被关联表中已经存在的数据

4.在修改和删除被关联表中的数据的时候 无法直接操作
	如果想要数据之间自动修改和删除需要添加额外的配置
	on update cascade  # 级联更新
    on delete cascade  # 级联删除

"""
由于外键有实质性的诸多约束 当表特别多的时候外键的增多反而会增加耦合程度
	所以在实际开发项目中 有时候并不会使用外键创建表关系
	而是通过SQL语句层面 建立逻辑意义上的表关系
		eg:操作员工表的sql执行完毕之后 立刻跟着执行操作部门的sql
"""

多对多关系

以书籍表与作者表为例
	1.先站在书籍表的角度
  		问:一本书能否对应多个作者
      答:可以
 	2.再站在作者表的角度
    	问:一个作者能否对应多本书
      	答:可以
   结论:两个都可以 关系就是'多对多'
 	针对'多对多'不能在表中直接创建 需要新建第三张关系表
#创建2张表分别是书和作者
create table book(
	id int primary key auto_increment,
 	title varchar(32),
  	price float(5,2)
);
create table author(
	id int primary key auto_increment,
 	name varchar(32),
  	phone bigint
);

#创建一张新的表来关联起书表和作者表的id
create table book2author(
	id int primary key auto_increment,
   author_id int, #作者的id
 	foreign key(author_id) references author(id)
	on update cascade  # 级联更新
    on delete cascade  # 级联删除
	
   book_id int, #书的id
  	foreign key(book_id) references book(id)
	on update cascade  # 级联更新
    on delete cascade  # 级联删除
);

一对一关系

以用户表与用户详情表为例
	1.先站在用户表的角度
  		问:一个用户能否对应多个用户详情
      答:不可以
 	2.再站在用户详情表的角度
    	问:一个用户详情能否对应多个用户
      	答:不可以
   结论:两个都可以 关系就是'一对一'或者没有关系	
   针对'一对一'外键字段建在任何一方都可以 但是推荐建在查询频率较高的表中

#用户
create table user(
	id int primary key auto_increment,
  	name varchar(32),
 	detail_id int unique,
  	foreign key(detail_id) references userdetail(id)
  	on update cascade
  	on delete cascade
);

#用户详情信息
create table userdetail(
	id int primary key auto_increment,
  	phone bigint
);