MySQL(Python相关) day04

2018.8.2

目录

1,外键(foreign bey)

2,表的复制

3,嵌套查询(子查询)

4,多表查询

5,连接查询

6、数据备份

7、数据恢复

8,MySQL的用户账户管理


day04

1,外键(foreign bey)

  1. 定义:让当前表字段的值在另一个表的范围内选择
  2. 语法
    foreign key(参考字段名)
    references 主表(被参考字段名)
    on delete  级联动作
    on updata 级联动作
  3. 使用规则
    1. 主表,从表字段数据类型要一致
    2. 主表被参考字段: 主键
  4. 示例
    表1,缴费信息(财务表)
    id    姓名      班级     缴费金额
    1   唐伯虎   AID06       300
    2   点秋香   AID06       260
    3   祝枝山   AID06       250

    表2,学生信息表(班主任)
    id    姓名     缴费金额
    1   唐伯虎       300
    2   点秋香       260
    3  XXXXXXXXXXX

    1,创建表
    表1:
    create table jftab(
    id int primary key,
    name varchar(15),
    class char(15),
    money int
    );

    insert into jftab values
    (1,'唐伯虎','AID06',300),
    (2,'点秋香','AID06',260),
    (3,'祝枝山','AID06',250);

    表2(从表):
    create table bjtab(
    stu_id int,
    name varchar(15),
    money int,
    foreign key(stu_id) references jftab(id)
    on delete cascade
    on update cascade
    );

    insert into bjtab values
    (1,'唐伯虎',300),
    (2,'点秋香',260); 
    #顺序1
    mysql> select * from jftab;
    +----+-----------+-------+-------+
    | id | name      | class | money |
    +----+-----------+-------+-------+
    |  1 | 唐伯虎    | AID06 |   300 |
    |  2 | 点秋香    | AID06 |   260 |
    |  3 | 祝枝山    | AID06 |   250 |
    +----+-----------+-------+-------+
    
    mysql> select * from bjtab;
    +--------+-----------+-------+
    | stu_id | name      | money |
    +--------+-----------+-------+
    |      1 | 唐伯虎    |   300 |
    |      2 | 点秋香    |   260 |
    +--------+-----------+-------+
    #删除点秋香
    mysql> delete from jftab where name='点秋香';
    
    mysql> select * from bjtab;
    +--------+-----------+-------+
    | stu_id | name      | money |
    +--------+-----------+-------+
    |      1 | 唐伯虎    |   300 |
    +--------+-----------+-------+
    #把唐伯虎id=2
    mysql> update jftab set id=2 where name='唐伯虎';
    
    mysql> select * from bjtab;
    +--------+-----------+-------+
    | stu_id | name      | money |
    +--------+-----------+-------+
    |      2 | 唐伯虎    |   300 |
    +--------+-----------+-------+
    
    
    
    
    
    

     
  5. 删除外键
    alter table 表名 drop foreign key 外键名;
    外键名: show create table 表名;
    #顺序2
    #获取外键值
    mysql> show create table bjtab;
    +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | bjtab | CREATE TABLE `bjtab` (
      `stu_id` int(11) DEFAULT NULL,
      `name` varchar(15) DEFAULT NULL,
      `money` int(11) DEFAULT NULL,
      KEY `stu_id` (`stu_id`),
      CONSTRAINT `bjtab_ibfk_1` FOREIGN KEY (`stu_id`) REFERENCES `jftab` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    #外键名就是 bjtab_ibfk_1
    #删除外键名
    alter table bjtab drop foreign key bjtab_ibfk_1;
    
  6. 级联动作
    1. cascade
      数据级联删除,更新(参考字段)
    2. restrict(默认)
      1. 当删除主表记录时,如果从表中有相关联记录则主表不允许删除
      2. 更新同理
    3. set null
      主表删除,更新,从表相关联记录字段值为NULL
      更新同理
    4. no action
      on delete no action on update no action
      同restrict,都是立即检查外键限制
  7. 已有表中添加外键
    alter table 表名 add
    foreign key(参考字段名)references 主表(被参考字段)
    on delete ...
    on updata ...
     
    #restrict(默认)
    当删除主表记录时,如果从表中有相关联记录则主表不允许删除
    更新同理
    
    mysql> alter table bjtab add
        -> foreign key(stu_id)
        -> references jftab(id);
    Query OK, 1 row affected (0.06 sec)
    Records: 1  Duplicates: 0  Warnings: 0
    
    mysql> select * from jftab;
    +----+-----------+-------+-------+
    | id | name      | class | money |
    +----+-----------+-------+-------+
    |  2 | 唐伯虎    | AID06 |   300 |
    |  3 | 祝枝山    | AID06 |   250 |
    +----+-----------+-------+-------+
    2 rows in set (0.00 sec)
    
    mysql> select * from bjtab;
    +--------+-----------+-------+
    | stu_id | name      | money |
    +--------+-----------+-------+
    |      2 | 唐伯虎    |   300 |
    +--------+-----------+-------+
    
    mysql> delete from jftab where name='唐伯虎';
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`song`.`bjtab`, CONSTRAINT `bjtab_ibfk_1` FOREIGN KEY (`stu_id`) REFERENCES `jftab` (`id`))
    #班级里面有外键关联,不允许删,所以只能先删班级里面的唐伯虎,再删缴费里面的唐伯虎
    
    mysql> delete from bjtab where name='唐伯虎';
    Query OK, 1 row affected (0.00 sec)
    
    mysql> delete from jftab where name='唐伯虎';
    Query OK, 1 row affected (0.01 sec)
    
    
    #set null
    #主表删除,更新,从表相关联记录字段值为NULL
    #更新同理
    mysql> insert into bjtab values
        -> (3,'祝枝山',250);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from bjtab;
    +--------+-----------+-------+
    | stu_id | name      | money |
    +--------+-----------+-------+
    |      3 | 祝枝山    |   250 |
    +--------+-----------+-------+
    
    mysql> select * from jftab;
    +----+-----------+-------+-------+
    | id | name      | class | money |
    +----+-----------+-------+-------+
    |  3 | 祝枝山    | AID06 |   250 |
    +----+-----------+-------+-------+
    
    mysql> show create table bjtab;
    mysql> alter table bjtab drop foreign key bjtab_ibfk_1;
    
    mysql> alter table bjtab add
        -> foreign key(stu_id)
        -> references jftab(id)
        -> on delete set null
        -> on update set null;
    Query OK, 1 row affected (0.05 sec)
    Records: 1  Duplicates: 0  Warnings: 0
    mysql> delete from jftab where name='祝枝山';
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from bjtab;
    +--------+-----------+-------+
    | stu_id | name      | money |
    +--------+-----------+-------+
    |   NULL | 祝枝山    |   250 |
    +--------+-----------+-------+
    
    
    
    


     

