MySQL核心知识总结


  1. MySQL核心知识总结

    1. MySQL基础

    1.1 MySQL相关概念

    ​ MySQL是关系型数据库中的一种,关系型数据库是一种高效的存储有组织关系的数据仓库。在开发中我们通常使用数据库管理系统(DBMS)并通过SQL操纵数据库来实现存储数据到数据库中或根据SQL从数据库中获取我们想要的数据。

    ​ 在Java开发中,我们通常使用ORM(Object Relation Mapping)框架封装JDBC(Java DataBase Connection)来操纵数据库,通常就会有以下约定,Java中的entity类对应数据库中的,类中的属性对应数据库中的字段,表中的一行数据即对应类的实例化对象。

    数据库的好处

    1. 可以持久化数据到本地
    2. 结构化查询

    数据库存储数据的特点

    1. 数据存放到表中,然后表再放到库中
    2. 一个库中可以有多张表,每张表具有唯一的表名用来标识自己
    3. 表中有一个或多个列,列又称为“字段”,相当于java中“属性”
    4. 表中的每一行数据,相当于java中“对象”

    1.2 MySQL安装及卸载

    ​ 首先到官网中下载MySQL安装包(推荐5.5版本以上),根据英文提示安装即可。相关的配置可在my.ini或者my-default.ini文件中进行修改。

    ​ 卸载直接通过软件管家或者到控制面板->程序->程序与功能中卸载即可,同时记得在安装处删除相关文件,卸载后仍然安装失败可删除注册表。

    1.3 MySQL基本命令

    MySQL的启动/停止命令为:

    #启动命令

    net start mysql # 这个mysql为你的mysql服务名称

    #停止命令

    net stop mysql

    MySQL登录命令

    mysql -h主机名 -P端口号 -u用户名 -p密码
    #例子:
    mysql -hlocalhost -P3306 -uroot -p123456
    #如果是连本机:-hlocalhost就可以省略,如果端口号没有修改:-P3306也可以省略 当需要连接远程mysql服务时需添加该参数

    查看数据库

    show databases;

    创建数据库

    create database mydatabase #mydatabase 为数据库名称

    使用数据库

    use mydatabase; #mydatabase 为数据库名称

    删除数据库

    drop database mydatabase;

    创建表

    语法

    CREATE TABLE 表名称
    (
    列名称1 数据类型 约束,
    列名称2 数据类型 约束,
    列名称3 数据类型 约束,
    ….
    );

    #实例
    Create Table: CREATE TABLE student (
    stu_id int(11) NOT NULL AUTO_INCREMENT,
    stu_name varchar(20) NOT NULL,
    stu_age int(3) DEFAULT NULL,
    PRIMARY KEY (stu_id)
    )

    删除表

    方式一,使用drop删除表,可以通过日志进行恢复

    drop table student;

    方式二,使用truncate删除表,无法恢复

    truncate table student;

    #推荐使用drop删除表

    修改表结构

    对于已经创建好的表,尤其是有大量数据的表,如果需要对表做结构上的改变,可以将表删除然后重新创建表,但是这种效率会产生一些额外的工作,数据会重新加载近来,如果此时有服务正在访问的话,也会影响服务读取表中数据,所以此时,我们需要表的修改语句来对已经创建好的表的定义进行修改。

    修改表结构一般使用 alter table 语句,下面是常用的命令

    ALTER TABLE tb MODIFY [COLUMN] column_definition [FIRST | AFTER col_name];

    比如我们想要将 job 表中的 name 由 varchar(20) 改为 varchar(25),可以使用如下语句

    alter table job modify name varchar(25);

    也可以对表结构进行修改,比如增加一个字段

    alter table job add home varchar(30);

    将新添加的表的字段进行删除

    alter table job drop column home;

    可以对表中字段的名称进行修改,比如吧 wage 改为 salary

    alter table job change wage salary decimal(10,2);

    修改字段的排列顺序,我们前面介绍过修改语法涉及到一个顺序问题,都有一个可选项 first | after column_name,这个选项可以用来修改表中字段的位置,默认 ADD 是在添加为表中最后一个字段,而 「CHANGE/MODIFY」 不会改变字段位置。比如

    alter table job add birthday after hiredate;

    可以对表名进行修改,例如将 job 表改为 worker

    alter table job rename worker;

    查看表的基本信息

    DESC student;

    +———-+————-+——+—–+———+—————-+
    | Field | Type | Null | Key | Default | Extra |
    +———-+————-+——+—–+———+—————-+
    | stu_id | int(11) | NO | PRI | NULL | auto_increment |
    | stu_name | varchar(20) | NO | | NULL | |
    | stu_age | int(3) | YES | | NULL | |
    +———-+————-+——+—–+———+—————-+

    查看表的创建语句

    show create table student \G;

      Table: student
    

    Create Table: CREATE TABLE student (
    stu_id int(11) NOT NULL AUTO_INCREMENT,
    stu_name varchar(20) NOT NULL,
    stu_age int(3) DEFAULT NULL,
    PRIMARY KEY (stu_id)
    ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8

    查看数据库中的表

    show tables;

    查看和修改字符集

    #查看
    show variables like ‘character_set_%’;
    #修改
    set names utf8;

    退出mysql

    exit;

    2. SQL

    ​ SQL(Structured Query Language)是“结构化查询语言”,它是一种针对表关联关系所设计的一门语言。各个数据库可以使用标准的SQL,同时在标准之外各个数据库又有一些自己的语法,如MySQL中的limit关键字就是独有的。

    2.1 SQL的分类

    • DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等; 关键字有:create drop alter;
    • DCL(Data Control Language):数据控制语言,用来定义数据库访问权限和安全级别,创建用户等。关键字:grant等
    • DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据);关键字有:insert、update、delete
    • DQL(Data Query Language):数据查询语言,用来查询数据库记录(数据);关键字有:select

    2.2 DQL

    2.2.1 基础查询

    一、语法
    select 查询列表
    from 表名;
    二、特点
    1、查询列表可以是字段、常量、表达式、函数,也可以是多个
    2、查询结果是一个虚拟表

    三、示例
    1、查询单个字段
    select 字段名 from 表名;
    2、查询多个字段
    select 字段名,字段名 from 表名;
    3、查询所有字段
    select * from 表名
    4、查询常量
    select 常量值;
    注意:字符型和日期型的常量值必须用单引号引起来,数值型不需要
    5、查询函数
    select 函数名(实参列表);
    6、查询表达式
    select 100/1234;
    7、起别名
    ①as
    ②空格
    8、去重
    select distinct 字段名 from 表名;

    9、+
    作用:做加法运算
    select 数值+数值; 直接运算
    select 字符+数值;先试图将字符转换成数值,如果转换成功,则继续运算;否则转换成0,再做运算
    select null+值;结果都为null

    10、【补充】concat函数
    功能:拼接字符
    select concat(字符1,字符2,字符3,…);

    11、【补充】ifnull函数
    功能:判断某字段或表达式是否为null,如果为null 返回指定的值,否则返回原本的值
    select ifnull(commission_pct,0) from employees;

    12、【补充】isnull函数
    功能:判断某字段或表达式是否为null,如果是,则返回1,否则返回0

    2.2.2 条件查询

    一、语法
    select 查询列表
    from 表名
    where 筛选条件

    二、筛选条件的分类

    条件查询可以使用如下运算符及关键字:

    • =、!=、<>、<、<=、>、>=;
    • AND、OR、NOT
    • BETWEEN…AND、IN(set)、IS NULL、IS NOT NULL

    模糊查询通过like关键字进行查询配合单字符占位符 _ ,多个字符占位符 % 进行模糊查询:

    以下表示查询姓名中第二个字为‘三’字的人,如张三、李三哥、吴三毛帅哥 等等都能匹配
    select * from student where stu_name like ‘_三%’;

    distinct关键字表示将查询出的相同的数据行进行去重:

    因为stu_id 不同故没有重复项
    select distinct * from student;
    +——–+———-+———+
    | stu_id | stu_name | stu_age |
    +——–+———-+———+
    | 2 | 张三 | 11 |
    | 3 | 张三 | 11 |
    +——–+———-+———+

    如果只查询字段stu_name 则存在两行重复值,去重后只返回一个值
    select distinct stu_name from student;
    +———-+
    | stu_name |
    +———-+
    | 张三 |
    +———-+

    2.2.3 排序查询

    关键字: order by 默认情况为升序,可省略ASC

    基础使用:

    • 升序 order by ‘列名’ asc;
    • 降序 order by ‘列名’ desc;

    order by 后面可以跟 单列、多列、函数

    select * from student order by stu_age;
    +——–+———-+———+
    | stu_id | stu_name | stu_age |
    +——–+———-+———+
    | 2 | 张三 | 11 |
    | 3 | 张三 | 11 |
    | 4 | 李四 | 11 |
    | 5 | 李四 | 12 |
    | 6 | 王五 | 12 |
    | 9 | 赵六1 | 34 |
    | 7 | 王五1 | 44 |
    | 8 | 赵六31 | 44 |
    +——–+———-+———+

    – 多列 先根据姓名降序、再根据年龄升序
    select * from student order by stu_name desc,stu_age asc;
    +——–+———-+———+
    | stu_id | stu_name | stu_age |
    +——–+———-+———+
    | 8 | 赵六31 | 44 |
    | 9 | 赵六1 | 34 |
    | 7 | 王五1 | 44 |
    | 6 | 王五 | 12 |
    | 4 | 李四 | 11 |
    | 5 | 李四 | 12 |
    | 2 | 张三 | 11 |
    | 3 | 张三 | 11 |
    +——–+———-+———+
    – 注意:order by多列需要在每列后面指明asc还是desc,该列位指明则默认asc
    如: select * from student order stu_name,stu_age desc; #此时是按姓名升序,按年龄降序

    – 函数排序 根据姓名的长度进行排序
    select * from student order by length(stu_name) desc;
    +——–+———-+———+
    | stu_id | stu_name | stu_age |
    +——–+———-+———+
    | 8 | 赵六31 | 44 |
    | 7 | 王五1 | 44 |
    | 9 | 赵六1 | 34 |
    | 2 | 张三 | 11 |
    | 3 | 张三 | 11 |
    | 4 | 李四 | 11 |
    | 5 | 李四 | 12 |
    | 6 | 王五 | 12 |
    +——–+———-+———+

    2.2.4 常见函数

    1)、聚合函数

    聚合函数作用是对查询的结果集进行运算并得出结果。常见的五种聚合函数:

    • sum(字段名):求和
    • avg(字段名):求平均值
    • max(字段名):求最大值
    • min(字段名):求最小值
    • count(字段名):计算非空字段值的个数

    select sum(stu_age),avg(stu_age),max(stu_age),min(stu_age),count(stu_age) from student;
    +————–+————–+————–+————–+—————-+
    | sum(stu_age) | avg(stu_age) | max(stu_age) | min(stu_age) | count(stu_age) |
    +————–+————–+————–+————–+—————-+
    | 179 | 22.3750 | 44 | 11 | 8 |
    +————–+————–+————–+————–+—————-+

    如果要对年龄进行去重查询记录数,可以使用如下方式

    select count(distinct stu_age) num from student;
    +—–+
    | num |
    +—–+
    | 4 |
    +—–+

    count(*): 计算结果集的总记录数

    count(1): 计算结果集的总记录数

    两种方式的结果相同,但是实现方式不同;推荐使用count(*), MySQL对其进行了优化,查询效率会高一些。

    2)、数学函数

    ABS(x) 返回x的绝对值
    CEIL(x) 返回大于x的最小整数值
    FLOOR(x) 返回大于x的最大整数值
    MOD(x,y) 返回x/y的模
    RAND(x) 返回0~1的随机值
    ROUND(x,y) 返回参数x的四舍五入的有y位的小数的值
    TRUNCATE(x,y) 返回数字x截断为y位小数的结果
    SQRT(x) 返回x的平方根
    POW(x,y) 返回x的y次方

    3)、字符串函数

    CONCAT(S1,S2,……,Sn) 连接S1,S2,……,Sn为一个字符串
    CONCAT(s, S1,S2,……,Sn) 同CONCAT(s1,s2,…)函数,但是每个字符串之间要加上s
    CHAR_LENGTH(s) 返回字符串s的字符数
    LENGTH(s) 返回字符串s的字节数,和字符集有关
    INSERT(str, index , len, instr) 将字符串str从第index位置开始,len个字符长的子串替换为字符串instr
    UPPER(s) 或 UCASE(s) 将字符串s的所有字母转成大写字母
    LOWER(s) 或LCASE(s) 将字符串s的所有字母转成小写字母
    LEFT(s,n) 返回字符串s最左边的n个字符
    RIGHT(s,n) 返回字符串s最右边的n个字符
    LPAD(str, len, pad) 用字符串pad对str最左边进行填充,直到str的长度为len个字符
    RPAD(str ,len, pad) 用字符串pad对str最右边进行填充,直到str的长度为len个字符
    LTRIM(s) 去掉字符串s左侧的空格
    RTRIM(s) 去掉字符串s右侧的空格
    TRIM(s) 去掉字符串s开始与结尾的空格
    TRIM(【BOTH 】s1 FROM s) 去掉字符串s开始与结尾的s1
    TRIM(【LEADING】s1 FROM s) 去掉字符串s开始处的s1
    TRIM(【TRAILING】s1 FROM s) 去掉字符串s结尾处的s1
    REPEAT(str, n) 返回str重复n次的结果
    REPLACE(str, a, b) 用字符串b替换字符串str中所有出现的字符串a
    STRCMP(s1,s2) 比较字符串s1,s2的大小
    SUBSTRING(s,index,len) 返回从字符串s的index位置其len个字符

    4)、日期时间函数

    CURDATE() 或 CURRENT_DATE() 返回当前日期
    CURTIME() 或 CURRENT_TIME() 返回当前时间
    NOW() SYSDATE()CURRENT_TIMESTAMP()LOCALTIME()LOCALTIMESTAMP() 返回当前系统日期时间
    YEAR(date)MONTH(date)DAY(date)HOUR(time)MINUTE(time)SECOND(time) 返回具体的时间值
    WEEK(date)WEEKOFYEAR(date) 返回一年中的第几周
    DAYOFWEEK() 返回周几,注意:周日是1,周一是2,。。。周六是7
    WEEKDAY(date) 返回周几,注意,周1是0,周2是1,。。。周日是6
    DAYNAME(date) 返回星期:MONDAY,TUESDAY…..SUNDAY
    MONTHNAME(date) 返回月份:January,。。。。。
    DATEDIFF(date1,date2)TIMEDIFF(time1, time2) 返回date1 - date2的日期间隔返回time1 - time2的时间间隔
    DATE_ADD(datetime, INTERVALE expr type) 返回与给定日期时间相差INTERVAL时间段的日期时间
    DATE_FORMAT(datetime ,fmt) 按照字符串fmt格式化日期datetime值
    STR_TO_DATE(str, fmt) 按照字符串fmt对str进行解析,解析为一个日期
    • (1)DATE_ADD(datetime,INTERVAL expr type)
    SELECT DATE_ADD(NOW(), INTERVAL 1 YEAR);SELECT DATE_ADD(NOW(), INTERVAL -1 YEAR); #可以是负数SELECT DATE_ADD(NOW(), INTERVAL ‘1_1’ YEAR_MONTH); #需要单引号
    表达式类型 YEAR_MONTH
    YEAR DAY_HOUR
    MONTH DAY_MINUTE
    DAY DAY_SECOND
    HOUR HOUR_MINUTE
    MINUTE HOUR_SECOND
    SECOND MINUTE_SECOND
    • (2)DATE_FORMAT(datetime ,fmt)和STR_TO_DATE(str, fmt)
    格式符 说明 格式符 说明
    %Y 4位数字表示年份 %y 表示两位数字表示年份
    %M 月名表示月份(January,….) %m 两位数字表示月份(01,02,03。。。)
    %b 缩写的月名(Jan.,Feb.,….) %c 数字表示月份(1,2,3,…)
    %D 英文后缀表示月中的天数(1st,2nd,3rd,…) %d 两位数字表示月中的天数(01,02…)
    %e 数字形式表示月中的天数(1,2,3,4,5…..)
    %H 两位数字表示小数,24小时制(01,02..) %h和%I 两位数字表示小时,12小时制(01,02..)
    %k 数字形式的小时,24小时制(1,2,3) %l 数字形式表示小时,12小时制(1,2,3,4….)
    %i 两位数字表示分钟(00,01,02) %S和%s 两位数字表示秒(00,01,02…)
    %W 一周中的星期名称(Sunday…) %a 一周中的星期缩写(Sun.,Mon.,Tues.,..)
    %w 以数字表示周中的天数(0=Sunday,1=Monday….)
    %j 以3位数字表示年中的天数(001,002…) %U 以数字表示年中的第几周,(1,2,3。。)其中Sunday为周中第一天
    %u 以数字表示年中的第几周,(1,2,3。。)其中Monday为周中第一天
    %T 24小时制 %r 12小时制
    %p AM或PM %% 表示%

    5)、流程函数

    IF(value,t ,f) 如果value是真,返回t,否则返回f
    IFNULL(value1, value2) 如果value1不为空,返回value1,否则返回value2
    CASE WHEN 条件1 THEN result1WHEN 条件2 THEN result2….[ELSE resultn]END 相当于Java的if…else if…
    CASE expr WHEN 常量值1 THEN 值1WHEN 常量值1 THEN 值1….[ELSE 值n]END 相当于Java的switch
    SELECT ename ,CASE WHEN salary>=15000 THEN ‘高薪’WHEN salary>=10000 THEN ‘潜力股’WHEN salary>=8000 THEN ‘屌丝’ELSE ‘草根’ENDFROM t_employee;
    SELECT oid,status, CASE statusWHEN 1 THEN ‘未付款’WHEN 2 THEN ‘已付款’WHEN 3 THEN ‘已发货’WHEN 4 THEN ‘确认收货’ELSE ‘无效订单’ENDFROM t_order;

    2.2.5 分组查询

    分组查询是按照表中的一个或多个字段进行分组,如在student表中可以按照姓名相同的进行分组,分组我们可以通过聚合函数对分组的结果进行统计计算,如若不进行计算则只会返回每个分组的第一行记录,例子如下:

    – 初始表数据如下
    select * from student;
    +——–+———-+———+
    | stu_id | stu_name | stu_age |
    +——–+———-+———+
    | 2 | 张三 | 11 |
    | 3 | 张三 | 11 |
    | 4 | 李四 | 11 |
    | 5 | 李四 | 12 |
    | 6 | 王五 | 12 |
    | 7 | 王五1 | 44 |
    | 8 | 赵六31 | 44 |
    | 9 | 赵六1 | 34 |
    +——–+———-+———+

    – 分组后却不进行聚合函数计算的结果(只返回分组后的第一行数据)
    select * from student group by stu_name;
    +——–+———-+———+
    | stu_id | stu_name | stu_age |
    +——–+———-+———+
    | 2 | 张三 | 11 |
    | 4 | 李四 | 11 |
    | 6 | 王五 | 12 |
    | 7 | 王五1 | 44 |
    | 9 | 赵六1 | 34 |
    | 8 | 赵六31 | 44 |
    +——–+———-+———+

    – 使用聚合函数对分组结果进行统计计算
    select stu_name,sum(stu_age) from student group by stu_name;
    +———-+————–+
    | stu_name | sum(stu_age) |
    +———-+————–+
    | 张三 | 22 |
    | 李四 | 23 |
    | 王五 | 12 |
    | 王五1 | 44 |
    | 赵六1 | 34 |
    | 赵六31 | 44 |
    +———-+————–+

    /** 总结: 分组是根据某个字段将结果集分成若干组,如在学生表中我们可以根据班级id将学生以不同的班级进行分组。我们通常将分组后临时表对某些字段进行聚合函数的操作,最后返回该分组的统计结果;如对通过班级分组后的学生,统计学生们的成绩之和或平均成绩等。 因此最终的结果字段一般是:分组字段 + 聚合函数(字段)
    **/

    分组查询执行顺序:

    1. from
    2. where
    3. group by
    4. having
    5. select
    6. order by

    where: 分组前对表数据进行筛选

    having: 分组后对分组结果集进行筛选

    举例:

    – 查询每个班级中学号大于10的学生们的平均成绩及班级编号,平均成绩需大于60,并以班级编号降序排序。
    select avg(score),class_id from student
    where stu_id > 10
    group by class_id
    having avg(score) > 60
    order by class_id desc;

    – 说明: 首先执行from查看执行的表为student,从student表中通过where条件进行过滤筛选,筛选后通过group by对结果进行分组,通过class_id 进行分组后 在通过having中的聚合函数进一步筛选过滤掉平均分低于60的班级,得到select中的结果,最后再同居order by中的班级编号降序排序

    2.2.6 连接查询

    一、含义
    当查询中涉及到了多个表的字段,需要使用多表连接
    select 字段1,字段2
    from 表1,表2,…;

    笛卡尔乘积:当查询多个表时,没有添加有效的连接条件,导致多个表所有行实现完全连接
    如何解决:添加有效的连接条件

    二、分类

    按年代分类:
    sql92:
    等值
    非等值
    自连接

