zoukankan      html  css  js  c++  java
  • 疫情环境下的网络学习笔记 python 5.5 MYSql 表关系,外键

    5.5

    昨日回顾

    • 存储引擎

      show engines

    • 创建表的完整语法

      create table t1(
      	name char(4) not null,
      	id int
      )
      
    • 严格模式:使用数据库的时候尽量让数据库少干活

    • 基本数据类型

      • 整型:tinyint,int,bigint,默认都有符号

      • 浮点型:float,double,decimal

        精确度 float < double < decimal

      • 字符类型

        char定长,varchar变长

      • 日期

      • 枚举与集合

    今日内容

    重要

    1. 约束条件
    2. 表与表之间建立关系(约束)
    3. 修改表的语法
    4. 复制表
    5. 作业:如何判断表关系及建立表关系

    约束条件

    default 默认值

    # 插入数据的时候指定字段
    create table t1(id int, name char(8));
    insert into t1(name,id) values('aaa',2020);
    
    # 创建表的时候给字段设置默认值
    create table t2(id int, name char(8), gender enum('male','female') default 'male');
    # 字段类型后面不加逗号,跟默认值
    
    insert into t2(id,name) values(2021,'bbb');
    # 这样,默认的gender就是male
    

    unique 唯一

    # 单列唯一
    create table t3(id int unique, name char(8));
    
    insert into t3 values(1, 'aaa'),(1, 'bbb');
    # 报错,显示 id 字段唯一
    insert into t3 values(1, 'ccc'),(2, 'ddd');
    # 正常添加
    
    # 联合唯一
    # 例,ip和端口,单个可以重复,但是加载到以前必须是唯一的
    create table t4(
    	id int,
    	ip char(16),
    	port int,
    	unique(ip,port)
    );
    # 在最后,用unique加括号,把联合唯一的字段放进去
    
    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);
    # 报错,ip和端口都与 1 重复
    

    primary key 主键

    重要

    单从约束效果来看,等价于 not null + unique

    # 创建表,id为主键
    create table t3(id int primary key);
    insert into t5 values(1),(1);
    insert into t5 values(null);
    # 报错
    insert into t5 values(1),(2);
    # 正常创建
    

    除了有约束效果以外,他还是innodb存储引擎组织数据的依据,innodb创建表的时候必须要有primary key

    类似于书的目录,能够帮助提示查询效率,并且是建表的依据

    那之前没有用主键是怎么建表的呢?

    1. 一张表有且只有一个主键,如果没有设置主键,那么回从上往下搜索直到遇到一个非空且唯一的字段,自动将其升级为主键
    2. 如果表中没有主键也没有其他任何的非空且唯一字段,那么innodb会采用自己内部提供的一个隐藏字段作为主键。这个隐藏的字段我们无法使用
    3. 通常一张表应该有一个主键字段,通常叫做id

    联合主键:了解

    create table t6(
    	ip char(16),
    	port int,
    	primary key(ip,port)
    );
    

    以后创建表,都必须给id加上主键

    auto_increment 自增

    当编号特别多的时候,设置每次新增数据,id自动+1

    create table t8(
    	id int rimary key auto_increment,
    	name char(16)
    );
    # 创建表,id自增
    
    insert into1 t8(name) vlues('aaa'),('bbb'),('ccc');
    # 插入后查看,既有name,又有id
    # auto_increment 通常都是加在主键上的,编号序号一类,不能给普通字段加
    

    这个约束条件内部有一个计数器,就算delete from 把数据删掉了,主键的自增序号也不会删除,而是会从当前计数再往下自增

    delete from t8; # 删除表中数据,没有删除自增序号
    truncate t8; # 清空表数据,并重置自增计数
    

    表与表间建立关系

    对普通的表进行拆分,将拆分的表建立联系

    表与表之间的关系

    # 表与表之间最多只有4种关系
    # 1. 一对多关系
    # 2. 多对多关系
    # 3. 一对一关系
    
    # 在确定表关系的时候要换位思考:在两边的表考虑是对应一个或多个
    # 一个部门有多个员工,一个员工只属于一个部门:单向的一对多关系
    

    外键:用来帮助我们建立表与表之间关系的字段:foreign key

    一对多关系

    foreign key
    
    # 建部门表
    create table dep(
    	id int promary key auto_increment,
    	dep_name char(16)
    );
    
    # 建员工表
    create table emp(
    	id int promary key auto_increment,
    	emp_name char(16),
    	gender enum('male','female') default 'male'
    	dep_id int,
        foreign key(dep_id) references dep(id)
        # 本表的dep_id字段是外键字段,与dep表的id有联系
    );
    
    # 先插入部门数据
    insert into dep(dep_name) values('外交部'),('技术部');
    # 插入员工数据
    insert into emp(emp_name, dep_id) values('aaa',1),('bbb',2);
    

    foreign key 规范

    1. 一对多关系表,外键字段建在 的一边
    2. 在创建表的时候要先建被关联表
    3. 在录入数据的时候必须先录入被关联表
    4. 当约束存在,想要修改被关联的表,不能直接操作,要想实现同步删除或更新,另外声明

    修改被关联表

    on update cascade

    # 1. 先修改关联的数据,再修改被关联的数据:操作太频繁,不用
    # 2. 真正做到表间有关系:更新就同部更新,删除就同部删除
    # 级联更新,级联删除(同部):在创建表的时候需要声明额外的参数
    create table emp(
    	id int promary key auto_increment,
    	emp_name char(16),
    	gender enum('male','female') default 'male'
    	dep_id int,
    	foreign key(dep_id) references dep(id)
    	on update cascade # 同部更新
    	on delete cascade # 同步删除
    );
    
    # 修改dep表,id变成200
    update dep set id=200 where id=2;
    select* from dep
    select* from emp
    # 此时查看emp表,关联了id=2的数据id也变成200了。如果删除id=200,那么员工表关联id=200的也被删除
    

    多对多关系

    例:书籍与作者,一本书有多个作者,一个作者不止写一本书,多对多关系

    # 创建书籍表
    create table book(
    	id int promary key auto_increment,
    	title varcahr(32),
    	price int
    );
    
    # 创建作者表
    create table author(
    	id int promary key auto_increment,
    	name varchar(32),
    	book_id int,
    )
    # 创建关系连接表
    create table book2author(
    	id int promary key auto_increment,
    	author_id int,
    	book_id int,
    	foreign key(author_id) references author(id)
    	on update cascade
    	on delete cascade,
    	# 作者id
    	foreign key(book_id) references book(id)
    	on update cascade
    	on delete cascade
        # 书本id
    )
    
    # 按照一对多的思想建表,谁都别想建成,对于这种场景,应该另外建一张表 book2author,专门存储表之间的关系
    # 作者与关系表表和书与关系表book2author都是一对多的关系
    #
    
    

    一对一关系

    用户独有的属性:昵称,年龄,email;一个用户只能对应一个昵称,一个年龄,同一昵称只对用一个用户:一对一关系

    一对一关系外键,建在哪里都可以不过推荐建在查询频率比较高的表中

    create table authordetail(
    	id int primary key auto_increment,
        phone int,
        addr 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 authordetail(id) 
        on update cascade  # 同步更新
        on delete cascade  # 同步删除
    )
    

    总结

    • 表关系的建立要用到 foreign key
      • 一对多:外键字段建在多的一方
      • 多对多:开设另外一张关系表
      • 一对一:建立在任意以访,推荐建在查询频率高的表中
    • 判断表之间关系的方式:换位思考

    修改表

    MYSQL不区分大小写

    # 1. 修改表名
    alter table 表名 rename 新表名;
    
    # 2. 增加字段
    alter table 表明 add 字段名 字段类型(宽度) 约束条件; # 默认在最后面添加
    alter table 表明 add 字段名 字段类型(宽度) 约束条件 first; # 添加到最前面
    alter table 表明 add 字段名 字段类型(宽度) 约束条件 last; # 添加在最后面;
    
    # 3. 删除字段
    alter table 表名 drop 字段名;
    
    # 4. 修改字段属性
    alter table 表名 modify 字段名 字段类型(宽度) 约束条件;
    
    # 修改字段名
    alter table 表名 change 旧字段名 新字段名 字段类型(宽度) 约束条件;
    

    复制表

    MYSQL每次查询得到的结果也是一张表:内存中的一张虚拟表

    # 1.
    create table new_table select * from t1;
    # create table 新表名 select * from 旧表名;
    # 这样只能复制了表的结构和数据,但是不能复制主键外键索引一类属性
    # 如果复制的约束条件结果中没有数据,得到一个没有数据的空表
    
  • 相关阅读:
    网页性能分析
    vue学习图解
    px-em-rem单位转换
    呼啦圈(keyframes和transform结合)
    菜单栏鼠标经过伸缩效果
    携程transform放大效果
    浮动布局demo
    倒圆角艺术
    伪类分类
    ingress-nginx 添加https证书
  • 原文地址:https://www.cnblogs.com/telecasterfanclub/p/12830240.html
Copyright © 2011-2022 走看看