• mysql入门与进阶


    MySQL入门与进阶

    需求:对一张表中的数据进行增删改查操作(CURD)
      C:create 创建
      U:update 修改
      R:read 读|检索 查询
      D:delete 删除
    涉及技术:数据库

    1、数据库认知

    1.1、数据库
      本质上就是一个文件系统.通过标准的sql对数据进行curd操作
    安装数据库管理系统:数据库管理系统就是一个软件,与安装其他软件操作一样,但是需要进行配置,具体步骤略

    1.2、常见的关系型数据库
      关系型数据库:存放实体与实体之间的关系的数据库(就是二维表)
        实体:用户 订单 商品
        关系:用户拥有订单  订单包含商品


      非关系型数据库:存放的是对象(redis) NO-sql(not only sql)

    常见数据库及对应特点
      软件名                  厂商                                特点
      mysql                   oracle                        开源mian的数据库
      oracle                  oracle                        大型的收费的数据库
      DB2                      IBM                          大型的收费的数据库
      sqlserver                微软                          中大型的收费的数据库
      sybase                  sybase                          (powerdesigner)

    MYSQL :开源免费的数据库,小型的数据库.已经被Oracle收购了.MySQL6.x版本也开始收费.
    
    Oracle :收费的大型数据库.Oracle公司的产品.Oracle收购SUN公司,收购MYSQL.
    
    DB2 :IBM公司的数据库产品,收费的.银行系统中.
    
    SQLServer:MS公司.收费的中型的数据库.
    
    SyBase :已经淡出历史舞台.提供了一个非常专业数据建模的工具PowerDesigner.
    
    SQLite : 嵌入式的小型数据库,应用在手机端.
    
    Java相关的数据库:MYSQL,Oracle

    安装了数据库管理系统的计算机称之为数据库服务器
    服务器:给别人提供提供服务器(软件服务器)
    我们可以通过标准的sql在服务器创建数据库(database),有了数据库之后,就可以在数据库上创建表了,有了表之后,就可以在里面存放数据了.

    SQL:结构化查询语句
    作用:管理数据库.
    
    sql的分类:
        DDL:数据定义语言
            操作对象:数据库和表
            关键词:create alter drop
        DML:数据操作语言
            操作对象:记录
         关键词:insert,delete,update DQL:数据查询语言(非官方)
         关键词:select DCL:数据控制语言 操作对象:用户 事务 权限
        关键词:if,grant

    2、DDL数据定义语言

    2.1 mysql数据库的登录

    命令:mysql -u root  -p    (即:mysql -u 数据库用户名 -p)

    2.2 DDL数据定义语言

      操作对象:数据库、表

      关键词:create alter drop

    2.3数据库的CRUD操作

    2.3.1创建数据库

    语法:
        * create database 数据库名;
        * create database 数据库名 character set 字符集;
        * create database 数据库名 character set 字符集 collate 校对规则;

    2.3.2查看数据库

    * 查看数据库服务器中的所有的数据库:show databases;
    * 查看某个数据库的定义的信息:show create database 数据库名;

    2.3.3删除数据库

    * drop database 数据库名称;

    此前有hejh3这个数据库,对其进行删除,执行结果如下:

    2.3.4修改数据库

    * alter database 数据库名 character set 字符集 collate 校对规则;

    2.3.5其他命令操作数据库

    * 切换数据库:use 数据库名;
    * 查看正在使用的数据库:select database();

    切换到hejh1数据库:

      

     查看当前使用的数据库:

    2.4数据库中表的CRUD操作

     2.4.1创建表

    create table 表名(
       字段名 类型(长度) 约束,
       字段名 类型(长度) 约束
    );

    java和mysql类型对比   Java MYSQL   
    int int   float float   double double   char/String char/varchar(char固定长度字符串,varchar可变长度的字符串)   Date date,time,datetime,timestamp   文件类型 BLOB、TEXT TEXT指的是文本文件 BLOB二进制文件
    *
    Oracle的文件类型:BLOB CLOB 约束:   单表约束:    * 主键约束:primary key    * 唯一约束:unique    * 非空约束:not null 创建一个分类表: 分类ID int类型 主键 自动增长 分类名称 字符串类型 长度20 create table category( cid int primary key auto_increment, cname varchar(20) ); ***** 注意:建表之前一定先选择数据库.

    例如,创建user表,

    create table user(
        id int primary key auto_increment,
        username varchar(20)
    );

    例如,创建user1表,

    create table user1(
        id int primary key auto_increment,
        username varchar(20)
    );

     

    2.4.2查看表

    查看数据库中的所有表:show tables;
    查看表结构:desc 表名;

    基于2.4.1创建的2张表,用show tables命令查看当前数据库hejh1下所有的表,

    查看表结构:desc 表名;

     

    2.4.3删除表

    drop table 表名;

    hejh1数据库中有,user、user1  2张表,删除user1表,drop table user1;

     

    truncate 清空表 ★
        格式:
            truncate 表名; 干掉表,重新创建一张空表
    和delete from 区别:   delete属于DML语句,数据可以回滚 truncate属于DDL语句    delete逐条删除 truncate干掉表,重新创建一张空表   
    auto_increment 自增
        要求:
            1.被修饰的字段类型支持自增. 一般int
            2.被修饰的字段必须是一个key 一般是primary key
      create table ai01(
            id varchar(10) auto_increment
        );-- 错误 Incorrect column specifier for column 'id'  

     create table ai01(
            id int auto_increment
        );-- 错误 Incorrect table definition; there can be only one auto column and it must be defined as a key

     

     2.4.4修改表

    格式:  alter table 表名 ....

    hejh1数据库中,修改user表名为user11,命令如下:
    修改表名:  alter table 旧表名 rename to 新表名;
    例如:  alter table user rename to user11;

    user表中增加password字段(列)

    添加字段:  alter table 表名 add [column] 字段描述;
    例如:  alter table user add password varchar(20);

     

     将字段password名字改为pwd,命令如下:

    改字段名:  alter table 表名 change 字段名称 新字段描述;
    例如:  alter table user change password pwd varchar(22);

     

    将pwd字段的类型从varchar改为int类型,命令如下:

    修改字段描述:  alter table 表名 modify 字段名称 字段类型 [约束];
    例如:  alter table user modify pwd int [not null];

     

    删除字段pwd,命令如下:

    删除字段:  alter table 表名 drop 字段名;
    例如:alter table user drop pwd;

     

    2.4.5常用命令

      切换或者进入数据库: use 数据库名称;

      

      查看当前数据库下所有表: show tables;

      

      查看表结构:desc 表名;

      

      查看建表语句:show create table 表名;

       

    3.DML数据操作语言

    操作对象:记录(行)
    关键词:insert update delete

     

    3.1insert插入数据

    语法:
    * insert into 表(列名1,列名2,列名3..)  values(值1,值2,值3..); -- 向表中插入某些列
    * insert into 表  values(值1,值2,值3..); --向表中插入所有列
    
    注意:
    * 1.列名数与values后面的值的个数相等
    * 2.列的顺序与插入的值得顺序一致
    * 3.列名的类型与插入的值要一致.
    * 4.插入值得时候不能超过最大长度.
    * 5.值如果是字符串或者日期需要加’’.
    
    cmd下插入中文的乱码的解决:
    * 修改mysql.ini文件.
        * 将[mysql]下面的字符集改为gbk
        * 重启mysql服务.services.msc
    插入:
        格式1:  insert into 表名 values(字段值1,字段值2...,字段值n);
        注意:
            默认插入全部字段,必须保证values后面的内容的类型、顺序和表结构中的一致,若字段类型为数字,可以省略引号

    例如:
      insert into user values(1,'hejh');
      insert into user values('2','swy');
      insert into user values('5');-- 错误的

     

    格式2:  insert into 表名(字段名,字段名1...) values(字段值,字段值1...);
    注意:  插入指定的字段,必须保证values后面的内容的类型、顺序和表名后面的字段的类型和顺序保持一致.
               
     例如:
          insert into user (username,id) values('hh',4);
          insert into user (username) values('jack',5);-- 错误的

     

    查看数据插入是否成功

     

     3.2 update数据修改

    格式: update 表名 set 字段名=字段值,字段名1=字段值1... [where 条件];
    例如: update user set username
    ='hejh1' where username='hh';

    注意:

      * 1.列名的类型与修改的值要一致.

      * 2.修改值得时候不能超过最大长度.

      * 3.值如果是字符串或者日期需要加’’.

    3.3 delete数据修改

    格式:  delete from 表名 [where 条件];
    例如:  delete from user where id = '4';

     

    面试:删除表中所有记录使用delete from 表名; 还是用truncate table 表名?

    * 删除方式:delete 一条一条删除. 而truncate 直接将表删除,重新建表.
    * 事务控制DML。delete属于DML,如果在一个事务中,delete数据,这些数据可以找回;truncate删除的数据找不回来。

     

     4.DQL数据查询语言

     关键词:select

    格式:
         select ... from 表名 where 条件 group by 分组字段 having 条件 order by 排序字段 ase|desc
       或
    select [distinct]*[列名,列名] from 表 [where 条件]

     4.1初始化测试环境

    建表:

    创建商品表
    create table products(
        pid int primary key auto_increment,
        pname varchar(20),
        price double,
        pnum int,
        cno int,
        pdate timestamp
    );

     

    插入数据:

    insert into products values (null,'泰国大榴莲',98,12,1,null);
    insert into products values (null,'新疆大枣',38,123,1,null);
    insert into products values (null,'新疆切糕',68,50,2,null);
    insert into products values (null,'十三香',10,200,3,null);
    insert into products values (null,'老干妈',20,180,3,null);
    insert into products values (null,'豌豆黄',20,120,2,null);

    4.2简单查询练习
      1.查询所有的商品
        select * from products;

        

      

      2.查询商品名和商品价格.
        -- 查看指定的字段
        -- 格式: select 字段名1,字段名2 from 表名
        select pname,price from products;

        

      

      3.查询所有商品都有那些价格.
        -- 去重操作 distinct
        -- 格式: select distinct 字段名,字段名2 from 表名
        select price from products;

        

        select distinct price from products;

        

      

      4.将所有商品的价格+10元进行显示.(别名)
        -- 可以在查询的结果之上进行运算,不影响数据库中的值
        -- 给列起别名 格式: 字段名 [as] 别名
        select price+10 from products;

        

        select price+10 新价格 from products;

        

        select price+10 '新价格' from products;

        

        select price+10 新 价 格 from products;-- 错误

        

        select price+10 '新 价 格' from products;

        

        select price+10 `新 价 格` from products;--错误,中文单引号

         

    4.3条件查询练习

      1.查询商品名称为十三香的商品所有信息:

      select * from products where pname='十三香';

      

     

     

      2.查询商品价格>60元的所有的商品信息:

      select * from products where price>60;

      

     

     

      3.查询商品名称中包含”新”的商品

    -- 模糊匹配 
        --    格式: 字段名 like "匹配规则";
        --    匹配内容 %
                "龙"    值为龙
                "%龙"    值以"龙"结尾
                "龙%"    值以"龙"开头
                "%龙%"     值包含"龙"
        --    匹配个数 "__" 占两个位置

     

      select * from products where pname like '%新%';

      

     

     

      4.查询价格为38,68,98的商品

      select * from products where price=38 or price=68 or price=98;

       

      select * from products where price in(38,68,98);

       

    where后的条件写法:
         * > ,<,=,>=,<=,<>,!=
    * like 使用占位符 _ 和 % _代表一个字符 %代表任意个字符. * select * from product where pname like '%新%';
    * in在某个范围中获得值. * select * from product where pid in (2,5,8);
    * between 较小值 and 较大值 select * from products where price between 50 and 70;

    4.4排序查询

      1.查询所有的商品,按价格进行排序.(asc-升序,desc-降序)

      select * from products order by price asc;

      

      select * from products order by price desc;

       

      2.查询名称有新的商品的信息并且按价格降序排序.

       select * from products where pname like '%新%' order by price desc;

       

      3.查询所有商品的信息并且按价格降序、数量升序排列.

       select * from products order by price desc,pnum asc;

       

     4.5聚合函数

    聚合函数:  对一列进行计算 返回值是一个,忽略null值
        * sum(),avg(),max(),min(),count();

      1.获得所有商品的价格的总和:

      select sum(price) from products;

      

      2.获得商品表中价格的平均数:

      select avg(price) from products;

      

    -- round(值,保留小数位)

       select  round(avg(price),3) from products ;

      

      3.获得商品表中有多少条记录:

       select count(*) from products;

       

      

      4.获得商品表中最高的价格:

      select  max(price) from products ;

      

      5.获得商品表中价格最小的商品信息:

       select min(price) from products ;

       

    4.6 group by分组 

      1.根据cno字段分组,分组后统计商品的个数.
        select cno,count(*) from products group by cno;

        

      2.根据cno分组,分组统计每组商品的总数量,并且总数量> 200;
        select cno,sum(pnum) from products group by cno having sum(pnum)>200;

      

    注意:
    where和having区别:
        1.where 是对分组前的数据进行过滤 ;having 是对分组后的数据进行过滤 
        2.where 后面不能使用聚合函数,having可以

     4.7数据类型

    java              mysql        
    byte              tinyint            
    short              smallint
    int                  int(★)
    long              bigint
    char/String          varchar(★)|char
                            varchar:可变长度 mysql的方言  varchar(20):  存放abc 只会占用三个
                            char:固定长度 char(20) 存放abc 占用20个
    boolean    tinyint|int 代替 float|double    float|double    注意:    double(5,2):该小数长度为5个,小数占2个 最大值:999.99 java.sql.Date    date 日期 java.sql.Time    time 时间 java.sql.Timestamp    timestamp(★) 时间戳 若给定值为null,数据库会把当前的系统时间存放到数据库中    datetime(★) 日期+时间 java.sql.Clob(长文本)    mysql的方言(text) java.sql.Blob(二进制)    blob

     5 约束

    约束作用:
      为了保证数据的有效性和完整性。
    常用约束:

      mysql常用约束:主键约束(primary key) 唯一约束(unique) 非空约束(not null) 外键约束(foreign key)

    5.1主键约束

    主键约束:被修饰过的字段唯一非空
            注意:一张表只能有一个主键,这个主键可以包含多个字段
            方式1:建表的同时添加约束 格式: 字段名称 字段类型 primary key
            方式2:建表的同时在约束区域添加约束 
                所有的字段声明完成之后,就是约束区域了
                格式: primary key(字段1,字段2)
        方式3:建表之后,通过修改表结构添加约束

    创建一张表,

    create table pk01(
        id int,
        username varchar(20),
        primary key (id)
    );

    insert into pk01 values(1,'hjh');-- 成功
    insert into pk01 values(2,'ttt');-- 失败 Duplicate entry '2' for key 'PRIMARY'
    insert into pk01 values(null,'tom');-- 失败  Column 'id' cannot be null

     

    再次创建表pk01,

    create table pk01(
        id int primary key,
        username varchar(20),
        primary key (id)
    );-- 错误的 一张表只能有一个主键

     

     方式3:建表之后,通过修改表结构添加约束

    create table pk02(
        id int,
        username varchar(20)
    );

     

    alter table pk02 add primary key(字段名1,字段名2..);
    alter table pk02 add primary key(id,username);

     给表pk02的id和username增加主键约束,所以id和username为联合主键,故id和username都是非空的,如下图

     

     

    插入数据,

    insert into pk02 values(1,'hejh');-- 成功
    insert into pk02 values(1,'hehe');-- 成功
    insert into pk02 values(1,'hehe');-- 失败

     

     5.2 唯一约束

     被修饰过的字段唯一,对null不起作用

    方式1:建表的同时添加约束 格式: 字段名称 字段类型 unique
    方式2:建表的同时在约束区域添加约束 
    方式3:建表之后,通过修改表结构添加约束

    方式1:建表的同时添加约束 格式: 字段名称 字段类型 unique

    create table un(
        id int unique,
        username varchar(20) 
    );

    insert into un value(1,'kk');-- 成功
    insert into un value(1,'ll');-- 错误 Duplicate entry '1' for key 'id'
    insert into un value(null,'oo');-- 成功
    insert into un value(null,'pp');-- 成功

     

    方式2:建表的同时在约束区域添加约束 
        所有的字段声明完成之后,就是约束区域了
        unique(字段1,字段值2...)

     建表un11,给id设置唯一性约束,故id非空,

    create table un11(
        id int ,
        username varchar(20) ,
      unique(id) );

     

    方式3:建表之后,通过修改表结构添加约束

    alter table 表名 add unique(字段1,字段2);-- 添加的联合唯一
    alter table 表名 add unique(字段1);-- 给一个添加唯一
    table 表名 add unique(字段2);-- 给另一个添加唯一
    create table un01(
    	id int,
    	username varchar(20)
    ); 
    

    给id和username设置联合唯一,只有id和username都相同,插入数据时才会报错,如下图

    alter table un01 add unique(id,username);
    insert into un01 values(1,'tom');-- 成功
    insert into un01 values(1,'jack');-- 成功
    insert into un01 values(1,'tom');-- 失败  Duplicate entry '1-tom' for key 'id'

     

    5.3 非空约束

    非空约束(了解)
            特点:被修饰过的字段非空
            方式:
                create table nn(
                    id int not null,
                    username varchar(20) not null
                );     

     

      insert into nn values(null,'tom');--  错误的 Column 'id' cannot be null

     

      

    5.4外键约束

    多个表之间是有关系的,那么关系靠谁来维护?

    多表约束:外键约束.

    alter table products add foreign key (cno) references category(cid);

    1.一对多关系

    客户和订单,分类和商品,部门和员工.
    一对多建表原则:在多的一方创建一个字段,字段作为外键指向一的一方的主键.
    用户和订单    
        -- 创建用户表
        create  table user(
            id int primary key auto_increment,
            username varchar(20)
        );
        
        -- 创建订单表
        create  table orders(
            id int primary key auto_increment,
            totalprice double,
            user_id int
        );

    为了保证数据的有效性和完整性,添加约束(外键约束).

    在多表的一方添加外键约束
        格式:
            alter table 多表名称 add foreign key(外键名称) references 一表名称(主键);
        例如:
            alter table orders add foreign key(user_id) references user(id);

    添加了外键约束之后有如下特点:★
        1.主表中不能删除从表中已引用的数据
        2.从表中不能添加主表中不存在的数据
    开发中处理一对多:
        在多表中添加一个外键,名称一般为主表的名称_id,字段类型一般和主表的主键的类型保持一致,
        为了保证数据的有效性和完整性,在多表的外键上添加外键约束即可.

     2.多对多关系

    学生和课程:
    多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键.
    例子:商品和订单
            -- 创建商品表
        create table product(
            id int primary key auto_increment,
            name varchar(20),
            price double
        );
    
        -- 创建中间表
        create table orderitem(
            oid int,
            pid int
        );

    -- 添加外键约束
        alter table orderitem add foreign key(oid) references orders(id);
        alter table orderitem add foreign key(pid) references product(id);

    开发中处理多对多:
        引入一张中间表,存放两张表的主键,一般会将这两个字段设置为联合主键,这样就可以将多对多的关系拆分成两个一对多了;
      为了保证数据的有效性和完整性,需要在中间表上添加两个外键约束即可.

    3.一对一关系

    在实际的开发中应用不多.因为一对一可以创建成一张表.
    
    两种建表原则: 唯一外键对应:假设一对一是一个一对多的关系,在多的一方创建一个外键指向一的一方的主键,将外键设置为unique. 主键对应:让一对一的双方的主键进行建立关系.

     6.多表查询

    建表与初始化数据

    ###创建分类表
    create table category(
      cid varchar(32) PRIMARY KEY ,
      cname varchar(100)        #分类名称
    );

     

    # 商品表
    CREATE TABLE products (
      pid varchar(32) PRIMARY KEY  ,
      name VARCHAR(40) ,
      price DOUBLE 
    );

     

    #添加外键字段
    alter table products add column category_id varchar(32);

     

    #添加约束
    alter table products add constraint product_fk foreign key (category_id) references category (cid);
    添加外键约束:
    
      alter table 从表 add constraint [外键名称字段]_fk foreign key(从表外键字段) references 主表(主表主键字段);
    
      [外键名称] 用于删除外键约束,一般以_fk结尾   alter table 从表drop foreign key [外键名称] 主要作用:保障数据的完整性. 不删除从表内容,主表不能删除.(因为在从表中有外键关联主表id,删除的时候只能先删除从表,后删主表,
                                          可以理解为:删除从表,释放主表id,之后才能删除主表)

     

    ### 订单表
    create table orders(
      oid varchar(32) PRIMARY KEY ,
      totalprice double     #总计
    );

     

    ### 订单项表
    create table orderitem(
      oid varchar(50),-- 订单id
      pid varchar(50)-- 商品id
    );

    ### 联合主键(可省略)
    alter table orderitem add primary key (oid,pid);

     

    ###---- 订单表和订单项表的主外键关系
    alter table orderitem add constraint orderitem_orders_fk foreign key (oid) references orders(oid);

     

    ###---- 商品表和订单项表的主外键关系
    alter table orderitem add constraint orderitem_product_fk foreign key (pid) references products(pid);

     

    -- 给分类表初始化数据
    insert into category values('c001','电器');
    insert into category values('c002','服饰');
    insert into category values('c003','化妆品');
    insert into category values('c004','书籍');

    -- 给商品表初始化数据
    insert into products(pid,name,price,category_id) values('p001','联想',5000,'c001');
    insert into products(pid,name,price,category_id) values('p002','海尔',3000,'c001');
    insert into products(pid,name,price,category_id) values('p003','雷神',5000,'c001');
    insert into products(pid,name,price,category_id) values('p004','JACK JONES',800,'c002');
    insert into products(pid,name,price,category_id) values('p005','真维斯',200,'c002');
    insert into products(pid,name,price,category_id) values('p006','花花公子',440,'c002');
    insert into products(pid,name,price,category_id) values('p007','劲霸',2000,'c002');
    insert into products(pid,name,price,category_id) values('p008','香奈儿',800,'c003');
    insert into products(pid,name,price,category_id) values('p009','相宜本草',200,'c003');
    insert into products(pid,name,price,category_id) values('p010','梅明子',200,null);
    

     

    6.1内连接

    内连接查询(使用的关键字 inner join  -- inner可以省略)

      格式1:显式的内连接
            select a.*,b.* from a [inner] join b on ab的连接条件
      格式2:隐式的内连接
            select a.*,b.* from a,b where ab的连接条件

    建表与初始化

    -- 用户表(user) 
      create table user (                                  
              id int auto_increment primary key,                
              username varchar(50)  -- 用户姓名                                                
         );

     

    -- 订单表(order)
      create table order1 (                                                  
              id int  auto_increment primary key,                                  
              price double,                                           
              user_id int                                       
      );

    -- 给订单表添加外键约束
    alter table orders add constraint user_fk foreign key (user_id) references user(id);

     

    -- 向user表中添加数据
        insert into user values(1,'张三');
        insert into user values(2,'李四');
        insert into user values(3,'王五');
        insert into user values(4,'赵六');

     

    -- 向order1 表中插入数据
        insert into order1 values(1,1314,3);
        insert into order1 values(2,1314,3);
        insert into order1 values(3,15,4);
        insert into order1 values(4,315,null);
        insert into order1 values(5,1014,null);

     

    示例如下:查询用户的订单,没有订单的用户不显示

    隐式内连接:
        select user.*,order1.* from user ,order1 where user.id=order1.user_id;
     显示内连接
        select user.*,order1.* from user join order1 on user.id=order1.user_id;

     

     

     6.2外连接

    外连接查询(使用的关键字 outer join -- outer可以省略)

    左外连接:left outer join
        select a.*,b.* from a left [outer] join b on 连接条件;
        意思:
            先展示join左边的(a)表的所有数据,根据条件关联查询 join右边的表(b),符合条件则展示出来,不符合以null值展示.
    
    右外连接:right outer join
        select a.*,b.* from b right [outer] join a on 连接条件;
        意思:
            先展示jion右边的表(a)表的所有数据,根据条件关联查询join左边的表(b),符合条件则展示出来,不符合以null值展示.

    查询所有用户的订单详情

    左外连接: user在左
    select user.*,order1.* from user left join order1 on user.id=order1.user_id;

     

    查询所有订单的用户详情

    右外连接:orders 在右
    select order1.*,user.* from user right join order1 on user.id=order1.user_id;

     

     6.3子查询

    子查询:
        一个查询依赖另一个查询,即当一个查询是另一个查询的条件时,称之为子查询
    例如:select user.*,tmp.* from user,(select * from orders where price>300) as tmp where user.id=tmp.user_id;

    查看用户为张三的订单详情

    1.先查询张三的id
        select id from User where username = '张三';// 3
    2.select * from orders where user_id = ?;
            
    两个合二为一
    select * from order1 where user_id = (select id from User where username = '张三');

    查询出订单的价格大于300的所有用户信息。

    1.先查询出订单价格>300的用户的id
        select user_id from orders where price >300;//(3,3,5,null)
    2.select * from user where id in(3,3,5,null);
            
    两个合二为一:
    select * from user where id in(select user_id from order1 where price >300);

    查询订单价格大于300的订单信息及相关用户的信息。
    内连接:
            select order1.*,user.* from order1,user where user.id=order1.user_id  and orders.price>300 ;

     

     6.4分页查询

    分页查询每个数据库的语句是不通用的.
    MYSQL:使用limit的关键字.
    * select * from product limit a,b;  --a:从哪开始,b:查询多少条.
    Oracle:使用SQL语句嵌套. SQLServer:使用top的关键字.

    7.事务管理

    7.1什么是事务管理

    ​事务是恢复和并发控制的基本单位。

      可以把一系列要执行的操作称为事务,而事务管理就是管理这些操作要么完全执行,要么完全不执行(很经典的一个例子是:A要给B转钱,首先A的钱减少了,但是突然的数据库断电了,导致无法给B加钱,然后由于丢失数据,B不承认收到A的钱;在这里事务就是确保加钱和减钱两个都完全执行或完全不执行)

    事务管理的意义:保证数据操作的完整性

    事务有四个特性(ACID):

      原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability)

    • 原子性:事务是应用中最小的执行单位,就如原子是自然界最小颗粒,具有不可再分的特征一样。事务是应用中不可再分的最小逻辑执行体,一组事务,要么成功;要么撤回。
    • 一致性:事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态。当数据库中只包含事务成功提交的结果时,数据库处于一致性状态。一致性是通过原子性来保证的。有非法数据(外键约束之类),事务撤回。。
    • 隔离性:各个事务的执行互不干扰,任意一个事务的内部操作对其他并发事务都是隔离的。即:并发执行事务之间不能看到对方的中间状态,并发执行的事务之间不能相互影响。事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。
    • 持久性:事务一旦提交,对数据所做的任何改变,都要记录到永久存储器中,通常是保存进物理数据库。软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改

    事务管理操作命令:

    • 开启事务管理:开启之后,下面的sql语句并不会马上执行并把结果写到表中,而是会写到事务日志中。
      • start transaction;
    • 回退操作:回退会清掉开始事务管理之后写到事务日志中的内容,即恢复到开启事务管理之前。
      • 语法:rollback;
      • 注意:回退操作只是回退"写"的内容,对于普通的读表select语句不能回退。
    • 事务提交:将sql语句的结果写到数据表中。
      • 语法:commit:

    建表与初始化数据:

    create table bank(
      bid int primary key auto_increment,
      bname varchar(20),
      money int
    );
    insert into bank values(null,'hejh',100);
    insert into bank values(null,'swy',100);

     开启事务:start transaction

      在执行start transaction之后,执行的一系列操作,是先写在相关日志里的,命令执行下去实际数据库并没有生效;一旦执行commit命令,start transaction命令和commit之间执行的开始生效,即数据库数据已经被修改提交。

     

    money被修改了。

      在执行commit命令之前,如果执行了rollback命令,则start transaction命令  到 rollback命令  之间执行的命令不会生效,数据回滚到start transaction命令执行之前的数据。

    注意:

    • 当 commit 或 rollback 语句执行后,事务会自动关闭。
    • 锁机制:在事务操作一个表时,如果使用索引来取值,那么会锁定到对应行;如果没有使用索引来取值,那么会锁定整个表。锁定之后其他连接无法操作指定行或表。

     

     7.2回滚点

     回滚点就是为了准确的回滚到某个操作之前,可以指定rollback回退的位置。

    语法:

    • 创建回滚点:savepoint 回滚点名;
    • 回滚到回滚点:rollback to 回滚点名;

    注意:回滚点在事务管理关闭(rollback或commit之后)之后失效,不要在事务之外使用回滚点。

    1)执行start transaction;开启事务

    start transaction;

    2)接着插入2条数据

    insert into bank values(null,'hh',333);
    insert into bank values(null,'ss',444);

    3)执行设置回滚点。在修改数据之前设置一个回滚点

     savepoint before_update;

     

    4)修改2条记录

    update bank set money=money-100 where name='hejh';
    update bank set money=money+100 where name='swy';

    此时查询表中数据如下图:

    5)一旦执行回滚命令,回滚到修改数据之前,数据表中数据显示如下图:

     rollback to before_update;

    7.3默认事务管理

    默认情况下,mysql的事务管理是关闭(自动事务)的,语句的结果会马上写到数据表中。
      可以通过select @@autocommit;来查看是否开启自动事务,值为1为自动事务已开启,为0则为关闭。
    关闭自动事务:set autocommit
    =0
    ;【关闭后需要commit来执行每一条语句,相当于开始了事务管理】
    不过注意的是set autocommit针对的是会话变量,所以这个设置只在此次会话连接中生效。

    敲入quit断开此次连接,然后再次连接,值为1:

    8.序列

    ① mysql的自增长“序列”和序列是两回事,mysql本身不提供序列机制,只有一个auto_increment自增长字段

    ②mysql的auto_increment可以设置起始值,但是不能设置步长,其固定步长是1

    ③mysql一个表只能有一个自增长字段。自增长只能被分配给固定表的固定的某一字段,不能被多个表共用,并且只能是数字型

    1.创建序列表sequence

    create  table sequence (
       name varchar(50) collate utf8_bin not null comment ,
       current_value int(11) not null comment ,
       increment int(11) not null default 1 comment, // 序列的自增值
     primary key(name)
    )
    engine=InnoDB default charset=utf8 collate=utf8_bin;

     2.创建函数--取当前值

    begin
      declare value integer;
      set value=0;
      select current_value into value
        from sequence
        where name = seq_name;
      return value;
    end

     3.创建函数--取下一个值

    drop function if exists nextval;
    delimiter $ create function nextval (seq_name varchar(50))    returns integer
    language SQL deterministic contains SQl SQL security definer comment '' begin    update sequence    set current_value = current_values + increment where name = seq_name; return currval(seq_name);
    end $
    delimiter

     4.创建函数--更新当前值

    drop function id exists setval;
    delimiter $ create function setval (seq_name varchar(50),value integer)    returns integer
    language SQL deterministic contains SQL SQL security definer comment '' begin update sequence    set current_value = value where name = seq_name; return currval(seq_name);
    end $ delimiter;

    5.测试序列

    insert into sequence values('testSeq',0,1);--添加一个sequence名称和初始值,以及自增幅度
    select setval('testSeq',10);--设置指定sequence的初始值
    select currval('testSeq');--查询指定sequence的当前值
    select nextval('testSeq');--查询指定squence的下一个值

    9.视图

     9.1什么是视图

    视图(view):是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。

      通过视图,可以展现基表(创建视图的表base table)的部分数据;视图数据来自定义视图的查询中使用的表,使用视图动态生成。

     

    9.2视图的特点

    视图是对若干张基本表的引用,是一张虚表,是查询语句执行的结果,不存储具体的数据(基本表数据发生了改变,视图也会跟着改变);

    可以跟基本表一样,进行增删改查操作(ps:增删改操作有条件限制);

     

    视图的优点:

      ①简单:使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤好的复合条件的结果集。

      ②安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行某个列,但是通过视图就可以简单的实现。

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

    视图使用场景: 

      ①权限控制的时候,不希望用户访问表中某些含敏感信息的列,比如salary...

      ②关键信息来源于多个复杂关联表,可以创建视图提取我们需要的信息,简化操作;

    9.2示例

    建表和数据初始化:用户(user)、课程(course)、用户课程中间表(user_course)

    drop table if exists course;
    create table course(
      id bigint(20) not null auto_increment,
      name varchar(20) not null,
      descroption varchar(200) not null,
      primary key(id)
    ) engine=InnoDB auto_increment=4 default charset=utf8;//从4开始自增
    insert into course values(null,'java','java从入门到精通');
    insert into course values(null,'javascript','javascript进阶');
    insert into course values(null,'vue','vue从入门到进阶');

    drop table if exists user;
    create table user(
      id int(20) not null auto_increment,
      account varchar(200) not null,
      name varchar(20) not null,
      address varchar(200) default null,
      primary key(id)
    ) engine=InnoDB auto_increment=1 default charset=utf8;
    insert into user values(null,'user1','hjh','中国上海');
    insert into user values(null,'user2','swy','中国广州');
    insert into user values(null,'user1','qyd','中国南昌');

     

    drop table if exists user_course;
    create table user_course(
      id int(20) not null auto_increment,
      userid int(20) not null,
      courseid int(20) not null,
      primary key(id)
    ) engine=InnoDB auto_increment=1 default charset=utf8;
    user的id是从1开始到3,course的id是从4到6,所以插入的时候数据是以下样式的:
    insert into user_course values(null,1,4);
    insert into user_course values(2,1,5);
    insert into user_course values(3,2,3);
    insert into user_course values(4,2,4);
    insert into user_course values(5,2,5);
    insert into user_course values(6,3,4);

     

     创建视图view_user_course

    drop view if exists view_user_course;
    create view view_user_course as (
      select uc.id as id,u.name as username,c.name as coursename
      from (
        (
          user u left join user_course uc on ((u.id = uc.userid))
        )
          left join course c on ((uc.courseid = c.id))
     )
    );

    查询hejh用户上的所以课程相关信息(hejh用户不存在,所以查询结果是empty)

     

     

    查询hjh用户上的所以课程相关信息(初始化数据时插入过一个用户名为hjh的用户,所以查询结果不为empty)

     多张表建立起来的视图中,不能做同时修改2张以上表数据的操作,会报错:

     可参考博文https://www.cnblogs.com/geaozhang/p/6792369.html#chuangjianshitu

    9.3视图的修改

      基本格式:create or replace view view_name as select语句;

    在视图存在的情况下可对视图进行修改,视图不在的情况下可创建视图

    9.4drop删除视图

      删除视图是指删除数据库中已存在的视图,删除视图时,只能删除视图的定义,不会删除数据,即不动基表。

    DROP VIEW [IF EXISTS]   
    view_name [, view_name] ...

    使用IF EXISTS选项使得删除不存在的视图时不抛出异常

    10.索引

    10.1索引的分类

      索引分单列索引(主键索引,唯一索引,普通索引)和组合索引。

        单列索引:即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引

        组合索引:即一个索引包含多个列

    创建索引时,需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

    索引的优点

      MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度(在数据量很大的时候,效果更明显)。

    索引的缺点

      虽然索引大大提高了查询速度,但是同时也会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE操作。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。

    10.2普通索引

    创建索引

      最基本的索引,没有限制,创建方式如下:

    create index 索引名 on  表名(字段(字段长度));
    如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length

    通过修改表结构来添加索引:

    alter table 表名 add index 索引名(字段名);

    建表时直接指定索引:

    create table 名(
       字段 数据类型 约束, 字段 数据类型 约束, index [索引名] (字段(字段长度)) );

    删除索引:

    drop index 索引名 on 表名

    10.3 唯一索引

    与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:

      直接创建唯一索引:

    create unique index 索引名 on 表名(字段(字段长度))

      修改表结构创建唯一索引:

    alter table 表名 add unique [索引名](字段名(字段长度))

      创建表的时候直接指定唯一索引:

    create table 表名(
      字段1 数据类型 约束,
      字段2 数据类型 约束,
      ......
      unique [索引名] (字段名(字段长度))

    使用ALTER 命令添加和删除索引:

    有四种方式来添加数据表的索引:
    ①alter table 表名 add primary key(字段列表);//添加一个主键,这意味着索引值必须是唯一的,且不能为NULL
    ②alter table 表名 add unique 索引名(字段列表);//创建索引的值必须是唯一的(输了Null外,null可能会出现很多次)
    ③alter table 表名 add index 索引名 (字段列表);//添加普通索引,索引值可以出现多次
    ④alter table 表名 add fulltext 索引名(字段列表);//指定索引为fulltext,用于全文索引

    ALTER 命令中使用 DROP 子句来删除索引。尝试以下实例删除索引:

    alter table 表名 drop index 索引名;

    使用 ALTER 命令添加和删除主键

    主键只能作用于一个列上,添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下

    alter table 表名 modify 字段 数据类型 约束;
    alter table 表名 add primary key(字段名);

    也可以使用 ALTER 命令删除主键:

    alter table 表名 drop primary key;

    删除主键时只需指定PRIMARY KEY,但在删除索引时,必须知道索引名。

    显示索引信息:show index

    使用 SHOW INDEX 命令列出表中的相关索引信息。可以通过添加 G 来格式化输出信息。

    尝试以下实例:

    show index from 表名; G

    参见博文:细说mysql索引   https://www.cnblogs.com/chenshishuo/p/5030029.html

  • 相关阅读:
    EVM靶机渗透
    Joomla漏洞复现
    渗透测试
    Kali软件库认识
    谷歌hack语法
    Metasploit学习
    sqli-labs less-17
    sqli-labs(less-11-16)
    sqli-labs (less-8-less-10)
    less-7
  • 原文地址:https://www.cnblogs.com/hejh/p/10721993.html
Copyright © 2020-2023  润新知