也支持一部分外连接(用于oracle、sqlserver,mysql不支持)

sql99【推荐使用】
内连接
等值
非等值
自连接
外连接
左外
右外
全外(mysql不支持)
交叉连接

三、SQL92语法
1、等值连接
语法:
select 查询列表
from 表1 别名,表2 别名
where 表1.key=表2.key
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】

特点:
① 一般为表起别名
②多表的顺序可以调换
③n表连接至少需要n-1个连接条件
④等值连接的结果是多表的交集部分

2、非等值连接
语法:
select 查询列表
from 表1 别名,表2 别名
where 非等值的连接条件
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
3、自连接

语法:
select 查询列表
from 表 别名1,表 别名2
where 等值的连接条件
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】

自连接,顾名思义就是自己和自己连接。举个例子便知,employee 员工表中包含了员工id、员工姓名、上级id,有些员工是其他员工的上级,即员工的上级id和某位员工的员工id相等,此时我们要查询出员工姓名及上级姓名就可以用自连接:

select a.employee_name,b.employee.name
from employee a,employee b
where a.manager.id = b.employee.id;

四、SQL99语法
1、内连接
语法:
select 查询列表
from 表1 别名
【inner】 join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;

特点:
①表的顺序可以调换
②内连接的结果=多表的交集
③n表连接至少需要n-1个连接条件

