zoukankan      html  css  js  c++  java
  • 前端学数据库之多表操作

    前面的话

      上一篇博文中介绍了子查询的相关内容,最后我们将查询结果存储到一个新的数据表中。下面我们将接着子查询的案例,详细介绍数据库中的多表操作

    准备工作

      在上一篇博文,我们将详细数据存储到tdb_goods数据表中,将详细数据中的类别信息存储到tdb_goods_cates数据表中

      接下来,我们要研究如何通过tdb_goods_cates数据表来更新tdb_goods表

    多表更新

      多表更新类似于单表更新

    UPDATE table_references SET col_name1={expr1|DEFAULT}
    [,col_name2={expr2|DEFAULT}]...
    [WHERE where_condition]

      表的参照关系如下:

    table_reference
    {[INNER | CROSS] JOIN |{LEFT|RIGHT} [OUTER] JOIN}
    table_reference
    ON conditional_expr

      从结果中看出,tdb_goods数据表中goods_cate列中的值已经更新为tdb_goods_cates数据表中对应的cate_id的值。这样一来,用数字替代字符串,极大地节省了存储空间

    两步更新

      在上面的多表更新的操作中,实际上我们经过了两个步骤,先创建了一个空表,将原数据表的查询结果写入空表,再利用写入结果的表反向更新原数据表

      如果使用CREATE SELECT语句将可以实现两步更新,在创建数据表同时将查询结果写入到数据表(合并了CREATE和INSERT...SELECT两个操作步骤),再利用写入结果的表反向更新原数据表

    CREATE TABLE [IF NOT EXISTS] tbl_name
    [(create_definition,...)]
    select_statement

      下面来处理原数据表tdb_goods中的品牌信息,首先查询tdb_goods表的"品牌",并分组

    SELECT brand_name FROM tdb_goods GROUP BY brand_name;

      将品牌信息放入新表tdb_goods_brands中

      CREATE TABLE tdb_goods_brands (
        brand_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
        brand_name VARCHAR(40) NOT NULL
      ) SELECT brand_name FROM tdb_goods GROUP BY brand_name;

      再参照品牌表,更新原商品数据表

      这里要注意的是,两张表中,同时存在brand_name这个字段。要区分它们,需要给它们起不同的别名或在字段前面加入表名

      查看商品数据表的列结构,我们发现,虽然数据被修改为了数字,但数据类型仍然是字符型

      下面修改商品数据表中goods_cate和brand_name的列名称和列类型

      这样,我们已经将一个大的数据表分为小的数据表进行存储了。现在,分别在tdb_goods_cates和tdb_goods_brands表再插入几条新的记录

    INSERT tdb_goods_cates(cate_name) VALUES('路由器'),('交换机'),('网卡');
    INSERT tdb_goods_brands(brand_name) VALUES('海尔'),('清华同方'),('神舟');

      在tdb_goods数据表也写入新的记录

     INSERT tdb_goods(goods_name,cate_id,brand_id,goods_price) VALUES(' LaserJet Pro P1606dn 黑白激光打印机','12','4','1849');

    连接

      通过上面的操作,已经把重复的数据分散到不同的数据表中进行存储了,尽可能的节省存储空间了。但是,显示时,却需要把原来的数据显示出来,这就需要使用下面要介绍的概念——连接

    语法结构

      MySQL在SELECT语句、多表更新、多表删除语句中支持连接(JOIN)操作

    table_reference
    {[INNER | CROSS] JOIN |{LEFT|RIGHT} [OUTER] JOIN}
    table_reference
    ON conditional_expr

      数据表参照(table_reference)时,数据表可以使用tbl_name AS alias_name 或tbl_name alias_name赋予别名

      table_subquery可以作为子查询使用在FROM子句中,这样的子查询必须为其赋予别名

    tbl_name[[AS] alias] | table_subquery [AS] alias

    连接类型

      连接类型主要包括内连接(INNER JOIN)、左外连接(LEFT [OUTER] JOIN)、右外连接(RIGHT [OUTER] JOIN)

      在mysql中,JOIN、CROSS JOIN 和 INNER JOIN是等价的

    连接条件

      使用ON关键字来设定连接条件,也可以使用WHERE来代替。一般地,使用ON关键字来设定连接条件,使用WHERE关键字进行结果集记录的过滤

    内连接

      内连接显示左表及右表符合连接条件的记录

      下面通过内连接来查询所有商品的详细信息,原来商品表中有24件商品,但只显示出23件,因为那一件不符合连接条件

      

      关于内连接,有以下注意:使用内连接查找的记录在连接数据表中不存在,并且在WHERE子句中尝试一下操作:column_name IS NULL 。如果 column_name 被指定为 NOT NULL,MySQL将在找到符合连接着条件的记录后停止搜索更多的行(查找冲突)

    左外连接

      左外连接指显示左表的全部记录及右表符合连接条件的记录

      下面通过左外连接来查询所有商品的详细信息,原来商品表中有24件商品,现在也显示出24件,但最后一件商品的分类为NULL,这是因为右表的这一个分类不符合条件,所以显示为NULL

    右外连接

      右外连接指显示右表的全部记录及左表符合连接条件的记录

      下面通过右外连接来查询所有商品的详细信息,原来商品表中有24件商品,现在显示出26件,多出来的是符合右表但不符合左表的记录

      关于外连接,有以下几点注意,以左外连接为例

    A LEFT JOIN B join_condition

      数据表B的结果集依赖于数据表A,数据表A的结果集根据左连接条件依赖所有数据表(B表除外)

      左外连接条件决定如何检索数据表B(在没有指定WHERE条件的情况下)

      如果数据表A的某条记录符合WHERE条件,但是在数据表B不存在符合连接条件的记录,将生成一个所有列为空的额外的B行

    多表连接

      三张表以上的连接称为多表连接,原理与两张表的连接相同

      下面通过内连接实现查询所有商品的详细信息

    无限级表

      上图中是tdb_goods_cates表的记录。但实际的分类并非这10类,而是无限分类。下面来介绍无限分类的数据表的实现

      无限级表至少需要三个列,一个是类型id,一个类型名称,一个是父级id

    CREATE TABLE tdb_goods_types(
     type_id   SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
     type_name VARCHAR(20) NOT NULL,
     parent_id SMALLINT UNSIGNED NOT NULL DEFAULT 0
    ); 

      然后,写入给定数据

    自身连接

      自身连接指同一个数据表对其自身进行连接。为作区分,需要添加别名。字表别名定义为s,父表别名定义为p

      下面来查找所有分类及其父类

      下面来查找所有分类及其子类

      下面来查找所有分类及其子类的数目

    删除重复项

      从记录中,可以看出24条记录中存在重复的项,现在要想办法把重复的项删除

      首先,先查找到重复的项

      然后,需要使用多表删除来实现删除操作

    DELETE tbl_name[.*][,tbl_name[.*]]...
    FROM table_references
    [WHERE where_condition]

    好的代码像粥一样,都是用时间熬出来的
     
     
    标签: mysql
    转载:http://www.cnblogs.com/xiaohuochai/p/6078814.html
  • 相关阅读:
    phpmyadmi 上传大文件
    wget 命令用法详解
    cuDnn的安装ubuntu16.04环境下(tensorflow正式安装之前的必备安装操作)
    ubuntu16.04 源码安装Python3.7 (可以在此基础上安装Tensorflow) (确保Tensorflow计算框架与系统的彻底隔离)
    大工软件学院 校园网登录脚本
    UML图 之 活动图 (汇总版)
    详解UML图之类图 (转)
    Java中private、protected、public和default的区别 (转)
    AI产业将更凸显个人英雄主义 周志华老师的观点是如此的有深度
    对什么样的人应该敬而远之
  • 原文地址:https://www.cnblogs.com/wang1593840378/p/6105647.html
Copyright © 2011-2022 走看看