学习python-Day40


今日学习内容

约束条件

  1. 主键

    • 单纯从约束角度上主键等价于非空唯一 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)
      
  2. 自增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)
    
  3. 外键

    • 外键前戏

      创建一张员工表
      	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.被关联表字段无法修改和删除:操作限制太强
      '''
      

      image

      image

      级联更新、级联删除
      	被关联数据一旦变动,关联的数据同步变动
      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建立代码层面的关系。
      '''
      

      image

      image

表关系

外键字段是用来记录表与表之间数据的关系,而数据的关系有四种:一对多关系、多对多关系、一对一关系、没有关系。

表数据关系的判定>>>:换位思考

  1. 一对多

    针对员工表和部门表判断数据关系
    1.先站在员工的角度
        问:一条员工数据能否对应多条部门数据
        翻:一名员工能否属于多个部门
        答:不可以
    2.再站在部门表的角度
        问:一条部门数据能否对应多条员工数据
        翻:一个部门能否拥有多个员工
        答:可以
    完成换位思考之后得出答案:一个不可以一个可以
    那么关系就是'一对多'
    	一个部门对应多个员工,一个员工只属于一个部门。
    
  2. 多对多

    以书籍表和作者表为例
    	1.先站在书籍表的角度
            问:一条书籍数据能否对应多条作者数据
            答:可以
        2.再站在作者表的角度
        	问:一条作者数据能否对应多条书籍数据
            答:可以
        两边都可以 那么表数据关系就是'多对多'
        注意:针对多对多表关系 外键字段不能建在任意一方。
        
     	需要单独开设第三张关系表,存储两表的数据关系  
    

    image

    image

  3. 一对一没有关系

    以用户表和用户详情表
    	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
        );
        
        一对一和一对多的区别在于,外键字段是唯一才符合一对一。
        
    

    image

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/280929.html

(0)
上一篇 2022年8月16日
下一篇 2022年8月16日

相关推荐

发表回复

登录后才能评论