zoukankan      html  css  js  c++  java
  • 数据库

    数据库服务器:运行数据库管理软件

    数据库管理软件:管理-数据库  (mysql)

    数据库:即文件夹,用来组织文件/表

    表:即文件,用来存放多行内容/多条记录

    数据库命名规则:

    可以由字母、数字、下划线、@、#、$
    区分大小写
    唯一性
    不能使用关键字如 create select
    不能单独使用数字
    最长128位

    show create table t1G; #查看表详细结构,可加G

    修改表结构

    语法:
    1. 修改表名
          ALTER TABLE 表名 
                              RENAME 新表名;
    
    2. 增加字段
          ALTER TABLE 表名
                              ADD 字段名  数据类型 [完整性约束条件…],
                              ADD 字段名  数据类型 [完整性约束条件…];
          ALTER TABLE 表名
                              ADD 字段名  数据类型 [完整性约束条件…]  FIRST;
          ALTER TABLE 表名
                              ADD 字段名  数据类型 [完整性约束条件…]  AFTER 字段名;
    
    3. 删除字段
          ALTER TABLE 表名 
                              DROP 字段名;
    
    4. 修改字段
          ALTER TABLE 表名 
                              MODIFY  字段名 数据类型 [完整性约束条件…];
          ALTER TABLE 表名 
                              CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
          ALTER TABLE 表名 
                              CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];
    1. 修改存储引擎
    mysql> alter table service 
        -> engine=innodb;
    
    2. 添加字段
    mysql> alter table student10
        -> add name varchar(20) not null,
        -> add age int(3) not null default 22;
    
    mysql> alter table student10
        -> add stu_num varchar(10) not null after name;                //添加name字段之后
    
    mysql> alter table student10                        
        -> add sex enum('male','female') default 'male' first;          //添加到最前面
    
    3. 删除字段
    mysql> alter table student10
        -> drop sex;
    
    mysql> alter table service
        -> drop mac;
    
    4. 修改字段类型modify
    mysql> alter table student10
        -> modify age int(3);
    mysql> alter table student10
        -> modify id int(11) not null primary key auto_increment;    //修改为主键
    
    5. 增加约束(针对已有的主键增加auto_increment)
    mysql> alter table student10 modify id int(11) not null primary key auto_increment;
    ERROR 1068 (42000): Multiple primary key defined
    
    mysql> alter table student10 modify id int(11) not null auto_increment;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    6. 对已经存在的表增加复合主键
    mysql> alter table service2
        -> add primary key(host_ip,port);        
    
    7. 增加主键
    mysql> alter table student1
        -> modify name varchar(10) not null primary key;
    
    8. 增加主键和自动增长
    mysql> alter table student1
        -> modify id int not null primary key auto_increment;
    
    9. 删除主键
    a. 删除自增约束
    mysql> alter table student10 modify id int(11) not null; 
    
    b. 删除主键
    mysql> alter table student10                                 
        -> drop primary key;
    示例

    复制表

    复制表结构+记录 (key不会复制: 主键、外键和索引)
    mysql> create table new_service select * from service;
    
    只复制表结构
    mysql> select * from service where 1=2;        //条件为假,查不到任何记录
    Empty set (0.00 sec)
    mysql> create table new1_service select * from service where 1=2;  
    Query OK, 0 rows affected (0.00 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> create table t4 like employees;
    View Code

    字符串类型

    #常用字符串系列:char与varchar
    注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡
    
    #其他字符串系列(效率:char>varchar>text)
    TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
    BLOB 系列    TINYBLOB BLOB MEDIUMBLOB LONGBLOB 
    BINARY系列 BINARY VARBINARY
    
    text:text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。
    mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
    longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
    View Code

    枚举类型和集合类型

    enum 单选 只能在给定的范围内选一个值,如性别 sex 男male/女female

    set 多选 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3...)

    MariaDB [db1]> create table consumer( 
        -> name varchar(50),
        -> sex enum('male','female'),
        -> level enum('vip1','vip2','vip3','vip4','vip5'), #在指定范围内,多选一
        -> hobby set('play','music','read','study') #在指定范围内,多选多
        -> );
    
    MariaDB [db1]> insert into consumer values  
        -> ('egon','male','vip5','read,study'),
        -> ('alex','female','vip1','girl');
    View Code

    查询

    SELECT 字段1,字段2... FROM 表名
                      WHERE 条件
                      GROUP BY field
                      HAVING 筛选
                      ORDER BY field
                      LIMIT 限制条数

    重点中的重点:关键字的执行优先级
    from     找到表
    where    条件(一次过滤)
    group by  分组
    having   过滤(二次过滤)
    select   
    distinct   去重
    order by   排序
    limit    限制条数

    group by 

    单独使用GROUP BY关键字分组
        SELECT post FROM employee GROUP BY post;
        注意:我们按照post字段分组,那么select查询的字段只能是post,想要获取组内的其他相关信息,需要借助函数
    
    GROUP BY关键字和GROUP_CONCAT()函数一起使用
        SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post;#按照岗位分组,并查看组内成员名
        SELECT post,GROUP_CONCAT(name) as emp_members FROM employee GROUP BY post;
    
    GROUP BY与聚合函数一起使用
        select post,count(id) as count from employee group by post;#按照岗位分组,并查看每个组有多少人

    having

    #!!!执行优先级从高到低:where > group by > having 
    #1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。
    
    #2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数

    触发器

    使用触发器可以定制用户对表进行【增、删、改】操作时前后的行为,注意:没有查询

    # 插入前
    CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    
    # 插入后
    CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    
    删除/更新:tri_before_delete_tb1 
                    tri_before_update_tb1
                    DELETE/UPDATE        
    #准备表
    CREATE TABLE cmd (
        id INT PRIMARY KEY auto_increment,
        USER CHAR (32),
        priv CHAR (10),
        cmd CHAR (64),
        sub_time datetime, #提交时间
        success enum ('yes', 'no') #0代表执行失败
    );
    
    CREATE TABLE errlog (
        id INT PRIMARY KEY auto_increment,
        err_cmd CHAR (64),
        err_time datetime
    );
    
    #创建触发器
    delimiter //
    CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
    BEGIN
        IF NEW.success = 'no' THEN #等值判断只有一个等号
                INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必须加分号
          END IF ; #必须加分号
    END//
    delimiter ;
    
    
    #往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
    INSERT INTO cmd (
        USER,
        priv,
        cmd,
        sub_time,
        success
    )
    VALUES
        ('egon','0755','ls -l /etc',NOW(),'yes'),
        ('egon','0755','cat /etc/passwd',NOW(),'no'),
        ('egon','0755','useradd xxx',NOW(),'no'),
        ('egon','0755','ps aux',NOW(),'yes');
    
    
    #查询错误日志,发现有两条
    mysql> select * from errlog;
    +----+-----------------+---------------------+
    | id | err_cmd         | err_time            |
    +----+-----------------+---------------------+
    |  1 | cat /etc/passwd | 2017-09-14 22:18:48 |
    |  2 | useradd xxx     | 2017-09-14 22:18:48 |
    +----+-----------------+---------------------+
    rows in set (0.00 sec)
    
    插入后触发触发器
    示例

    事务

    务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。

    create table user(
    id int primary key auto_increment,
    name char(32),
    balance int
    );
    
    insert into user(name,balance)
    values
    ('wsb',1000),
    ('egon',1000),
    ('ysb',1000);
    
    #原子操作
    start transaction;
    update user set balance=900 where name='wsb'; #买支付100元
    update user set balance=1010 where name='egon'; #中介拿走10元
    update user set balance=1090 where name='ysb'; #卖家拿到90元
    commit;
    
    #出现异常,回滚到初始状态
    start transaction;
    update user set balance=900 where name='wsb'; #买支付100元
    update user set balance=1010 where name='egon'; #中介拿走10元
    uppdate user set balance=1090 where name='ysb'; #卖家拿到90元,出现异常没有拿到
    rollback;
    commit;
    mysql> select * from user;
    +----+------+---------+
    | id | name | balance |
    +----+------+---------+
    |  1 | wsb  |    1000 |
    |  2 | egon |    1000 |
    |  3 | ysb  |    1000 |
    +----+------+---------+
    rows in set (0.00 sec)
    介绍
    #介绍
    delimiter //
                create procedure p4(
                    out status int
                )
                BEGIN
                    1. 声明如果出现异常则执行{
                        set status = 1;
                        rollback;
                    }
    
                    开始事务
                        -- 由秦兵账户减去100
                        -- 方少伟账户加90
                        -- 张根账户加10
                        commit;
                    结束
    
                    set status = 2;
    
    
                END //
                delimiter ;
    
    #实现
    delimiter //
    create PROCEDURE p5(
        OUT p_return_code tinyint
    )
    BEGIN 
        DECLARE exit handler for sqlexception 
        BEGIN 
            -- ERROR 
            set p_return_code = 1; 
            rollback; 
        END; 
    
        DECLARE exit handler for sqlwarning 
        BEGIN 
            -- WARNING 
            set p_return_code = 2; 
            rollback; 
        END; 
    
        START TRANSACTION; 
            DELETE from tb1; #执行失败
            insert into blog(name,sub_time) values('yyy',now());
        COMMIT; 
    
        -- SUCCESS 
        set p_return_code = 0; #0代表执行成功
    
    END //
    delimiter ;
    
    #在mysql中调用存储过程
    set @res=123;
    call p5(@res);
    select @res;
    
    #在python中基于pymysql调用存储过程
    cursor.callproc('p5',(123,))
    print(cursor.fetchall()) #查询select的查询结果
    
    cursor.execute('select @_p5_0;')
    print(cursor.fetchall())
    示例
    '''
    一:基本操作
        1.开始服务
        管理员cmd    net start mysql57
        cmd          mysql -u root -p
    
        2.停止服务
        管理员cmd   net stop 服务名称(mysql57)
    
        3.连接数据
        格式:mysql -u 用户名 -p
        示例:mysql -u root -p
        输入密码(安装时设置)
    
        4.退出登录(断开连接)
        ctrl + z
    
        5.查看版本(连接后执行)
        示例:终端 mysql> select version();
        6.显示当前时间(连接后执行)
        示例:终端 mysql> select now();
    
        7.远程连接(当前未登录)
        格式:(C:>)mysql -h ip地址 -u 用户名
    
    二、数据库操作
        1.创建数据库
        格式:create database  数据库名  charset=utf8;
        e.g.:create database  crt charset=utf8;
    
        2.删除数据库
        格式:drop database  数据库名;
        e.g.:drop database  crt;
    
        3.切换数据库
        格式:use 数据库名;
        e.g.:use crt;
    
        4.查看当前数据库
        select database();
    
    三、表操作
        1.查看数据库中所有表
        show tables;
        2.创建表
        格式:create table 表名(列及类型);
        说明:auto_increment = 自生长
              primary key  =  主键
              not null   =   不为空
              default  =  默认值
        e.g.:create table stu(id    int auto_increment primary key,
                               name  varchar(20) not null,
                               age     int       not null,
                               gender  bit     default 1,
                               address varchar(20),
                               isDelete  bit    default 0);
        level enum('vip1','vip2','vip3'),  枚举类型
        hobbies set('play','music','read','run')  集合类型
    
        3.删除表
        格式:drop table 表明;
        e.g.:drop table ;
    
        4.查看表结构(不要修改表结构)
        格式:desc 表名;
        e.g.:desc stu;
    
        5.查看建表语句
        格式:show createtable 表名;
        e.g.:show create table stu;
    
        6.重命名表名
        格式:rename table 原表名 to 新表名;
        e.g.:rename table stu to studt;
    
        7.修改表
        格式: alter table 表明 addchangedrop 列名 类型;
        e.g.:alter table stu add gender bit default 1;
    
    四、数据操作
        1.增加数据
          a、全列插入
            说明:主键列是自动增长,但在全列插入时需要占位
                    通常使用0,插入后以实际数据为准
            格式:insert into 表名 values(...)
            e.g.:insert into studt values(0,'tom',19,1,'北京',0);
          b、缺省插入
            格式:insert into 表名(列1,列2,...) values(...);
            e.g.:insert into studt(name,age,address) values('ll',16,'上海');
          c、同时插入多条数据
            格式:insert into 表名 values(...),(...),...;
            e.g.:insert into studt values(0,'hh',18,0,'hhh',0),(0,'zz',18,1,'zzz',0);
        2.删
            格式:delete from 表名 where 条件;
            e.g.:delete from studt where id=4;
            如果  <delete from 表名;>  删除所有数据
        3.改(表内数据)
            格式:update 表名 set 列1=值1,列2=值2,... where 条件
            e.g.:update studt set age=100 where id=5;
            如果不指定where,整个列全修改
        4.查
            说明:查询表中全部数据
            格式:select *from 表名;
            e.g.:select *from studt;
    
    五、查  《对于表》
        1.基本语法
            格式:select * from 表名
            说明:
                a、from关键字后边是表名,表示数据来源于该表
                b、select后面写表中的列名,*表示所有列
                c、在select的列名部分,可以使用as为列名起别名
                    这个别名显示在结果集中
                d、如果要查询多个列,之间使用逗号分隔
            e.g.:
                select * from studt;
                select name,age from studt;
                select name as a,age from studt;
        2.消除重复行
            在select后面列的前面使用distinct可消除重复的行
            e.g.:
                select name from studt;
                select distinct name from studt;
        3.条件查询
            a、语法
                select * from 表名 where 条件;
            b、比较运算符
                >  <  =  >=  <=  !=
                需求:查询id值大于8的所有数据
                select * from studt where id>8;
            c、逻辑运算符
                and
                or
                not
                需求:查询id值大于7的女同学
                select * from studt where id>7 and gender = 0;
            d、模糊查询
                like
                    %表示任意多个字符
                    _表示一个任意字符
                需求:查询姓习的同学
                e.g.:select * from studt where name like '习%';
    
                # 正则表达式
                select * from employee where name regexp '^jin.*(g|n)$';
    
            e、范围查询
                in :表示在一个非连续的范围内
                between a and b :表示在一个连续的范围内
                需求:
                    >:查询编号为5,7,9
                      e.g.:select * from studt where id in (5,7,9);
    
                    >:查询编号为5到9
                    e.g.:select * from studt where id between 5 and 9;
    
            f、空判断
               insert into studt(name,age) values('Trangp',86);
    
                注意:null 与''(空字符串)不同
                判断空:is null
                判断非空:is not null
                需求:查询没有地址的同学
                e.g.:select * from studt where address is null;
                    select * from studt where address is not null;
    
            g、优先级
                小括号、not、比较运算符、逻辑运算符
                and比or的优先级高,可结合括号指定优先级
    
        4.聚合
            为了快速得到统计的数据,提供了5个聚合函数
            a、count(*) 表示计算总行数,括号中可以是*或列名
            b、max(列) 表示求此列的最大值
            c、min(列)最小值
            d、sum(列)  求和
            e、avg(列)  平均值
    
            查询学生总数
                select count(*) from studt;
            查询女生编号的最大
                select max(id) from studt where gender = 0;
            查询所有年龄的和
                select sum(age) from studt;
    
        5.分组:
        group by 在where 之后使用
            按照字段分组,表示此字段相同的数据会被放到一个集合中
            分组后,只能查询出相同的数据列,对于有差异的数据列
                    无法显示在结果集中
            可以对分组后的数据进行统计,做聚合运算
    
            语法:select 列1,列2,聚合... from 表名 group by 列1,
                    列2,列3...
            需求:查询男女生总数
            e.g.:select gender,count(*) from studt group by gender;
               select name,gender,count(*) from studt group by name,gender;
    
            分组后的数据筛选:select 列1,列2,聚合... from 表名 group
                by 列1,列2,列3... having 列1,... 聚合...
                e.g.:select gender,count(*) from studt group by gender
                        having gender;  或gender=0
    
                where:对表进行筛选,对原始数据的筛选
                having:对group by 的结果进行筛选,是对结果集的筛选(二次筛选)
    
        6.排序
            语法:select * from 表名 order by 列1;
                asc|desc,列2 asc|desc,...;
    
            说明:
                a、将数据按照列1进行排序,如果某些列1的值相同,
                        则按列2排序
                b、默认按照从小到大的顺序排序
                c、asc升序
                d、desc降序序
    
            需求:按年龄排序
            e.g.:select * from studt order by age;
            select * from studt where isDelete=0 order by age desc;
            # where 在order by 前面
            select * from studt where isDelete=0 order by age desc,id desc;
            出现相同的可再指定一种排序规则
    
        7.分页
            语法:select * from 表名 limit start,count;
            说明:start索引从零开始,count为数量
            e.g.:select * from studt limit 0,3;
                  select * from studt limit 3,3;
                  select * from studt where gender=1 limit 0,3;
    六、关联
        建表语句
        1.create table class(id int auto_increment primary key,
                            name varchar(20) not null,
                            stuNum int not null);
        2.create table student(id int auto_increment primary key,
                                 name varchar(20) not null,
                                 gender bit default 1,
                                 classid int not null,
                    foreign key(classid) references class(id)
                    on delete cascade   # 被关联表删除时,主表删除对应字段
                    on update cascade   # 被关联表更新时,。。。
                    );
    
        输入一些数据:
        insert into class values(0,'Py01',50),(0,'Py01',50),
                        (0,'Py01',50),(0,'Py01',50);
    
        insert into student values(0,'toy',1,1);
        insert into student values(0,'toy',1,10);报错
        insert into student values(0,'jack',1,2);
    
        select * from student;
        关联查询:
        select student.name,class.name from class inner join
            student on class.id=student.classid;
    
    
        分类:
        1、内连接:表Ai inner join 表B
            表示A与B匹配的行会出现在结果集中
        2、左连接:表Ai left join 表B
             表示A与B匹配的行会出现在结果集中,外加表A中独有的数据
                    未对应的数据使用null填充
        3、右连接:表Ai right join 表B
            表示A与B匹配的行会出现在结果集中,外加表B中独有的数据
                    未对应的数据使用null填充
        4、全外连接:在内连接的基础上保留左右两表没有对应关系的记录
            select * from employee left join department on employee.dep_id = department.id
            union
            select * from employee right join department on employee.dep_id = department.id ;
    '''
    
    select distinct 字段1,字段2,字段3 from 库.表
            distinct 去重    from 找到表
        where 条件
        group by 分组条件
        having 过滤
        order by 排序字段
        limit n;
    写的顺序:distinct > from > where > group by > having > order by > limit
    执行顺序:from > where > group by > having > distinct>  order by > limit
    
    #正则表达式
    select * from employee where name like 'jin%';
    select * from employee where name regexp '^jin';
    select * from employee where name regexp '^jin.*(g|n)$';
    all
  • 相关阅读:
    Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理
    Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析
    Java生鲜电商平台-秒杀系统微服务架构设计与源码解析实战
    超硬核Java学习路线图+学习资源+实战项目汇总,看完以后不用再问我怎么学Java了!
    还没使用过消息队列?这一份书单值得你好好看看!
    学习Spring,看这几本书就够了
    这份书单,想要晋级高级Java工程师的朋友值得一看!
    搞定JVM基本原理和面试题,看看这几本书妥妥够了!
    《自拍教程16》cmd的常用技巧
    《自拍教程15》命令行软件的通用技巧
  • 原文地址:https://www.cnblogs.com/webc/p/9174239.html
Copyright © 2011-2022 走看看