04、Mysql多表

124 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情

04、Mysql多表

01.多表_建表的原则:

    需求:创建一个表可以存储学员信息:学员编号,姓名,性别,年龄,科目

    1).原则:

        1.保证表中的一列,只记录一件事情。如果记录了多件事情,建议分成多列。

        2.为每个表创建一个主键。

        3.要保证每个表只记录一件事情,如果记录多件事情,要分成多表存储。中间可以使用"引用"来引用另一个表的数据。

    2).两个概念:

        1.主表:被其它表引用的表;

        2.从表:引用主表的表;

02.多表_表和表之间的关系:

    1).一对多【最常用,比例较多】:

        1.常见实例:客户和订单,分类和商品,部门和员工

                客户(主) --> 订单(从)(外键字段)

                分类(主) --> 商品(从)(外键字段)--》注意:本例描述的是:一个商品只属于一个类别

                部门(主) --> 员工(从)(外键字段)

        2.一对多建表原则:在从表(多方)创建一个字段(外键字段),此字段作为外键指向主表(一方)的主键

        3.关于外键的说明:

            1).外键字段的名称可以和主键的主键名称不同;

            2).外键字段的数据类型要跟主键的数据类型相同或者比主键类型更宽。

    2).多对多【较常用,比例较少】:

        1.常见实例:学生和课程

                学生 --> 课程   --》注意:本例描述:一个学生可以选择多门课程

        2.多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键。

    3).一对一【基本不用】:不建议使用:

      家庭成员表                    银行卡表
        id    姓名    性别    年龄    卡ID        id    卡号        银行名称    开户日期
        1    汪峰    男    25    1    --->    1    6212262666666    招商银行    2017-01-01
        2    章子怡    女    22    2    --->    2    2412382777777    建设银行    2017-02-01

        上述表格就没有必要分开了,银行卡表的记录只被家庭成员表中的一条记录引用,不会被多条记录引用,这就是一对一的关系,

        这种关系,建议合成一张表

        家庭成员表

        家庭成员表
        id    姓名    性别    年龄    卡号    银行名称    开户日期
        1    汪峰    男    25    .....
        2    章子怡    女    22    .....
  • 声明外键约束        

语法:alter table 从表 add [constraint] [外键名称] foreign key (从表外键字段名) references 主表 (主表的主键);

[外键名称] 用于删除外键约束的,一般建议“_fk”结尾

    alter table 从表 drop foreign key 外键名称

  • 使用外键目的:

保证数据完整性

               //多对多时,一般建立一个中间表,中间表一般用两个字段做联合主键,这两个字段又都是外键,是为了保证数据不重复

03.多表_外键约束:

    1).什么是外键约束:可以在"从表"的"外键字段"上创建一个"外键约束"

    2).外键约束的作用:强制要求"外键"字段的值必须参考"主表"中"主键"字段的值,如果外键中出现了主键中没有的值,

                       数据库会立即抛异常,它可以保证我们数据的完整性和一致性。

    3).其它说明:外键字段允许:NULL值

             外键的值可以重复,可以为NULL,但必须参考主表的主键的值。

    4).创建语句:

        格式:alter table 从表 add constraint 外键名称 foreign key (从表外键字段名) references 主表 (主表的主键);

        例如:   ALTER TABLE emp ADD CONSTRAINT fk_emp FOREIGN KEY (deptId) REFERENCES dept (did);

    5).可以使用SQLYog中的"架构设计器"来设置两个表的关系。

            注意:从"从表"向"主表"中拖拽。

04.多表实战_一对多:

    1).分类和商品(前提:一个商品只属于一个类别)

05.多表查询:

    1).交叉查询:(错误的结果,显示的两个表的记录的乘积,也叫:笛卡尔积)

    `select * from product,category;`

    2).内连接查询【最常用】:(显示两个表的等值记录)    //  两个表位置可以互换,如果是* 的话  先显示前表字段     //显示 隐式 都是交叉查询之后筛选

        1).隐式内连接【常用】:    from 俩表 where 俩表的等值关系

            格式:  select 字段列表    from 从表,主表   where 从表.外键字段 = 主表.主键字段:     //如果再有条件 + and  条件

            例如:select * from product,category where product.cid = category.cid;

        2).显示内连接: inner join ... on 等值关系                         ////如果再有条件 + where  条件

            格式:    select 字段列表  from 从表 INNER JOIN 主表 ON 从表.外键字段 = 主表.主键字段

            例如: select * from product inner join category on product.cid = category.cid;

        3).关于"表别名"

            例如: select * from product p,category c where p.cid = c.cid;

                select * from product p inner join category c on p.cid = c.cid;

        4).关于隐式和显示连接的其它写法:

            1).隐式内连接:select ... from 从表 , 主表 on 从表.外键字段 = 主表.主键字段;//错误

            2).显示内连接:select ... from 从表 inner join 主表 where 从表.外键字段 = 主表.主键字段;//OK的,但不建议

    3).外连接查询【较常用】:

        1).左外连接:能查询出"左表"的所有记录,包括跟右表等值的和不等值的。     // 左右连接位置可以互换,谁在左边 左连接差的就是谁

            格式:select 字段列表 from 从表 left join 主表 on 从表.外键字段 = 主表.主键字段;

            需求:查询出所有商品,有类别的显示类别名称,没有类别的显示NULL

                select * from product p left join category c on p.cid = c.cid;

        2).右外连接:能查询出"右表"的所有记录,包括跟左表等值的和不等值的。

            格式:select 字段列表 from 从表 right join 主表 on 从表.外键字段 = 主表.主键字段;

            需求:查询出所有的"商品类别",有商品的类别要同时显示商品,没有的显示NULL

                select * from product p right join category c on p.cid = c.cid;

06.子查询:

    1).什么是子查询:一个查询的查询条件,需要从另一个查询来获取,这样就要嵌套两个查询语句。作为其他查询的条件的查询就是:子查询;

               //  子查询可以作为一个结果,也可以作为一个临时表

    2).例如:查询出价格比"海澜之家"更高的商品信息:

            select * from product where price > (select price from product where pname = '海澜之家');

    3).例如:查询"化妆品"分类商品详情

        1).select * from product where cid = (select cid from category where cname = '化妆品')---属于:单表查询            //子查询的结果作为另个表

        2).select * from product p , (select * from category where cname = '化妆品') c where p.cid = c.cid;

    4).例如:查询"化妆品"和"家电"两个商品详情

        1).select * from product p , (select * from category where cname in ('化妆品','家电')) c where p.cid = c.cid;

07.三表联查:      //按照这个格式 可以多表联查

    1).内连接查询:

        1).隐式内连接:

            select * from 表1 , 表2 , 表3 where 表1 和 表2的等值关系 and 表2和表3的等值关系;

        2).显示内连接:

            select * from 表1 inner join 表2 on 表1和表2的等值关系 inner join 表3 on (表1和表2的连接结果) 和表3的等值关系;

    2).外连接查询:

        select * from 表1 left/right join 表2 on 表1和表2的等值关系 left/right join 表3 on (表1和表2的连接结果)和表3的等值关系;

注意: foreign key (dept_id) references dept(id)

MySQL 里 1  ‘1’  代表 true   0   ‘0’  代表false