分类:
等值连接
非等值连接
自连接

2、外连接
语法:
select 查询列表
from 表1 别名
left|right|full【outer】 join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;
特点:
①查询的结果=主表中所有的行,如果从表和它匹配的将显示匹配行,如果从表没有匹配的则显示null
②left join 左边的就是主表,right join 右边的就是主表
full join 两边都是主表
③一般用于查询除了交集部分的剩余的不匹配的行

3、交叉连接

语法:
select 查询列表
from 表1 别名
cross join 表2 别名;

特点:
类似于笛卡尔乘积

2.2.7 子查询

一、含义
嵌套在其他语句内部的select语句称为子查询或内查询,
外面的语句可以是insert、update、delete、select等,一般select作为外面语句较多
外面如果为select语句,则此语句称为外查询或主查询

二、分类
1、按出现位置
select后面:
仅仅支持标量子查询
from后面:
表子查询
where或having后面:
标量子查询
列子查询
行子查询
exists后面:
标量子查询
列子查询
行子查询
表子查询

2、按结果集的行列
标量子查询(单行子查询):结果集为一行一列
列子查询(多行子查询):结果集为多行一列
行子查询:结果集为多行多列
表子查询:结果集为多行多列

三、示例
where或having后面
1、标量子查询
案例:查询最低工资的员工姓名和工资
①最低工资
select min(salary) from employees