2,表的复制

  1. 表的重命名:alter table 表名 rename 新表名;
  2. 语法
    create table 表名 select ... from 表名 where 条件;
  3. 示例
    1. 复制MOSHOU.sanguo表的全部记录和字段,sanguo2
      create table sanguo2
      select * from MOSHOU.sanguo;
       
    2. 复制MOSHOU.sanguo表的前3条记录,sanguo3
      create table sanguo3
      select * from MOSHOU.sanguo
      limit 3;
    3. 复制MOSHOU.sanguo表的id,name,country 三个字段的前5条记录,sanguo4
      create table sanguo4
      select id,name,country from MOSHOU.sanguo
      limit 5;
  4. 复制表结构
    create table 表名 select * from 表名 where false;
    1. 复制MOSHOU.sanguo表结构 ,sanguo5
      create table sanguo5
      select * from MOSHOU.sanguo
      where false;
  5. 注意
    1. 复制表的时候不会把原表的 键(key) 属性复制过来

3,嵌套查询(子查询)

  1. 定义:把内层的查询结果作为外层的查询条件
  2. 语法格式
    select ... from 表名 where 条件(select ...);
  3. 示例
    1. 把攻击值小于平均攻击值的英雄名字和攻击值显示出来
      1. 先计算平均值
        select avg(gongji) from MOSHOU.sanguo;
      2. 找到 < 平均值
        select name,gongji from MOSHOU.sanguo
        where gongji < 平均值;
      3. 这样写才对嘛
        select name,gongji from MOSHOU.sanguo
        where gongji < (select avg(gongji) from MOSHOU.sanguo);
    2. 找出每个国家攻击力最高的英雄的名字和攻击值
      第1种做法是无bug,第二种做法可能会出错
       
      1. select name,gongji from MOSHOU.sanguo
        where (country,gongji) in
        (select country,max(gongji) from MOSHOU.sanguo group by country);
         
      2. select name,gongji from MOSHOU.sanguo
        where
        gongji in (
        select max(gongji) from MOSHOU.sanguo group by country);

