mysql高级部分(java)

1.约束

1.1 概念

  • 约束是作用于表中列上的规则,用于限制加入表的数据

    例如:我们可以给id列加约束,让其值不能重复,不能为null值。

  • 约束的存在保证了数据库中数据的正确性、有效性和完整性

    添加约束可以在添加数据的时候就限制不正确的数据,年龄是3000,数学成绩是-5分这样无效的数据,继而保障数据的完整性。

1.2 分类

  • 非空约束: 关键字是 NOT NULL

    保证列中所有的数据不能有null值。

    例如:id列在添加 马花疼 这条数据时就不能添加成功。

  • 唯一约束:关键字是 UNIQUE

    保证列中所有数据各不相同。

    例如:id列中三条数据的值都是1,这样的数据在添加时是绝对不允许的。

  • 主键约束: 关键字是 PRIMARY KEY

    主键是一行数据的唯一标识,要求非空且唯一。一般我们都会给没张表添加一个主键列用来唯一标识数据。

    例如:上图表中id就可以作为主键,来标识每条数据。那么这样就要求数据中id的值不能重复,不能为null值。

  • 检查约束: 关键字是 CHECK

    保证列中的值满足某一条件。

    例如:我们可以给age列添加一个范围,最低年龄可以设置为1,最大年龄就可以设置为300,这样的数据才更合理些。

    注意:MySQL不支持检查约束。

    这样是不是就没办法保证年龄在指定的范围内了?从数据库层面不能保证,以后可以在java代码中进行限制,一样也可以实现要求。

  • 默认约束: 关键字是 DEFAULT

    保存数据时,未指定值则采用默认值。

    例如:我们在给english列添加该约束,指定默认值是0,这样在添加数据时没有指定具体值时就会采用默认给定的0。

  • 外键约束: 关键字是 FOREIGN KEY

    外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性。

    外键约束现在可能还不太好理解,后面我们会重点进行讲解。

    22班还没有,学生 班级

  • 非空

  • 唯一

  • 主键

  • 检查(mysql没有)

  • 默认

  • 外键