②查询员工的姓名和工资,要求工资=①
select last_name,salary
from employees
where salary=(
select min(salary) from employees
);

2、列子查询
案例:查询所有是领导的员工姓名
①查询所有员工的 manager_id
select manager_id
from employees

②查询姓名,employee_id属于①列表的一个
select last_name
from employees
where employee_id in(
select manager_id
from employees
);

2.2.8 分页查询

一、应用场景
当要查询的条目数太多,一页显示不全
二、语法

select 查询列表
from 表
limit 【offset,】size;
注意:
offset代表的是起始的条目索引,默认从0卡死
size代表的是显示的条目数

公式:
假如要显示的页数为page,每一页条目数为size
select 查询列表
from 表
limit (page-1)*size,size;

2.2.9 联合查询

一、含义
union:合并、联合,将多次查询结果合并成一个结果
二、语法
查询语句1
union 【all】
查询语句2
union 【all】

三、意义
1、将一条比较复杂的查询语句拆分成多条语句
2、适用于查询多个表的时候,查询的列基本是一致

四、特点
1、要求多条查询语句的查询列数必须一致
2、要求多条查询语句的查询的各列类型、顺序最好一致
3、union 去重,union all包含重复项

2.2.10 查询语句顺序

语法:
select 查询列表 ⑦
from 表1 别名 ①
连接类型 join 表2 ②
on 连接条件 ③
where 筛选 ④
group by 分组列表 ⑤
having 筛选 ⑥
order by排序列表 ⑧
limit 起始条目索引,条目数; ⑨