4,多表查询

  1. 两种方式
    1,select 字段名列表 from 表名列表;(笛卡尔积)
    t1:name-->'A1' 'A2' 'A3'
    t2:name-->'B1' 'B2' 
    select * from t1,t2;
        +------+-------+
        | name | name2 |
        +------+-------+
        | A1   | B1    |
        | A1   | B2    |
        | A2   | B1    |
        | A2   | B2    |
        | A3   | B1    |
        | A3   | B2    |
        +------+-------+

    2,...where 条件
  2. 练习 点击查看
    1. 显示省和市的信息
      mysql> select sheng.s_name,city.c_name from sheng,city
          -> where
          -> sheng.s_id=city.cfather_id;
      +-----------+--------------+
      | s_name    | c_name       |
      +-----------+--------------+
      | 河北省    | 石家庄市     |
      | 河北省    | 沧州市       |
      | 河北省    | 廊坊市       |
      | 陕西省    | 西安市       |
      | 四川省    | 成都市       |
      | 四川省    | 重庆市       |
      | 广东省    | 广州市       |
      | 山东省    | 济南市       |
      | 湖北省    | 武汉市       |
      | 河南省    | 郑州市       |
      +-----------+--------------+
      

       
    2. 显示省,市和县的信息
      mysql> select sheng.s_name,city.c_name,xian.x_name from sheng,city,xian
          -> where
          -> sheng.s_id=city.cfather_id and
          -> city.c_id=xian.xfather_id;
      +-----------+--------------+-----------+
      | s_name    | c_name       | x_name    |
      +-----------+--------------+-----------+
      | 河北省    | 石家庄市     | 正定县    |
      | 湖北省    | 武汉市       | 武昌区    |
      +-----------+--------------+-----------+
      2 rows in set (0.00 sec)
      

