今日学习内容
约束条件
-
主键
-
单纯从约束角度上主键等价于非空唯一
not null 、unique
create table t1( id int primary key, name varchar(32) ); mysql> desc t1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.02 sec) 作用:主键可加快数据查询
-
InnoDB
存储引擎(规定一张表必须有且只有一个主键
)1.如果创建的表没有主键或者非空唯一的字段,则InnoDB存储引擎会自动采用一个隐藏的字段作为主键。 2.如果创建的表中没有主键但是有非空且唯一的字段,则InnoDB存储引擎会自动设置成主键。 create table t2( nid int not null unique, sid int not null unique, uid int not null unique, name varchar(32) ); mysql> desc t2; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | nid | int(11) | NO | PRI | NULL | | | sid | int(11) | NO | UNI | NULL | | | uid | int(11) | NO | UNI | NULL | | | name | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 4 rows in set (0.01 sec)
-
创建表的时候有一个
id
字段,并且该字段是主键
。uid、sid、pid、gid、cid、id 补充说明: 单列主键:id int primary key 联合主键: sid int, nid int, primary key(sid, nid) 联合主键 mysql> desc t3; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | sid | int(11) | NO | PRI | 0 | | | nid | int(11) | NO | PRI | 0 | | | name | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 3 rows in set (0.01 sec)
-
-
自增
auto_increment
该约束条件不能单独使用,必须跟在键后面(主要配合主键一起使用) create table t4( id int auto_increment ); 报错提示:there can be only one auto column and it must be defined as a key create table t4( id int primary key auto_increment, name varchar(32) ); mysql> desc t4; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set (0.01 sec) mysql> insert into t4(name) values('肖战'),('王一博'),('晨哥'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from t4; +----+-----------+ | id | name | +----+-----------+ | 1 | 肖战 | | 2 | 王一博 | | 3 | 晨哥 | +----+-----------+ 3 rows in set (0.00 sec) ----------------------------------------------------------------------------------------- 自增特点: 1.'不会因为执行删除数据的操作而回退或者重置' mysql> insert into t4(name) values ('晨哥yyds'); Query OK, 1 row affected (0.00 sec) mysql> select * from t4; +----+------------+ | id | name | +----+------------+ | 1 | 肖战 | | 2 | 王一博 | | 3 | 晨哥 | | 4 | 晨哥yyds | +----+------------+ 4 rows in set (0.00 sec) mysql> delete from t4 where id = 3; Query OK, 1 row affected (0.01 sec) mysql> select * from t4; +----+------------+ | id | name | +----+------------+ | 1 | 肖战 | | 2 | 王一博 | | 4 | 晨哥yyds | +----+------------+ 3 rows in set (0.00 sec) 2.'如果想要重置主键,要么删表重建,要么格式化表' truncate 表名; #删除表数据并且重置主键值。 mysql> desc t3; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | sid | int(11) | NO | PRI | 0 | | | nid | int(11) | NO | PRI | 0 | | | name | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 3 rows in set (0.01 sec) mysql> select * from t3; +-----+-----+-----------+ | sid | nid | name | +-----+-----+-----------+ | 1 | 1 | 肖战 | | 2 | 2 | 王一博 | +-----+-----+-----------+ 2 rows in set (0.00 sec) mysql> truncate t3; Query OK, 0 rows affected (0.02 sec) mysql> select * from t3; Empty set (0.00 sec)
-
外键
-
外键前戏
创建一张员工表 id name gender dep_name dep_desc 上述表的缺陷 1.表结构不清晰(无法辨别到底是员工表还是部门表) 2.字段数据反复存取(浪费存储空间) 3.表的扩展性极差(修改一块内容不行需修改一整块内容,执行效率低) 优化操作>>>:'把一张表拆成两张表' 员工表---部门表 id name gender id dep_name dep_desc 拆表之后解决上述问题,但是出现一个很重要的问题:两张表没有任何联系 解决措施>>>:'添加外键字段' 前提下,需要添加一个部门编号字段并且该字段是主键。 id name gender dep_id '外键字段作用:专门记录表与表之间数据关系'
-
外键
1.先写普通字段 2.然后写有外键的字段 create table emp( id int primary key auto_increment, name varchar(32), gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep(id) ); create table dep( id int primary key auto_increment, dep_name varchar(32), dep_desc varchar(32) ); mysql> insert into dep(dep_name, dep_desc) values('演员','表演系'),('街舞','舞蹈系'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from dep; +----+----------+-----------+ | id | dep_name | dep_desc | +----+----------+-----------+ | 1 | 演员 | 表演系 | | 2 | 街舞 | 舞蹈系 | +----+----------+-----------+ 2 rows in set (0.00 sec) mysql> insert into emp(name, gender, dep_id) values('xz','male',1),('wyb','male',2); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from emp; +----+------+--------+--------+ | id | name | gender | dep_id | +----+------+--------+--------+ | 1 | xz | male | 1 | | 2 | wyb | male | 2 | +----+------+--------+--------+ 2 rows in set (0.00 sec) ''' 1.创建表的时候呀先创建被关联的表(没有外键的表),然后再是关联表(有外键的表) 2.插入数据的时候,要先插入被关联表的数据,然后在插入关联表的时候要插入被关联表拥有的数据。 3.被关联表字段无法修改和删除:操作限制太强 '''
级联更新、级联删除 被关联数据一旦变动,关联的数据同步变动 create table emp1( id int primary key auto_increment, name varchar(32), gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep1(id) on update cascade # 级联更新 on delete cascade # 级联删除 ); create table dep1( id int primary key auto_increment, dep_name varchar(32), dep_desc varchar(32) ); ''' 扩展: 在实际工作,很多时候可能并不会使用外键。因为外键增加了表之间的耦合度,不便于单独操作,资源消耗增加。 我们为了能够描述表数据的关系,又不想使用外键,通过写sql建立代码层面的关系。 '''
-
表关系
外键字段是用来记录表与表之间数据的关系,而数据的关系有四种:一对多关系、多对多关系、一对一关系、没有关系。
表数据关系的判定>>>:换位思考
-
一对多
针对员工表和部门表判断数据关系 1.先站在员工的角度 问:一条员工数据能否对应多条部门数据 翻:一名员工能否属于多个部门 答:不可以 2.再站在部门表的角度 问:一条部门数据能否对应多条员工数据 翻:一个部门能否拥有多个员工 答:可以 完成换位思考之后得出答案:一个不可以一个可以 那么关系就是'一对多' 一个部门对应多个员工,一个员工只属于一个部门。
-
多对多
以书籍表和作者表为例 1.先站在书籍表的角度 问:一条书籍数据能否对应多条作者数据 答:可以 2.再站在作者表的角度 问:一条作者数据能否对应多条书籍数据 答:可以 两边都可以 那么表数据关系就是'多对多' 注意:针对多对多表关系 外键字段不能建在任意一方。 需要单独开设第三张关系表,存储两表的数据关系
-
一对一 、没有关系
以用户表和用户详情表 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 ); 一对一和一对多的区别在于,外键字段是唯一才符合一对一。