2.3 DML

2.3.1 插入

一、方式一
语法:
insert into 表名(字段名,…) values(值,…);
特点:
1、要求值的类型和字段的类型要一致或兼容
2、字段的个数和顺序不一定与原始表中的字段个数和顺序一致
但必须保证值和字段一一对应
3、假如表中有可以为null的字段,注意可以通过以下两种方式插入null值
①字段和值都省略
②字段写上,值使用null
4、字段和值的个数必须一致
5、字段名可以省略,默认所有列

二、方式二
语法:
insert into 表名 set 字段=值,字段=值,…;

两种方式 的区别:
1.方式一支持一次插入多行,语法如下:
insert into 表名【(字段名,..)】 values(值,..),(值,…),…;
2.方式一支持子查询,语法如下:
insert into 表名 查询语句;

2.3.2 修改

一、修改单表的记录 ★
语法:update 表名 set 字段=值,字段=值 【where 筛选条件】;

二、修改多表的记录【补充】
语法:
update 表1 别名
left|right|inner join 表2 别名
on 连接条件
set 字段=值,字段=值
【where 筛选条件】;

2.3.3 删除

方式一:使用delete
一、删除单表的记录★
语法:delete from 表名 【where 筛选条件】【limit 条目数】
二、级联删除[补充]
语法:
delete 别名1,别名2 from 表1 别名
inner|left|right join 表2 别名
on 连接条件
【where 筛选条件】