5,连接查询

  1. 内连接
    1. 语法格式
      select 字段名 from
      表1 inner join 表2 on 条件;
      inner join 表3 on 条件
    2. 显示省市详细信息
      select sheng.s_name,city.c_name from sheng
      inner join city on sheng.s_id=city.cfather_id;
    3. 显示省市县详细信息
      select sheng.s_name,city.c_name,xian.x_name from sheng
      inner join city on sheng.s_id=city.cfather_id
      inner join xian on city.c_id=xian.xfather_id;
       
  2. 外连接
    1. 左连接
      1. 以左为主显示查询信息
      2. select 字段名 from
        表1 left join 表2 on 条件
        left join 表3 on 条件;
      3. 显示省和市详细信息
        select sheng.s_name as sheng,city.c_name as city
        from sheng left join city
        on sheng.s_id=city.cfather_id;
        +-----------+--------------+
        | sheng     | city         |
        +-----------+--------------+
        | 河北省    | 石家庄市     |
        | 河北省    | 沧州市       |
        | 河北省    | 廊坊市       |
        | 陕西省    | 西安市       |
        | 四川省    | 成都市       |
        | 四川省    | 重庆市       |
        | 广东省    | 广州市       |
        | 山东省    | 济南市       |
        | 湖北省    | 武汉市       |
        | 河南省    | 郑州市       |
        | 海南省    | NULL         |
        | 云南省    | NULL         |
        | 山西省    | NULL         |
        +-----------+--------------+
        

         
      4. 显示省,市和县的详细信息
        select sheng.s_name as sheng,city.c_name as city,xian.x_name as xian
        from sheng left join city
        on sheng.s_id=city.cfather_id
        left join xian on city.c_id=xian.xfather_id;
         
        +-----------+--------------+-----------+
        | sheng     | city         | xian      |
        +-----------+--------------+-----------+
        | 河北省    | 石家庄市     | 正定县    |
        | 湖北省    | 武汉市       | 武昌区    |
        | 河北省    | 沧州市       | NULL      |
        | 河北省    | 廊坊市       | NULL      |
        | 陕西省    | 西安市       | NULL      |
        | 四川省    | 成都市       | NULL      |
        | 四川省    | 重庆市       | NULL      |
        | 广东省    | 广州市       | NULL      |
        | 山东省    | 济南市       | NULL      |
        | 河南省    | 郑州市       | NULL      |
        | 海南省    | NULL         | NULL      |
        | 云南省    | NULL         | NULL      |
        | 山西省    | NULL         | NULL      |
        +-----------+--------------+-----------+
        

         
    2. 右连接
      1. 用法同左连接,以右边为主显示查询结果
      2. 显示省,市和县的详细信息
        select sheng.s_name as sheng,city.c_name as city,xian.x_name as xian
        from sheng right join city
        on sheng.s_id=city.cfather_id
        right join xian on city.c_id=xian.xfather_id;
         
        
        +-----------+--------------+--------------+
        | sheng     | city         | xian         |
        +-----------+--------------+--------------+
        | 河北省    | 石家庄市     | 正定县       |
        | 湖北省    | 武汉市       | 武昌区       |
        | NULL      | 上海市       | 浦东新区     |
        | NULL      | 雄安新区     | 安新县       |
        | NULL      | 雄安新区     | 容城县       |
        | NULL      | 雄安新区     | 雄县         |
        | NULL      | NULL         | 哈哈         |
        | NULL      | NULL         | 嘎嘎         |
        +-----------+--------------+--------------+
        

         

6、数据备份

