MySQL之字段约束条件
一、MySQL之字段约束条件
1.unsigned 无符号
unsigned 为非负数,可以用此类增加数据长度
eg:tinyint最大是127,那tinyint unsigned最大可以到127 * 2
int最大是65535,那int unsigned最大可以到65535 * 2
create table t1(id tinyint unsigned);
2.zerofill 零填充
通俗的意思就是补零
create table t1(id int(3) zerofill)
3.not null 非空
ps:所有字段类型不加约束条件的情况下默认都可以为空
在值里面写空字符串也算个字符,不为空
create table t1(id int not null,name varchar(16));
4.default 默认值
# 默认值遵循的原则就是有值就用传的值,没有值就用默认值
create table t1(id int,name varchar(16) not null default 'jason');
5.unique 唯一值
MySQL通过给字段添加唯一性约束来设置行值唯一,设置的字段是不会重复的,是唯一的
单列唯一:
create table t1(id int unique,name varchar(16));
insert into t4 values(1,'jia'),(2,'jason');
再插入相同的字段就会报错,原因是设置了唯一索引,不允许重复添加
联合唯一:
mysql> create table t5(
-> id int,
-> ip varchar(32),
-> port int,
-> unique(ip,port)
-> );
mysql> insert into t5 values(1,'127.0.0.1',8080),(2,'127.0.0.1',8081),(3,'127.0.0.2',8080);
mysql> insert into t5 values(4,'127.0.0.1',8080);
再次插入违反了唯一性,就报错
二、字段约束条件之主键
1.单从约束层面上而言主键相当于not null + unique(非空且唯一)
mysql> create table t6(
-> id int primary key,
-> name varchar(16)
-> );
mysql> insert into t6(name) values('jason');
ERROR 1364 (HY000): Field 'id' doesn't have a default value
# 非空且唯一,主键不能为空,而且唯一,已经有值了的话再添加值会报错的
mysql> insert into t6 values(1,'jason');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
2.InnoDB存储引擎规定一张表必须有且只有一个主键
1.当表中没有主键也没有其他非空唯一的字段情况下:
InnoDB会采用一个隐藏的字段作为表的主键,隐藏意味着无法使用,基于该表的数据查询只能一行一行的查询,速度特别慢的
2.当表中没有主键但是有其他的非空且唯一的字段,那么会从从上往下的第一个字段自动升级为主键
mysql> create table t7(
-> id int,
-> age int not null unique,
-> phone bigint not null unique,
-> birth int not null unique,
-> height int not null unique
-> );
mysql> desc t7;
+--------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| age | int(11) | NO | PRI | NULL | |
| phone | bigint(20) | NO | UNI | NULL | |
| birth | int(11) | NO | UNI | NULL | |
| height | int(11) | NO | UNI | NULL | |
+--------+------------+------+-----+---------+-------+
3.创建表的时候都应该有一个ID字段,并且该字段作为主键
单列主键:
mysql> create table t8(
-> id int primary key,
-> name varchar(16),
-> age int);
Query OK, 0 rows affected (0.01 sec)
联合主键:
mysql> create table t9(
-> u_id int,
-> g_id int,
-> primary key(u_id,g_id));
Query OK, 0 rows affected (0.04 sec)
三、auto_increate自增
自增一张表只能出现一次
mysql> create table t10(
-> id int primary key auto_increment,
-> name varchar(16)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t10(name) values('jia'),('jason'),('wei');
mysql> select * from t10;
+----+-------+
| id | name |
+----+-------+
| 1 | jia |
| 2 | jason |
| 3 | wei |
+----+-------+
自增不会因为数据的删除而回退,永远自增往前,按照前一个ID的数继续往后自增,按照更大的往前自增
# 如果想要重置主键的话,想要格式化表,用到truncate 表名:删除表数据并重置主键值
mysql> truncate t10;
四、字段约束条件之外键
1.外键前戏
1.若需要创建一张员工表
id |
name |
age |
dep_name |
dep_desc |
1 |
jia |
18 |
学习部 |
检查学习 |
2 |
jason |
19 |
纪检部 |
检查学风 |
3 |
wei |
18 |
宿管部 |
检查卫生 |
4 |
xin |
22 |
学习部 |
检查学习 |
5 |
kevin |
21 |
纪检部 |
检查学风 |
上表的缺陷:
1.表的结构不清晰,不知道是员工表还是部门表
2.字段数据反复存取,浪费存储空间
3.表的扩展性极差,牵一发动全身,效率极低
2.拆表,将表拆分为员工表和部门表
添加员工部门编号字段填写部门数据的主键值,外键字段,专门用于记录表与表之间的数据关系
2.外键字段的创建
mysql> create table dep(
-> id int primary key auto_increment,
-> dep_name varchar(32),
-> dep_desc varchar(32)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> create table emp(
-> id int primary key auto_increment,
-> name varchar(32),
-> age int,
-> dep_id int,
-> foreign key(dep_id) references dep(id)
-> );
Query OK, 0 rows affected (0.02 sec)
1.创建表的时候一定要先创建被关联表
2.录入数据的时候一定先录入被关联表
3.修改数据的时候外键字段无法修改和删除
级联更新、级联删除:被关联数据一旦变动,关联的数据同步变动
on update cascade # 级联更新
on delete cascade # 级联删除
五、表之间的关系
-
关系的判断
关系总共有四种:
一对多
多对多
一对一
没有关系
2.一对多关系
员工表和部门表:
1.站员工角度
一个员工可以对应多个部门吗(不可以)
2.站在部门的角度
一个部门能否对应多名员工(可以)
员工部和部门部的关系就是一对多的关系
mysql> create table dep(
-> id int primary key auto_increment,
-> dep_name varchar(32),
-> dep_desc varchar(32)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> 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
-> );
Query OK, 0 rows affected (0.02 sec)
2.多对多关系
书籍表和作者表:
1.站书籍角度
一个书籍可以对应多个作者吗(可以)
2.站在作者的角度
一个书籍能否对应多个作者(可以)
书籍和作者的关系就是多对多的关系
mysql> create table book(
-> id int primary key auto_increment,
-> title varchar(32),
-> price float(6,2)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> create table author(
-> id int primary key auto_increment,
-> name varchar(16),
-> phone bigint
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> create table book_author(
-> id int primary key auto_increment,
-> book_id int,
-> foreign key(book_id) references book(id)
-> on update cascade
-> on delete cascade,
-> author_id int,
-> foreign key(author_id) references author(id)
-> on update cascade
-> on delete cascade
-> );
Query OK, 0 rows affected (0.01 sec)
3.一对一关系
用户表和用户详情表:
1.站用户角度
一个用户可以对应多个用户详情吗(不可以)
2.站在作者的角度
一个用户能否对应多个用户详情(不可以)
用户和用户详情的关系就是一对一的关系
mysql> create table userdetail(
-> id int primary key auto_increment,
-> phone bigint
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> 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
-> );
Query OK, 0 rows affected (0.01 sec)
作业
服务器表与应用程序表
课程表与班级表
学生表与班级表
老师表与课程表
书籍表与出版社表
服务器表与应用程序表
1.一个服务器可以服务多个程序
2.一个程序只需要一个服务器服务就好了
关系:一对多
mysql> create table the_servser(
-> id int primary key auto_increment,
-> name varchar(16)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> create table program(
-> id int primary key auto_increment,
-> name varchar(16),
-> server_id int,
-> foreign key(server_id) references the_servser(id)
-> on update cascade
-> on delete cascade
-> );
Query OK, 0 rows affected (0.02 sec)
课程表与班级表
1.一个课程对应多个班级
2.一个班级对应多个课程
多对多
mysql> create table course(
-> id int primary key auto_increment,
-> name varchar(32)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> create table class(
-> id int primary key auto_increment,
-> name varchar(32)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> create table c_course(
-> id int primary key auto_increment,
-> c_id int,
-> foreign key(c_id) references class(id)
-> on update cascade
-> on delete cascade,
-> course_id int,
-> foreign key(course_id) references course(id)
-> on update cascade
-> on delete cascade
-> );
Query OK, 0 rows affected (0.02 sec)
学生表与班级表
1.一个学生对应一个班级
2.一个班级对应多个学生
一对多
mysql> create table student(
-> id int primary key auto_increment,
-> name varchar(16)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> create table class1(
-> id int primary key auto_increment,
-> name varchar(16),
-> s_id int,
-> foreign key(s_id) references student(id)
-> on update cascade
-> on delete cascade
-> );
Query OK, 0 rows affected (0.01 sec)
老师表与课程表
1.多个老师对应多个课程
2.多个课程对应多个老师
多对多
mysql> create table teacher(
-> id int primary key auto_increment,
-> name varchar(16)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> create table course1(
-> id int primary key auto_increment,
-> name varchar(16)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> create table t_course(
-> id int primary key auto_increment,
-> c_id int,
-> foreign key(c_id) references course1(id)
-> on update cascade
-> on delete cascade
-> t_id int,
-> foreign key(t_id) references teacher(id)
-> on update cascade
-> on delete cascade
-> );
Query OK, 0 rows affected (0.02 sec)
书籍表与出版社表
1.一个书籍对应多个出版社
2.一个出版社出版多个数据
多对多
mysql> create table book1(
-> id int primary key auto_increment,
-> name varchar(32)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> create table press(
-> id int primary key auto_increment,
-> name varchar(16)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> create table b_press(
-> id int primary key auto_increment,
-> b_id int,
-> foreign key(b_id) references book1(id)
-> on update cascade
-> on delete cascade,
-> p_id int,
-> foreign key(p_id) references press(id)
-> on update cascade
-> on delete cascade
-> );
Query OK, 0 rows affected (0.05 sec)