方式二:使用truncate
语法:truncate table 表名

两种方式的区别【面试题】★

1.truncate删除后,如果再插入,标识列从1开始
delete删除后,如果再插入,标识列从断点开始
2.delete可以添加筛选条件
truncate不可以添加筛选条件
3.truncate效率较高
4.truncate没有返回值
delete可以返回受影响的行数
5.truncate不可以回滚
delete可以回滚

2.4 DDL

2.4.1 库的管理

一、创建库
create database 【if not exists】 库名【 character set 字符集名】;

二、修改库
alter database 库名 character set 字符集名;
三、删除库
drop database 【if exists】 库名;

2.4.2 表的管理

一、创建表 ★
create table 【if not exists】 表名(
字段名 字段类型 【约束】,
字段名 字段类型 【约束】,
。。。
字段名 字段类型 【约束】

)

二、修改表

1.添加列
alter table 表名 add column 列名 类型 【first|after 字段名】;
2.修改列的类型或约束
alter table 表名 modify column 列名 新类型 【新约束】;
3.修改列名
alter table 表名 change column 旧列名 新列名 类型;
4 .删除列
alter table 表名 drop column 列名;
5.修改表名
alter table 表名 rename 【to】 新表名;

三、删除表
drop table【if exists】 表名;

四、复制表
1、复制表的结构
create table 表名 like 旧表;
2、复制表的结构+数据
create table 表名
select 查询列表 from 旧表【where 筛选】;