1.3 非空约束

  • 概念

    非空约束用于保证列中所有数据不能有NULL值

  • 语法

  • 添加约束

  • -- 创建表时添加非空约束
    CREATE TABLE 表名(
       列名 数据类型 NOT NULL,
       …
    ); 
    -- 建完表后添加非空约束
    ALTER TABLE 表名 MODIFY 字段名 数据类型 NOT NULL;

    删除约束

  • ALTER TABLE 表名 MODIFY 字段名 数据类型;

    1.4 唯一约束

  • 概念

    唯一约束用于保证列中所有数据各不相同

  • 语法

    • 添加约束

      -- 创建表时添加唯一约束
      CREATE TABLE 表名(
         列名 数据类型 UNIQUE [AUTO_INCREMENT],
         -- AUTO_INCREMENT: 当不指定值时自动增长
         …
      ); 
      CREATE TABLE 表名(
         列名 数据类型,
         …
         [CONSTRAINT] [约束名称] UNIQUE(列名)
      ); 
      -- 建完表后添加唯一约束
      ALTER TABLE 表名 MODIFY 字段名 数据类型 UNIQUE;

      删除约束

    • ALTER TABLE 表名 DROP INDEX 字段名;

      1.5 主键约束

    • 概念

      主键是一行数据的唯一标识,要求非空且唯一

      一张表只能有一个主键

    • 语法

      • 添加约束

        -- 创建表时添加主键约束
        CREATE TABLE 表名(
           列名 数据类型 PRIMARY KEY [AUTO_INCREMENT],
           …
        ); 
        CREATE TABLE 表名(
           列名 数据类型,
           [CONSTRAINT] [约束名称] PRIMARY KEY(列名)
        ); 
        ​
        -- 建完表后添加主键约束
        ALTER TABLE 表名 ADD PRIMARY KEY(字段名);
      • 删除约束

        ALTER TABLE 表名 DROP PRIMARY KEY;
    • 1.6 默认约束

    • 概念

      保存数据时,未指定值则采用默认值

    • 语法

      • 添加约束

        -- 创建表时添加默认约束
        CREATE TABLE 表名(
           列名 数据类型 DEFAULT 默认值,
           …
        ); 
        -- 建完表后添加默认约束
        ALTER TABLE 表名 ALTER 列名 SET DEFAULT 默认值;
      • 删除约束

        ALTER TABLE 表名 ALTER 列名 DROP DEFAULT;
    • 1.7 约束练习

      根据需求,为表添加合适的约束

      -- 员工表
      CREATE TABLE emp (
          id INT,  -- 员工id,主键且自增长
          ename VARCHAR(50), -- 员工姓名,非空且唯一
          joindate DATE,  -- 入职日期,非空
          salary DOUBLE(7,2),  -- 工资,非空
          bonus DOUBLE(7,2)  -- 奖金,如果没有将近默认为0
      );

      上面一定给出了具体的要求,我们可以根据要求创建这张表,并为每一列添加对应的约束。建表语句如下:

      DROP TABLE IF EXISTS emp;
      ​
      -- 员工表
      CREATE TABLE emp (
        id INT PRIMARY KEY, -- 员工id,主键且自增长
        ename VARCHAR(50) NOT NULL UNIQUE, -- 员工姓名,非空并且唯一
        joindate DATE NOT NULL , -- 入职日期,非空
        salary DOUBLE(7,2) NOT NULL , -- 工资,非空
        bonus DOUBLE(7,2) DEFAULT 0 -- 奖金,如果没有奖金默认为0
      );

      通过上面语句可以创建带有约束的 emp 表,约束能不能发挥作用呢。接下来我们一一进行验证,先添加一条没有问题的数据

      INSERT INTO emp(id,ename,joindate,salary,bonus) values(1,'张三','1999-11-11',8800,5000);
    • 验证主键约束,非空且唯一

    • INSERT INTO emp(id,ename,joindate,salary,bonus) values(null,'张三','1999-11-11',8800,5000);

      执行结果如下:

      从上面的结果可以看到,字段 id 不能为null。那我们重新添加一条数据,如下:

      INSERT INTO emp(id,ename,joindate,salary,bonus) values(1,'张三','1999-11-11',8800,5000);

      执行结果如下:

      从上面结果可以看到,1这个值重复了。所以主键约束是用来限制数据非空且唯一的。那我们再添加一条符合要求的数据

      INSERT INTO emp(id,ename,joindate,salary,bonus) values(2,'李四','1999-11-11',8800,5000);

      执行结果如下:

    • 验证非空约束

    • INSERT INTO emp(id,ename,joindate,salary,bonus) values(3,null,'1999-11-11',8800,5000);

      执行结果如下:

      从上面结果可以看到,ename 字段的非空约束生效了。

    • 验证唯一约束

    • INSERT INTO emp(id,ename,joindate,salary,bonus) values(3,'李四','1999-11-11',8800,5000);

      执行结果如下:

      从上面结果可以看到,ename 字段的唯一约束生效了。

    • 验证默认约束

    • INSERT INTO emp(id,ename,joindate,salary) values(3,'王五','1999-11-11',8800);

      执行完上面语句后查询表中数据,如下图可以看到王五这条数据的bonus列就有了默认值0。

      注意:默认约束只有在不给值时才会采用默认值。如果给了null,那值就是null值。

      如下:

      INSERT INTO emp(id,ename,joindate,salary,bonus) values(4,'赵六','1999-11-11',8800,null);

      执行完上面语句后查询表中数据,如下图可以看到赵六这条数据的bonus列的值是null。

    • 验证自动增长: auto_increment 当列是数字类型 并且唯一约束

    • 重新创建 emp 表,并给id列添加自动增长

      -- 员工表
      CREATE TABLE emp (
        id INT PRIMARY KEY auto_increment, -- 员工id,主键且自增长
        ename VARCHAR(50) NOT NULL UNIQUE, -- 员工姓名,非空并且唯一
        joindate DATE NOT NULL , -- 入职日期,非空
        salary DOUBLE(7,2) NOT NULL , -- 工资,非空
        bonus DOUBLE(7,2) DEFAULT 0 -- 奖金,如果没有奖金默认为0
      );

      接下来给emp添加数据,分别验证不给id列添加值以及给id列添加null值,id列的值会不会自动增长:

      INSERT INTO emp(ename,joindate,salary,bonus) values('赵六','1999-11-11',8800,null);
      INSERT INTO emp(id,ename,joindate,salary,bonus) values(null,'赵六2','1999-11-11',8800,null);
      INSERT INTO emp(id,ename,joindate,salary,bonus) values(null,'赵六3','1999-11-11',8800,null);

      tips:

    • 建表时添加约束

    • 图形化修改约束

    • 1.8 外键约束

      问题导入:

      删除部门的时候需不要要考虑部门是否有员工?

      字段加在哪个表?

      1.8.1 概述

      外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性。

      如何理解上面的概念呢?如下图有两张表,员工表和部门表:

      员工表中的dep_id字段是部门表的id字段关联,也就是说1号学生张三属于1号部门研发部的员工。现在我要删除1号部门,就会出现错误的数据(员工表中属于1号部门的数据)。而我们上面说的两张表的关系只是我们认为它们有关系,此时需要通过外键让这两张表产生数据库层面的关系,这样你要删除部门表中的1号部门的数据将无法删除。

      1.8.2 语法

      外键是在子表中 不是父表中的。

    • 添加外键约束

    • -- 创建表时添加外键约束
      CREATE TABLE 表名(
         列名 数据类型,
         …
         [CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名) 
      ); 
      -- 建完表后添加外键约束
      ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
    • 删除外键约束

    • ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

      解决方案 先操作子表中的关联内容 再操作主表中的关联内容

      1.8.3 练习

      根据上述语法创建员工表和部门表,并添加上外键约束:

      -- 删除表
      DROP TABLE IF EXISTS emp;
      DROP TABLE IF EXISTS dept;
      ​
      -- 部门表
      CREATE TABLE dept(
          id int primary key auto_increment,
          dep_name varchar(20),
          addr varchar(20)
      );
      -- 员工表 
      CREATE TABLE emp(
          id int primary key auto_increment,
          name varchar(20),
          age int,
          dep_id int,
      ​
          -- 添加外键 dep_id,关联 dept 表的id主键
          CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES dept(id)
      );

      添加数据

      -- 添加 2 个部门
      insert into dept(dep_name,addr) values
      ('研发部','广州'),('销售部', '深圳');
      ​
      -- 添加员工,dep_id 表示员工所在的部门
      INSERT INTO emp (NAME, age, dep_id) VALUES 
      ('张三', 20, 1),
      ('李四', 20, 1),
      ('王五', 20, 1),
      ('赵六', 20, 2),
      ('孙七', 22, 2),
      ('周八', 18, 2);

      此时删除 研发部 这条数据,会发现无法删除。

      -- 删除外键
      alter table emp drop FOREIGN key fk_emp_dept;
      --重新添加外键
      alter table emp add CONSTRAINT fk_emp_dept FOREIGN key(dep_id) REFERENCES dept(id);

      小结:

    • 非空约束not null

    • 唯一约束nuique 唯一索引

    • 主键约束 primary key 主键索引

    • 默认约束 default

    • 外键约束 foreign key

    • 主表 (被动) --- 从表(有关联列)

    • 添加外键,---从表

    • CONSTRAINT fk_emp_dept FOREIGN key(dep_id) REFERENCES dept(id);

    • 2,数据库设计

    • 规范

    • 流程

    • 表关系

    • 2.0 数据库设计简介

    • 数据库设计概念

      • 数据库设计就是根据业务系统的具体需求,结合我们所选用的DBMS,为这个业务系统构造出最优的数据存储模型。

      • 建立数据库中的表结构以及表与表之间的关联关系的过程。

      • 有哪些表?表里有哪些字段?表和表之间有什么关系?

    • 数据库设计的步骤

      • 需求分析(数据是什么? 数据具有哪些属性? 数据与属性的特点是什么)

      • 逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑我们所选用的数据库管理系统)

      • 物理设计(根据数据库自身的特点把逻辑设计转换为物理设计)

      • 维护设计(1.对新的需求进行建表;2.表优化)

    • 2.1 多表介绍

      多表概念

      说白了就是多张数据表,而表与表之间是可以有一定的关联关系,这种关联关系通过外键约束实现。

      多表的分类

    • 一对一

    • 一对多

    • 多对多

    • 多表设计范式

      三范式

      2.2 表关系(一对一)

    • 一对一

    • 适用场景

    • 用户表-------------用户详情表。

      手机号登录表------qq号登录表。

      商品表-------------商品详情表。

      人和身份证。一个人只有一个身份证,一个身份证只能对应一个人。

      员工表,员工领导表(自关联)

         一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能
    • 实现方式

      在任意一方加入外键,关联另一方主键,并且设置外键为唯一(UNIQUE)

    • 案例

      我们以 用户表 举例:

      而在真正使用过程中发现 id、photo、nickname、age、gender 字段比较常用,此时就可以将这张表查分成两张表。

    • 用户登录表(username,password)--- qq登录表(id,name)---微信登录表(id,name)

      -----用户详情表(id,name,age,sex,address,header....)

      建表语句如下:

      create table tb_user_desc (
          id int primary key auto_increment,
          city varchar(20),
          edu varchar(10),
          income int,
          status char(2),
          des varchar(100)
      );
      ​
      create table tb_user (
          id int primary key auto_increment,
          photo varchar(100),
          nickname varchar(50),
          age int,
          gender char(1),
          desc_id int unique,
          -- 添加外键
          CONSTRAINT fk_user_desc FOREIGN KEY(desc_id) REFERENCES tb_user_desc(id)    
      );
      

      特殊的一对一

      自关联:

      2.3 表关系(一对多)

    • 一对多

      适用场景

      • 部门和员工

      • 商品分类和商品 一个分类下可以有多个商品。

      • 超市表和类品表

      • 用户和订单。一个用户可以有多个订单。

      • 订单和商品。

    • 实现方式

      在多的一方建立外键,指向一的一方的主键

    • 案例

      我们还是以 员工表部门表 举例:

      经过分析发现,员工表属于多的一方,而部门表属于一的一方,此时我们会在员工表中添加一列(dep_id),指向于部门表的主键(id):

      建表语句如下:

      -- 删除表
      DROP TABLE IF EXISTS tb_emp;
      DROP TABLE IF EXISTS tb_dept;
      ​
      -- 部门表
      CREATE TABLE tb_dept(
          id int primary key auto_increment,
          dep_name varchar(20),
          addr varchar(20)
      );
      -- 员工表 
      CREATE TABLE tb_emp(
          id int primary key auto_increment,
          name varchar(20),
          age int,
          dep_id int,
      ​
          -- 添加外键 dep_id,关联 dept 表的id主键
          CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES tb_dept(id)   
      );
      -- alter table tb_emp add CONSTRAINT fk_emp_dept1 FOREIGN key(dep_id) REFERENCES  tb_dept(id); 
      

    • 2.4 表关系(多对多)

    • 多对多

      适用场景

      • 商品和客户

      • 商品 和 订单

      • 学生和课程。一个学生可以选择多个课程,一个课程也可以被多个学生选择。

      • 购物车 商品

      • 老师和课程表

    • 实现方式

      建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

    • 案例

      我们以 订单表商品表 举例:

      经过分析发现,订单表和商品表都属于多的一方,此时需要创建一个中间表,在中间表中添加订单表的外键和商品表的外键指向两张表的主键:

      建表语句如下:

      -- 删除表
      DROP TABLE IF EXISTS tb_order_goods;
      DROP TABLE IF EXISTS tb_order;
      DROP TABLE IF EXISTS tb_goods;
      ​
      -- 订单表
      CREATE TABLE tb_order(
          id int primary key auto_increment,
          payment double(10,2),
          payment_type TINYINT,
          status TINYINT
      );
      ​
      -- 商品表
      CREATE TABLE tb_goods(
          id int primary key auto_increment,
          title varchar(100),
          price double(10,2)
      );
      ​
      -- 订单商品中间表
      CREATE TABLE tb_order_goods(
          id int primary key auto_increment,
          order_id int,
          goods_id int,
          count int
      );
      ​
      -- 建完表后,添加外键
      alter table tb_order_goods add CONSTRAINT fk_order_id FOREIGN key(order_id) REFERENCES tb_order(id);
      alter table tb_order_goods add CONSTRAINT fk_goods_id FOREIGN key(goods_id) REFERENCES tb_goods(id);
    • 2.5 数据库设计三范式

      1.第一范式(确保每列保持原子性)

      2.第二范式(确保表中的每列都和主键相关)

      3.第三范式(确保每列都和主键列直接相关,而不是间接相关)

      设计范式:

      1.第一范式(确保每列保持原子性)

      也就是说表中每个字段不能再被拆分。

      详细地址不满足第一范式!还可以继续拆分成 xx区 最终具体到xx号

      2.第二范式(确保表中的每列都和主键相关)

      小结三范式:

      1.第一范式(确保每列保持原子性)

      2.第二范式(确保表中的每列都和主键相关)

      3.第三范式(确保每列都和主键列直接相关,而不是间接相关)

      反三范式案例:

      临时订单方便展示,会把商品名称放到订单表里展示!

      2.6 数据库设计案例

      2.6.1 佳人
      create table people_detail(
      id int primary key auto_increment,
      image varchar(255),
      ename varchar(255),
      birthday date,
      sex char(1),
      address varchar(255)
      );
      create table people(
      id int primary key auto_increment,
      name varchar(255),
      age int,
      image varchar(255),
      status char(1),
      xueli varchar(255),
      detail_id int,
      CONSTRAINT fk_people_detail FOREIGN key(detail_id) REFERENCES people_detail(id)
      );

      根据下图设计表及表和表之间的关系:

      经过分析,我们分为 专辑表 曲目表 短评表 用户表 4张表。

      一个专辑可以有多个曲目,一个曲目只能属于某一张专辑,所以专辑表和曲目表的关系是一对多。

      一个专辑可以被多个用户进行评论,一个用户可以对多个专辑进行评论,所以专辑表和用户表的关系是 多对多。

      一个用户可以发多个短评,一个短评只能是某一个人发的,所以用户表和短评表的关系是 一对多。(E-R图)

      多表重要字段设计分析:

      曲目表: 曲目id name...等基本字段 专辑id

      专辑表: 专辑id 发行时间等基本信息

      短评表: 短评id 短评信息等基本字段 专辑id 用户id

      用户表: 用户id name...基本字段等

      用户—专辑表: id 专辑id 用户id

      drop table Music;
      drop table Song;
      drop table Review;
      drop table User;
      ​
      -- 专辑
      create table Music(
      title varchar(32),
      alias varchar(32),
      image varchar(64),
      style varchar(8),
      type varchar(4),
      medium varchar(4),
      publish_time date,
      publisher varchar(16),
      number  tinyint,
      barcode bigint,
      summary varchar(1024),
      artist varchar(16),
      id int PRIMARY key 
      ); 
      -- 曲目
      create table Song(
      name varchar(32),
      serial_number tinyint,
      id int PRIMARY key 
      ); 
      -- 评论
      create table Review(
      id int  PRIMARY key auto_increment,
      content varchar(256),
      rating tinyint,
      review_time datetime,
      review_id int
      ); 
      ​
      -- 用户
      create table User(
      id int PRIMARY key auto_increment,
      username varchar(16),
      image varchar(64),
      signature varchar(64),
      nickname varchar(16)
      ); 
      ​
      -- 专辑表和用户表的关系是 =多对多
      create table tb_Music_User(
      id int primary key auto_increment,
      music_id int,
      user_id int,
      count int
      );
      ​
      ​
      -- 添加外键
      -- 专辑对 曲目 一对多
      ALTER TABLE Music ADD CONSTRAINT fk_sc1 FOREIGN KEY (id) REFERENCES Song(id);
      -- 专辑表和用户表的关系是 ==多对多
      ALTER TABLE tb_Music_User ADD CONSTRAINT fk_tc1 FOREIGN KEY (music_id) REFERENCES Music(id);
      ALTER TABLE tb_Music_User ADD CONSTRAINT fk_tc2 FOREIGN KEY (user_id) REFERENCES User(id);
      ​
      -- 用户表和短评表的关系是 ==一对多==
      ALTER TABLE Review ADD CONSTRAINT fk_gc1 FOREIGN KEY (review_id) REFERENCES User(id);

      总结:

      1对多设计,外键在多!!!

      多对多设计,外键在中间表!!!

    • 3. 多表查询

      3.0 笛卡尔积查询

      笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尔积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。 笛卡尔积由笛卡尔提出。又称笛卡尔乘积。

      简单概括:举例说明 集合X={1,2,3},集合Y={a,b};两个集合的笛卡尔积为{(1,a),(1,b),(2,a),(2,b),(3,a),(3,b)}. 他们的结果为X集合的成员个数✖Y集合成员个数。

      笛卡尔积查询

      select * from 表1,表2;

      eg:

       select * from dept,emp;

      多表查询顾名思义就是从多张表中一次性的查询出我们想要的数据。我们通过具体的sql给他们演示,先准备环境

      DROP TABLE IF EXISTS emp;
      DROP TABLE IF EXISTS dept;
      ​
      # 创建部门表
          CREATE TABLE dept(
              did INT PRIMARY KEY AUTO_INCREMENT,
              dname VARCHAR(20)
          );
      ​
          # 创建员工表
          CREATE TABLE emp (
              id INT PRIMARY KEY AUTO_INCREMENT,
              NAME VARCHAR(10),
              gender CHAR(1), -- 性别
              salary DOUBLE, -- 工资
              join_date DATE, -- 入职日期
              dep_id INT,
              FOREIGN KEY (dep_id) REFERENCES dept(did) -- 外键,关联部门表(部门表的主键)
          );
          -- 添加部门数据
          INSERT INTO dept (dNAME) VALUES ('研发部'),('市场部'),('财务部'),('销售部');
          -- 添加员工数据
          INSERT INTO emp(NAME,gender,salary,join_date,dep_id) VALUES
          ('孙悟空','男',7200,'2013-02-24',1),
          ('猪八戒','男',3600,'2010-12-02',2),
          ('唐僧','男',9000,'2008-08-08',2),
          ('白骨精','女',5000,'2015-10-07',3),
          ('蜘蛛精','女',4500,'2011-03-14',1),
          ('小白龙','男',2500,'2011-02-14',null); 

      执行下面的多表查询语句

      select * from emp , dept;  -- 从emp和dept表中查询所有的字段数据

      结果如下:

      从上面的结果我们看到有一些无效的数据,如 孙悟空 这个员工属于1号部门,但也同时关联的2、3、4号部门。所以我们要通过限制员工表中的 dep_id 字段的值和部门表 did 字段的值相等来消除这些无效的数据,

      select * from emp , dept where emp.dep_id = dept.did;

      执行后结果如下:

      上面语句就是连接查询,那么多表查询都有哪些呢?

    • 连接查询

      • 内连接查询 :相当于查询AB交集数据

      • 外连接查询

        • 左外连接查询 :相当于查询A表所有数据和交集部门数据

        • 右外连接查询 : 相当于查询B表所有数据和交集部分数据

    • 子查询

    • 3.1 内连接查询

      内连接查询:两张表有交集的部分数据(有主外键关联的数据)。

    • 语法

    • -- 隐式内连接
      SELECT 字段列表 FROM 表1,表2… WHERE 条件;
      ​
      -- 显示内连接
      SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 条件;

      内连接相当于查询 A B 交集数据

    • 案例

      • 隐式内连接

        SELECT
            *
        FROM
            emp,
            dept
        WHERE
            emp.dep_id = dept.did;
        

      • 查询 emp的 name, gender,dept表的dname

        SELECT
            emp. NAME,
            emp.gender,
            dept.dname
        FROM
            emp,
            dept
        WHERE
            emp.dep_id = dept.did;
        

        上面语句中使用表名指定字段所属有点麻烦,sql也支持给表指别名,上述语句可以改进为

        SELECT
            t1. NAME,
            t1.gender,
            t2.dname
        FROM
            emp t1,
            dept t2
        WHERE
            t1.dep_id = t2.did;
      • 显式内连接

        select * from emp inner join dept on emp.dep_id = dept.did;
        -- 上面语句中的inner可以省略,可以书写为如下语句
        select * from emp  join dept on emp.dep_id = dept.did;
        

    • 3.2 外连接查询

    • 语法

      -- 左外连接
      SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
      ​
      -- 右外连接
      SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;

      左外连接:相当于查询A表所有数据和交集部分数据

      右外连接:相当于查询B表所有数据和交集部分数据

    • 案例

      • 查询emp表所有数据和对应的部门信息(左外连接)

        select * from emp left join dept on emp.dep_id = dept.did;
        

        结果显示查询到了表(emp)中所有的数据及两张表能关联的数据。

      • 查询dept表所有数据和对应的员工信息(右外连接)

        select * from emp right join dept on emp.dep_id = dept.did;
        

        结果显示查询到了右表(dept)中所有的数据及两张表能关联的数据。

        要查询出部门表中所有的数据,也可以通过左外连接实现,只需要将两个表的位置进行互换:

        select * from dept left join emp on emp.dep_id = dept.did;
    • 小结:

      普通两张表: 笛卡尔乘积 4*4=16

      内连接: 条件筛选

      外联接:

      左外: 左边的全部加上中间的 left join on

      右外:右边的全部加上中间的 right join on

      3.3 子查询

    • 概念

      查询中嵌套查询,称嵌套查询为子查询。

      什么是查询中嵌套查询呢?我们通过一个例子来看:

      需求:查询工资高于猪八戒的员工信息。

      来实现这个需求,我们就可以通过二步实现,第一步:先查询出来 猪八戒的工资

      select salary from emp where name = '猪八戒'

      第二步:查询工资高于猪八戒的员工信息

      select * from emp where salary > 3600;

      第二步中的3600可以通过第一步的sql查询出来,所以将3600用第一步的sql语句进行替换

      select * from emp where salary > (select salary from emp where name = '猪八戒');

      这就是查询语句中嵌套查询语句。

    • 子查询根据查询结果不同,作用不同

      • 子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断 普通条件

        SELECT 列名 FROM 表名 WHERE 列名=(SELECT 列名 FROM 表名 [WHERE 条件]);
      • 子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断 in

      SELECT 列名 FROM 表名 WHERE 列名 [NOT] IN (SELECT 列名 FROM 表名 [WHERE 条件]); 
      • 子查询语句结果是多行多列,子查询语句作为虚拟表 from

      SELECT 列名 FROM 表名 [别名],(SELECT 列名 FROM 表名 [WHERE 条件]) [别名] [WHERE 条件];

    • 案例

      • 查询 '财务部' 和 '市场部' 所有的员工信息

        -- 查询 '财务部' 或者 '市场部' 所有的员工的部门did
        select did from dept where dname = '财务部' or dname = '市场部';
        ​
        select * from emp where dep_id in (select did from dept where dname = '财务部' or dname = '市场部');
      • 查询入职日期是 '2011-11-11' 之后的员工信息和部门信息

        -- 查询入职日期是 '2011-11-11' 之后的员工信息
        select * from emp where join_date > '2011-11-11' ;
        -- 将上面语句的结果作为虚拟表和dept表进行内连接查询
        select * from (select * from emp where join_date > '2011-11-11' ) t1, dept where t1.dep_id = dept.did;
    • 自关联查询概念: 在同一张表中数据有关联性,我们可以把这张表当成多个表来查询。

      查询员工信息,并展示员工的领导姓名(自关联)

      -- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询
      /*
      分析:
      1.姓名 查emp表 直接上级姓名mgr查询emp表  所以emp表的id和mgr是自关联
      所以我们是在一个emp里查询
      2.emp.id=emp.mgr
      3.需要查询左表的全部数据 罗贯中没有领导  和交集数据
      */
      -- 第一种
      select e1.*,e2.ename as '领导'  from emp e1,emp e2 where e1.mgr = e2.id;
      -- 第二种
      SELECT
      t1.*,
      t2.ename
      FROM
      emp t1
      LEFT JOIN emp t2
      ON t1.mgr=t2.id;

      子查询三类:

    • 子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断 where 后面

    • 子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断 in里面

    • 子查询语句结果是多行多列,子查询语句作为虚拟表 from后面

    • 子查询效率较低,尽量少用。

      3.4 案例

    • 环境准备:

    • DROP TABLE IF EXISTS emp;
      DROP TABLE IF EXISTS dept;
      DROP TABLE IF EXISTS job;
      DROP TABLE IF EXISTS salarygrade;
      ​
      -- 部门表
      CREATE TABLE dept (
        id INT PRIMARY KEY PRIMARY KEY, -- 部门id
        dname VARCHAR(50), -- 部门名称
        loc VARCHAR(50) -- 部门所在地
      );
      ​
      -- 职务表,职务名称,职务描述
      CREATE TABLE job (
        id INT PRIMARY KEY,
        jname VARCHAR(20),
        description VARCHAR(50)
      );
      ​
      -- 员工表
      CREATE TABLE emp (
        id INT PRIMARY KEY, -- 员工id
        ename VARCHAR(50), -- 员工姓名
        job_id INT, -- 职务id
        mgr INT , -- 上级领导
        joindate DATE, -- 入职日期
        salary DECIMAL(7,2), -- 工资
        bonus DECIMAL(7,2), -- 奖金
        dept_id INT, -- 所在部门编号
        CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
        CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
      );
      -- 工资等级表
      CREATE TABLE salarygrade (
        grade INT PRIMARY KEY,   -- 级别
        losalary INT,  -- 最低工资
        hisalary INT -- 最高工资
      );
                      
      -- 添加4个部门
      INSERT INTO dept(id,dname,loc) VALUES 
      (10,'教研部','北京'),
      (20,'学工部','上海'),
      (30,'销售部','广州'),
      (40,'财务部','深圳');
      ​
      -- 添加4个职务
      INSERT INTO job (id, jname, description) VALUES
      (1, '董事长', '管理整个公司,接单'),
      (2, '经理', '管理部门员工'),
      (3, '销售员', '向客人推销产品'),
      (4, '文员', '使用办公软件');
      ​
      ​
      -- 添加员工
      INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 
      (1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
      (1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
      (1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
      (1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
      (1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
      (1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
      (1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
      (1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
      (1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
      (1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
      (1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
      (1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
      (1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
      (1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
      ​
      ​
      -- 添加5个工资等级
      INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 
      (1,7000,12000),
      (2,12010,14000),
      (3,14010,20000),
      (4,20010,30000),
      (5,30010,99990);
    • 需求

    • -- 1.查询员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述(内连接)
      -- 2.查询所有部门编号和部门名称员工姓名、工资(外连接)
      -- 3.查询员工姓名,工资,工资等级(内)
      -- 4.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置(内)
      -- 5.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级(内)
      -- 6.查询出部门编号、部门名称、部门位置、部门人数(子查询)
      -- 7.查询出部门编号、部门名称、部门位置、部门人数(如果部门没有人补0)(子查询)
          -- (提示函数:外连接查询+ifnull(列,0))

    • 查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述(内连接)

    •      /*
              分析:
                  1. 员工编号,员工姓名,工资 信息在emp 员工表中
                  2. 职务名称,职务描述 信息在 job 职务表中
                  3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id
           */
           -- 方式一 :隐式内连接
           SELECT
              emp.id,
              emp.ename,
              emp.salary,
              job.jname,
              job.description
           FROM
              emp,
              job
           WHERE
              emp.job_id = job.id;
           
           -- 方式二 :显式内连接
         SELECT
              emp.id,
              emp.ename,
           emp.salary,
           job.jname,
           job.description
              FROM
                  emp
              INNER JOIN job ON emp.job_id = job.id;
    • 查询所有部门编号和部门名称.员工姓名、工资(外连接)

    • select dept.id,dept.dname,emp.ename,emp.salary from dept left join emp on dept.id = emp.dept_id;

      3.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置(内连接)

           /*
              分析:
                  1. 员工编号,员工姓名,工资 信息在emp 员工表中
                  2. 职务名称,职务描述 信息在 job 职务表中
                  3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id
           
                  4. 部门名称,部门位置 来自于 部门表 dept
                  5. dept 和 emp 一对多关系 dept.id = emp.dept_id
           */
           
           -- 方式一 :隐式内连接
           SELECT
              emp.id,
              emp.ename,
              emp.salary,
              job.jname,
              job.description,
              dept.dname,
              dept.loc
           FROM
              emp,
              job,
              dept
           WHERE
              emp.job_id = job.id
              and dept.id = emp.dept_id
           ;
           
           -- 方式二 :显式内连接
           SELECT
              emp.id,
              emp.ename,
          emp.salary,
              job.jname,
          job.description,
              dept.dname,
              dept.loc
           FROM
              emp
           INNER JOIN job ON emp.job_id = job.id
           INNER JOIN dept ON dept.id = emp.dept_id

      4.查询员工姓名,工资,工资等级(内连接)

           /*
              分析:
                  1. 员工姓名,工资 信息在emp 员工表中
                  2. 工资等级 信息在 salarygrade 工资等级表中
                  3. emp.salary >= salarygrade.losalary  and emp.salary <= salarygrade.hisalary
           */
           SELECT
         emp.ename,
           emp.salary,
           t2.*
              FROM
                  emp,
                  salarygrade t2
              WHERE
                  emp.salary >= t2.losalary
              AND emp.salary <= t2.hisalary

      5.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级(内连接)

           /*
              分析:
                  1. 员工编号,员工姓名,工资 信息在emp 员工表中
                  2. 职务名称,职务描述 信息在 job 职务表中
                  3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id
           
                  4. 部门名称,部门位置 来自于 部门表 dept
                  5. dept 和 emp 一对多关系 dept.id = emp.dept_id
                  6. 工资等级 信息在 salarygrade 工资等级表中
                  7. emp.salary >= salarygrade.losalary  and emp.salary <= salarygrade.hisalary
           */
           SELECT
              emp.id,
              emp.ename,
              emp.salary,
              job.jname,
          job.description,
              dept.dname,
          dept.loc,
              t2.grade
           FROM
              emp
           INNER JOIN job ON emp.job_id = job.id
           INNER JOIN dept ON dept.id = emp.dept_id
           INNER JOIN salarygrade t2 ON emp.salary BETWEEN t2.losalary and t2.hisalary;

      6.查询出部门编号、部门名称、部门位置、部门人数(子连接)

           /*
              分析:
                  1. 部门编号、部门名称、部门位置 来自于部门 dept 表
                  2. 部门人数: 在emp表中 按照dept_id 进行分组,然后count(*)统计数量
                  3. 使用子查询,让部门表和分组后的表进行内连接
           */
           -- 根据部门id分组查询每一个部门id和员工数
           select dept_id, count(*) from emp group by dept_id;
           
           SELECT
              dept.id,
              dept.dname,
              dept.loc,
              t1.total
           FROM
              dept,
              (
                  SELECT
                      dept_id,
                  count(*) total
              FROM
                  emp
              GROUP BY
                  dept_id
           ) t1
            WHERE
              dept.id = t1.dept_id;

      7.查询出部门编号、部门名称、部门位置、部门人数(如果部门没有人补0)(子查询)

      -- (提示函数:外连接查询+ifnull(列,0))

       SELECT
              dept.id,
              dept.dname,
              dept.loc,
              IFNULL(t1.count,0)
           FROM
              dept LEFT JOIN (
                  SELECT
                      dept_id,
                  count(*) count
              FROM
                  emp
              GROUP BY
                  dept_id
           ) t1 on dept.id = t1.dept_id;

    • 连接查询

      • 内连接(显,隐式)

      • 外连接(左连接,右连接)

    • 子查询

      • 子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断 where 后面

      • 子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断 in里面

      • 子查询语句结果是多行多列,子查询语句作为虚拟表 from后面

    • 4,事务

      问题:

      1. 什么是事务? default   ?一条一提交!
      2. 开启事务,提交,回滚。

      4.1 概述

      数据库的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令。

      事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败。

      事务是一个不可分割的工作逻辑单元。

      mysql默认事务为 : 一条一事务!

      这些概念不好理解,接下来举例说明

      张三和李四账户中各有100块钱,现李四需要转换500块钱给张三,具体的转账操作为

    • 第一步:查询李四账户余额

    • 第二步:从李四账户金额 -500

    • 第三步:给张三账户金额 +500

    • 现在假设在转账过程中第二步完成后出现了异常第三步没有执行,就会造成李四账户金额少了500,而张三金额并没有多500;这样的系统是有问题的。如果解决呢?使用事务可以解决上述问题

      从上图可以看到在转账前开启事务,如果出现了异常回滚事务,三步正常执行就提交事务,这样就可以完美解决问题。

      4.2 语法

    • 开启事务

      START TRANSACTION;
      或者  
      BEGIN;
    • 提交事务

      commit;
    • 回滚事务

      rollback;

    • 4.3 代码验证

    • 环境准备

      DROP TABLE IF EXISTS account;
      ​
      -- 创建账户表
      CREATE TABLE account(
          id int PRIMARY KEY auto_increment,
          name varchar(10),
          money double(10,2)
      );
      ​
      -- 添加数据
      INSERT INTO account(name,money) values('张三',1000),('李四',1000);

    • 不加事务演示问题

      -- 转账操作
      -- 1. 查询李四账户金额是否大于500
      ​
      -- 2. 李四账户 -500
      UPDATE account set money = money - 500 where name = '李四';
      ​
      出现异常了...  -- 此处不是注释,在整体执行时会出问题,后面的sql则不执行
      -- 3. 张三账户 +500
      UPDATE account set money = money + 500 where name = '张三';

      整体执行结果肯定会出问题,我们查询账户表中数据,发现李四账户少了500。

    • 添加事务sql如下:

      -- 开启事务
      BEGIN;
      -- 转账操作
      -- 1. 查询李四账户金额是否大于500
      ​
      -- 2. 李四账户 -500
      UPDATE account set money = money - 500 where name = '李四';
      ​
      出现异常了...  -- 此处不是注释,在整体执行时会出问题,后面的sql则不执行
      -- 3. 张三账户 +500
      UPDATE account set money = money + 500 where name = '张三';
      ​
      -- 提交事务
      COMMIT;
      ​
      -- 回滚事务
      ROLLBACK;

      上面sql中的执行成功进选择执行提交事务,而出现问题则执行回滚事务的语句。以后我们肯定不可能这样操作,而是在java中进行操作,在java中可以抓取异常,没出现异常提交事务,出现异常回滚事务。

    • 开启事务: start TRANSACTION 或者 begin

      提交事务: commit

      回滚:rollback

      ROLLBACK TRANSACTION 清除自事务的起点或到某个保存点所做的所有数据修改。 ROLLBACK 还释放由事务控制的资源。 的操作恢复到事务执行前或某个指定位置. 数据回滚。
      要想使用回滚 SELECT @@autocommit; set @@autocommit = 0;

      说明:

      mysql中事务是自动提交的。

      也就是说我们不添加事务执行sql语句,语句执行完毕会自动的提交事务。

      可以通过下面语句查询默认提交方式:

      SELECT @@autocommit;

      查询到的结果是1 则表示自动提交,结果是0表示手动提交。当然也可以通过下面语句修改提交方式

      set @@autocommit = 0;

      4.4 事务的四大特征(面试题)

    • 原子性(Atomicity): 事务是不可分割的最小操作单位,要么同时成功,要么同时失败

    • 一致性(Consistency) :事务完成时,必须使所有的数据都保持一致状态

    • 隔离性(Isolation) :多个事务之间,操作的可见性 并发

    • 持久性(Durability) :事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

    • 事务:

    • 概念:多条语句要么同时成功,要么同时失败

    • 操作:开启事务、提交事务、回滚事务

    • 事务的四个特性:原子性、一致性、隔离性、持久性

    • 5. 视图

      为什么要用视图(虚表)?

      概念:其本质是对应于一条SELECT语句,结果集被赋予一个名字,即视图名字。

      1. 我们有表了,我们为什么还要用虚表呢?

      2. 比如:学生表、班级表

      3. 查询的时候总是展示班级name,学生name。每次我都要写两个表。

      4. 现在我吧classname,studentname封装成一个表。是不是会简化我们的查询呢?

      1.视图的概念
    • 视图(VIEW)也被称作虚表,即虚拟的表,是一组数据的逻辑表示,其本质是对应于一条SELECT语句,结果集被赋予一个名字,即视图名字

    • 视图本身并不包含任何数据,它只包含映射到基表的一个查询语句,当基表数据发生变化,视图数据也随之变化。

    • 2.视图的好处
    • 简单

      • 对于使用视图的用户不需要关心表的结构、关联条件和筛选条件。因为这张虚拟表中保存的就是已经过滤好条件的结果集。

    • 安全

      • 视图可以设置权限 , 致使访问视图的用户只能访问他们被允许查询的结果集。

    • 数据独立

      • 一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。

    • 3.视图数据准备
      -- 创建db7数据库
      CREATE DATABASE db7;
      ​
      -- 使用db7数据库
      USE db7;
      ​
      -- 创建country表
      CREATE TABLE country(
          id INT PRIMARY KEY AUTO_INCREMENT,
          country_name VARCHAR(30)
      );
      -- 添加数据
      INSERT INTO country VALUES (NULL,'中国'),(NULL,'美国'),(NULL,'俄罗斯');
      ​
      -- 创建city表
      CREATE TABLE city(
          id INT PRIMARY KEY AUTO_INCREMENT,
          city_name VARCHAR(30),
          cid INT, -- 外键列。关联country表的主键列id
          CONSTRAINT cc_fk1 FOREIGN KEY (cid) REFERENCES country(id)
      );
      -- 添加数据
      INSERT INTO city VALUES (NULL,'北京',1),(NULL,'上海',1),(NULL,'纽约',2),(NULL,'莫斯科',3);
      4.视图的创建
    • 创建视图语法

    • -- 标准语法
      CREATE VIEW 视图名称 [(列名列表)] AS 查询语句;
    • 普通多表查询,查询城市和所属国家

    • -- 普通多表查询,查询城市和所属国家
      SELECT
          t1.*,
          t2.country_name
      FROM
          city t1,
          country t2
      WHERE
          t1.cid = t2.id;
          
      -- 经常需要查询这样的数据,就可以创建一个视图
    • 创建视图基本演示

    • -- 创建一个视图。将查询出来的结果保存到这张虚拟表中
      CREATE
      VIEW
          city_country
      AS
          SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;
    • 创建视图并指定列名基本演示

    • -- 创建一个视图,指定列名。将查询出来的结果保存到这张虚拟表中
      CREATE
      VIEW
          city_country2 (city_id,city_name,cid,country_name) 
      AS
          SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;
      ​
      5.视图的查询
    • 查询视图语法

    • -- 标准语法
      SELECT * FROM 视图名称;
    • 查询视图基本演示

    • -- 查询视图。查询这张虚拟表,就等效于查询城市和所属国家
      SELECT * FROM city_country;
      ​
      -- 查询指定列名的视图
      SELECT * FROM city_country2;
      ​
      -- 查询所有数据表,视图也会查询出来
      SHOW TABLES;
    • 查询视图创建语法

    • -- 标准语法
      SHOW CREATE VIEW 视图名称;
    • 查询视图创建语句基本演示

    • SHOW CREATE VIEW city_country;
      6.视图的修改

      注意:视图表数据修改,会自动修改源表中的数据

    • 修改视图表中的数据

    • -- 标准语法
      UPDATE 视图名称 SET 列名=值 WHERE 条件;
      ​
      -- 修改视图表中的城市名称北京为北京市
      UPDATE city_country SET city_name='北京市' WHERE city_name='北京';
      ​
      -- 查询视图
      SELECT * FROM city_country;
      ​
      -- 查询city表,北京也修改为了北京市
      SELECT * FROM city;
      ​
      -- 注意:视图表数据修改,会自动修改源表中的数据
    • 修改视图表结构

    • -- 标准语法
      ALTER VIEW 视图名称 [(列名列表)] AS 查询语句;
      ​
      -- 查询视图2
      SELECT * FROM city_country2;
      ​
      -- 修改视图2的列名city_id为id
      ALTER
      VIEW
          city_country2 (id,city_name,cid,country_name)
      AS
          SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;
      7.视图的删除
    • 删除视图

    • -- 标准语法
      DROP VIEW [IF EXISTS] 视图名称;
      ​
      -- 删除视图
      DROP VIEW city_country;
      ​
      -- 如果存在则删除
      DROP VIEW IF EXISTS city_country2;
      8.视图的总结
    • 视图是一种虚拟存在的数据表

    • 这个虚拟的表并不在数据库中实际存在

    • 说白了,视图就是将一条SELECT查询语句的结果封装到了一个虚拟表中,所以我们在创建视图的时候,工作重心就要放在这条SELECT查询语句上

    • 视图的好处

      • 简单

      • 安全

      • 数据独立

    • 6. 索引

      -- 索引 -- 正常查找为一个一个找....比较慢 -- 通过二叉树方式找综合提升查找性能 -- (B+tree算法) -- 增删改效率变低

      -- 索引分类: -- 主键索引、唯一索引、普通索引index、全文索引、组合索引(多列索引)

      小结:

    • 约束:主键primary key 外键 foreign key 唯一 unigue 默认default 非空not null 检查

    • 索引:B+tree

      1. 概念:通过算法提升查找性能

      2. 分类:主键索引、唯一索引、普通索引index、全文索引、组合索引(多列索引)

    • 多表设计:1v1 1vn nvn

      1. 1vn 从表字段在多的一方。多的一方为从表,1的一方为主表。

      2. nvn 从表字段在第三张表。两方都是主表,第三张表为从表。

    • 多表查询

      1. 笛卡尔积: 第一个表3条 第二个表4条 3x4=12条

      2. 连接查询

        1. 内连接 where 关联条件/ 第一个表 inner join 第二个表 on 关联条件

        2. 外连接

          1. 左外连接 左表 left join 右表 on 关联条件 (左表的全部+中间部分)

          2. 右外连接 左表 right join 右表 on 关联条件 (右表的全部+中间部分)

      3. 子查询(根据结果)

        1. 一个值(单行单列) 普通的值来处理 = < >

        2. 一条(多行单列)in 、 not in

        3. 一张表(多行多列) 虚表

    • 视图:

      1. 特点:1.简化开发2. 相对安全 3. 操作简单 4.不占用硬盘资源

    • 事务

      1. 概念:多条语句同时成功,同时失败。

      2. default?一条一提交。

      3. 开启(begin)、提交(commit)、回滚(rollback)。

      4. 特点:原子性A 一致性C 隔离性I 持久性D

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值