(mysqldump,在Linux终端中操作)

  1. 命令格式
    mysqldump -u用户名 -p 源库名 > ~/***.sql
  2. 源库名的表示方式
    --all-databases     备份所有库
    库名                      备份单个库
    -B 库1 库2 库3      备份多个库
    库名 表1 表2 表3  备份指定库的多张表
  3. 示例
    1、备份所有库,放到 mydata 目录下:all.sql
    mysqldump -uroot -p --all-databases > all.sql
    2、备份 db4 库中的 sheng city xian 三张表,scx.sql
    mysqldump -uroot -p db4 sheng city xian > scx.sql
    3、备份 MOSHOU 和 db4 库, md.sql
    mysqldump -uroot -p -B MOSHOU db4 > md.sql
    4、备份 db4 库, db4.sql
    mysqldump -uroot -p db4 > db4.sql

    如果 不在当前文件运行 ,da4.sql前面加所在文件夹目录,可以cd 到当前文件,没有改文件就用mkdir+新文件,去创建
    mysqldump -uroot -p db4 > ~/mydata/db4.sql
  4. 注意
    1. ctrl+shift+t 重新打开一个终端
      mkdir +文件名  :创建文件
      cd +文件名 :改变当前路径

7、数据恢复

  1. 命令格式(Linux终端)
     mysql -uroot -p 目标库名 < ***.sql
  2. 从所有库备份中恢复某一个库(--one-database)
    mysql -uroot -p --one-database 目标库名 < all.sql
    mysql -uroot -p --one-database db4 < all.sql
     
    mysql> drop database db4;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | blog_db            |
    | fruit              |
    | fruitday           |
    | mysql              |
    | performance_schema |
    | sys                |
    | testdb             |
    | userorder          |
    +--------------------+
    9 rows in set (0.00 sec)
    
    #没有此库,就创建一个新库
    mysql> create database db4;
    Query OK, 1 row affected (0.00 sec)
    
    $mysqldump -uroot -p db4 > db4.sql
    

     
  3. 示例
    1. 在db4.sheng新增一条记录    
      mysql> insert into sheng values(11,200003,'日本三');
      Query OK, 1 row affected (0.00 sec)
      
      mysql> select * from sheng;
      +----+--------+-----------+
      | id | s_id   | s_name    |
      +----+--------+-----------+
      |  1 | 130000 | 河北省    |
      |  2 | 140000 | 陕西省    |
      |  3 | 150000 | 四川省    |
      |  4 | 160000 | 广东省    |
      |  5 | 170000 | 山东省    |
      |  6 | 180000 | 湖北省    |
      |  7 | 190000 | 河南省    |
      |  8 | 200000 | 海南省    |
      |  9 | 200001 | 云南省    |
      | 10 | 200002 | 山西省    |
      | 11 | 200003 | 日本三    |
      | 16 |   3000 | 台湾省    |
      +----+--------+-----------+
      
    2. 在db4中新建一张表 t888,里面插入1条记录
      create table t888(
      id int
      );
      
      insert into t888 values(1);
      
      mysql> select * from t888;
      +------+
      | id   |
      +------+
      |    1 |
      +------+
      
      
    3. 从db4.sql中恢复db4库
      mysql -uroot -p db4 < db4.sql
      $mysql -uroot -p db4 < db4.sql
      
      mysql> show tables;
      +---------------+
      | Tables_in_db4 |
      +---------------+
      | bjtab         |
      | city          |
      | jftab         |
      | jifei1        |
      | nam           |
      | nam1          |
      | sanguo2       |
      | sanguo3       |
      | sanguo4       |
      | sanguo5       |
      | sheng         |
      | t888          |
      | xian          |
      +---------------+
      
      
      mysql> select * from t888;
      +------+
      | id   |
      +------+
      |    1 |
      +------+
      
      
      mysql> select * from sheng;
      +----+--------+-----------+
      | id | s_id   | s_name    |
      +----+--------+-----------+
      |  1 | 130000 | 河北省    |
      |  2 | 140000 | 陕西省    |
      |  3 | 150000 | 四川省    |
      |  4 | 160000 | 广东省    |
      |  5 | 170000 | 山东省    |
      |  6 | 180000 | 湖北省    |
      |  7 | 190000 | 河南省    |
      |  8 | 200000 | 海南省    |
      |  9 | 200001 | 云南省    |
      | 10 | 200002 | 山西省    |
      | 16 |   3000 | 台湾省    |
      +----+--------+-----------+
      #新增的数据没了,新增的表还在,
  4. 注意
    1. 恢复库时如果恢复到原库会将表中数据覆盖,新增表不会删除
    2. 数据恢复时如果恢复的库不存在,则必须先创建空库
       

8,MySQL的用户账户管理

  1. 开启MySQL远程连接
    1. sudo -i
    2. cd /etc/mysql/mysql.conf.d/
    3. subl mysqld.cnf
      #bind-address = 127.0.0.1  (前面加#键)
      ctrl+s保存
    4. /etc/init.d/mysql restart(重启)
  2. 添加授权用户
    1. mysql -uroot -p123456
    2. 授权
      grant 授权列表 on 库.表,to '用户名'@'%'
      identified by '密码' with grant option;

      权限列表 :  all privileges、select、insert
      库.表 :  *.*  所有库的所有表
    3. 示例
      1. 添加授权用户tiger,密码123,对所有库的所有表有所有权限
        grant all privileges on *.* to 'tiger'@'%'
        identified by '123' with grant option;

        mysql -utiger -p123
      2. 添加用户rabbit,对db4库有所有权限   
        grant all privileges on db4.* to "rabbit"@"%" identified by "123" with grant option;
         
        $ mysql -urabbit -p123
        
        mysql> show databases;
        +--------------------+
        | Database           |
        +--------------------+
        | information_schema |
        | db4                |
        +--------------------+
        2 rows in set (0.01 sec)
        

         

9,作业

  1. 综述:两张表,一张顾客信息表customers,一张订单表orders
    1. 创建一张顾客信息表customers,字段要求如下:
      c_id 类型为整型,设置为主键,并设置为自增长属性
      c_name 字符类型,变长,宽度为20
      c_age 微小整型,取值范围为0~255(无符号)
      c_sex 枚举类型,要求只能在('M','F')中选择一个值
      c_city 字符类型,变长,宽度为20
      c_salary 浮点类型,要求整数部分最大为10位,小数部分为2位
       

      create table customers(
      c_id int primary key auto_increment,
      c_name varchar(20),
      c_age tinyint unsigned,
      c_sex enum('M','F'),
      c_city varchar(20),
      c_salary decimal(12,2)
      );


       

      在表中任意插入3条记录,c_name为"Zhangsan","Lisi","Wangwu", c_city尽量    写"Beijing","Shanghai" ......

      insert into customers values
      (1,"Zhangsan",25,"M","Beijing",8000),
      (2,"Lisi",30,"F","Shanghai",10000),
      (3,"Wangwu",27,"M","Shenzhen",3000);

    2. 创建一张订单表orders,字段要求如下:
      o_id 整型
      o_name 字符类型,变长,宽度为30
      o_price 浮点类型,整数最大为10位,小数部分为2位
      设置此表中的o_id字段为customers表中c_id字段的外键,更新删除同步
       

      create table orders(
      o_id int,
      o_name varchar(30),
      o_price decimal(12,2),
      foreign key(o_id)
      references customers(c_id)
      on delete cascade
      on update cascade
      );


       

      在表中任意插入5条记录(注意外键限制)
      o_name分别为"iphone","ipad","iwatch","mate9","r11",其他信息自己定
      insert into orders values
      (1,"iphone",5288),
      (1,"ipad",3299),
      (3,"mate9",3688),
      (2,"iwatch",2222),
      (2,"r11",4400);

    3. 返回customers表中,工资大于4000元,或者年龄小于29岁,满足这样条件的前2条记录
      delect * from customers where c_salary > 4000 or c_age < 29 limit 2;

    4. 把customers表中,年龄大于等于25岁,并且地址是北京或者上海,这样的人的工资上调15%
      update customers set c_salary=c_salary*1.15 where c_age >= 25 and c_city in ("Beijing","Shanghai");

    5. 把customers表中,城市为北京的顾客,按照工资降序排列,并且只返回结果中的第一条记录
      select * from customers
      where c_city='Beijing'
      order by c_salary desc limit 1;

    6. 选择工资c_salary最少的顾客的信息
      select * from customers 
      where c_salary = (select min(c_salary) from customers);

    7. 找到工资大于5000的顾客都买过哪些产品的记录明细
      select * from orders where o_id in (select c_id from customers where c_salary > 5000);

    8. 删除外键限制
      1、show create table orders;
      2、alter table orders drop foreign key orders_ibfk_1;
       

    9. 删除customers主键限制

      1. 删除自增长属性
        alter table customers modify c_id int;

      2. 删除主键限制
        alter table customers drop primary key;

    10. 增加customers主键限制c_id
      alter table customers add primary key(c_id);

猜你喜欢

转载自blog.csdn.net/qq_42584444/article/details/81352450
今日推荐