2.4.3 数据类型

一、数值型
1、整型
tinyint、smallint、mediumint、int/integer、bigint
1 2 3 4 8

特点:
①都可以设置无符号和有符号,默认有符号,通过unsigned设置无符号
②如果超出了范围,会报out or range异常,插入临界值
③长度可以不指定,默认会有一个长度
长度代表显示的最大宽度,如果不够则左边用0填充,但需要搭配zerofill,并且默认变为无符号整型

2、浮点型
定点数:decimal(M,D)
浮点数:
float(M,D) 4
double(M,D) 8

特点:
①M代表整数部位+小数部位的个数,D代表小数部位
②如果超出范围,则报out or range异常,并且插入临界值
③M和D都可以省略,但对于定点数,M默认为10,D默认为0
④如果精度要求较高,则优先考虑使用定点数

二、字符型
char、varchar、binary、varbinary、enum、set、text、blob

char:固定长度的字符,写法为char(M),最大长度不能超过M,其中M可以省略,默认为1
varchar:可变长度的字符,写法为varchar(M),最大长度不能超过M,其中M不可以省略

三、日期型
year年
date日期
time时间
datetime 日期+时间 8
timestamp 日期+时间 4 比较容易受时区、语法模式、版本的影响,更能反映当前时区的真实时间

2.4.4 常见约束

一、常见的约束
NOT NULL:非空,该字段的值必填
UNIQUE:唯一,该字段的值不可重复
DEFAULT:默认,该字段的值不用手动插入有默认值
CHECK:检查,mysql不支持
PRIMARY KEY:主键,该字段的值不可重复并且非空 unique+not null
FOREIGN KEY:外键,该字段的值引用了另外的表的字段

主键和唯一
1、区别:
①、一个表至多有一个主键,但可以有多个唯一
②、主键不允许为空,唯一可以为空
2、相同点
都具有唯一性
都支持组合键,但不推荐
外键:
1、用于限制两个表的关系,从表的字段值引用了主表的某字段值
2、外键列和主表的被引用列要求类型一致,意义一样,名称无要求
3、主表的被引用列要求是一个key(一般就是主键)
4、插入数据,先插入主表
删除数据,先删除从表
可以通过以下两种方式来删除主表的记录
#方式一:级联删除
ALTER TABLE stuinfo ADD CONSTRAINT fk_stu_major FOREIGN KEY(majorid) REFERENCES major(id) ON DELETE CASCADE;

#方式二:级联置空
ALTER TABLE stuinfo ADD CONSTRAINT fk_stu_major FOREIGN KEY(majorid) REFERENCES major(id) ON DELETE SET NULL;

二、创建表时添加约束
create table 表名(
字段名 字段类型 not null,#非空
字段名 字段类型 primary key,#主键
字段名 字段类型 unique,#唯一
字段名 字段类型 default 值,#默认
constraint 约束名 foreign key(字段名) references 主表(被引用列)

)
注意:
支持类型 可以起约束名
列级约束 除了外键 不可以
表级约束 除了非空和默认 可以,但对主键无效

列级约束可以在一个字段上追加多个,中间用空格隔开,没有顺序要求

三、修改表时添加或删除约束
1、非空
添加非空
alter table 表名 modify column 字段名 字段类型 not null;
删除非空
alter table 表名 modify column 字段名 字段类型 ;

2、默认
添加默认
alter table 表名 modify column 字段名 字段类型 default 值;
删除默认
alter table 表名 modify column 字段名 字段类型 ;
3、主键
添加主键
alter table 表名 add【 constraint 约束名】 primary key(字段名);
删除主键
alter table 表名 drop primary key;

4、唯一
添加唯一
alter table 表名 add【 constraint 约束名】 unique(字段名);
删除唯一
alter table 表名 drop index 索引名;
5、外键
添加外键
alter table 表名 add【 constraint 约束名】 foreign key(字段名) references 主表(被引用列);
删除外键
alter table 表名 drop foreign key 约束名;

四、自增长列
特点:
1、不用手动插入值,可以自动提供序列值,默认从1开始,步长为1
auto_increment_increment
如果要更改起始值:手动插入值
如果要更改步长:更改系统变量
set auto_increment_increment=值;
2、一个表至多有一个自增长列
3、自增长列只能支持数值型
4、自增长列必须为一个key

一、创建表时设置自增长列
create table 表(
字段名 字段类型 约束 auto_increment
)
二、修改表时设置自增长列
alter table 表 modify column 字段名 字段类型 约束 auto_increment
三、删除自增长列
alter table 表 modify column 字段名 字段类型 约束

2.5 TCL

一、含义
事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行
二、特点(ACID)
A 原子性:一个事务是不可再分割的整体,要么都执行要么都不执行
C 一致性:一个事务可以使数据从一个一致状态切换到另外一个一致的状态
I 隔离性:一个事务不受其他事务的干扰,多个事务互相隔离的
D 持久性:一个事务一旦提交了,则永久的持久化到本地

三、事务的使用步骤 ★
了解:
隐式(自动)事务:没有明显的开启和结束,本身就是一条事务可以自动提交,比如insert、update、delete
显式事务:具有明显的开启和结束

使用显式事务:
①开启事务
set autocommit=0;
start transaction;#可以省略

②编写一组逻辑sql语句
注意:sql语句支持的是insert、update、delete

设置回滚点:
savepoint 回滚点名;

③结束事务
提交:commit;
回滚:rollback;
回滚到指定的地方:rollback to 回滚点名;
四、并发事务
1、事务的并发问题是如何发生的?
多个事务 同时 操作 同一个数据库的相同数据时
2、并发问题都有哪些?
脏读:一个事务读取了其他事务还没有提交的数据,读到的是其他事务“更新”的数据
不可重复读:一个事务多次读取,结果不一样
幻读:一个事务读取了其他事务还没有提交的数据,只是读到的是 其他事务“插入”的数据
3、如何解决并发问题
通过设置隔离级别来解决并发问题
4、隔离级别
脏读 不可重复读 幻读
read uncommitted:读未提交 × × ×
read committed:读已提交 √ × ×
repeatable read:可重复读 √ √ ×
serializable:串行化 √ √ √

2.6 视图

视图是对一些较复杂的SQL语句的封装。

  • 创建视图

语法:

create view viewName

as

查询语句;

使用:

select * from viewName where 筛选条件;

  • 修改视图

语法:

create or replace view 视图名 / alter view 视图名

as

查询语句;

  • 删除视图

drop view 视图名,视图名;

  • 查看视图

show create view 视图名;

2.7 存储过程

3 参考资料

总结自 B站:MySQL 基础+高级篇- 数据库 -sql -尚硅谷


文章作者: ring2
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ring2 !
  目录