15k字--快速上手MySQL

目录

1、MySQL数据库基础

[1.1 启动与关闭](#1.1 启动与关闭)

[1.2 数据库的概念](#1.2 数据库的概念)

[1.3 数据库操作](#1.3 数据库操作)

[1.4 数据库的逻辑关系](#1.4 数据库的逻辑关系)

[1.5 SQL分类](#1.5 SQL分类)

[1.6 存储引擎](#1.6 存储引擎)

2、MySQL库的操作(DDL)

[2.1 创建数据库](#2.1 创建数据库)

[2.2 查询&&使用&&修改&&删除数据库](#2.2 查询&&使用&&修改&&删除数据库)

[2.3 数据库的备份与还原](#2.3 数据库的备份与还原)

3、MySQL表结构的操作(DDL)

[3.1 创建表](#3.1 创建表)

[3.2 查询&&修改&&删除表](#3.2 查询&&修改&&删除表)

4、MySQL的数据类型

[4.1 数值类型](#4.1 数值类型)

[4.2 字符串类型](#4.2 字符串类型)

[4.3 日期和时间类型](#4.3 日期和时间类型)

[4.4 枚举和集合类型](#4.4 枚举和集合类型)

5、MySQL表的约束

[5.1 空属性](#5.1 空属性)

[5.2 默认值](#5.2 默认值)

[5.3 列描述](#5.3 列描述)

[5.4 填充0](#5.4 填充0)

[5.5 主键](#5.5 主键)

[5.6 自增长](#5.6 自增长)

[5.7 唯一键](#5.7 唯一键)

[5.8 外键](#5.8 外键)

6、MySQL表数据的操作(DML)

[6.1 INSERT](#6.1 INSERT)

[6.2 SELECT(重点)](#6.2 SELECT(重点))

[6.3 UPDATE](#6.3 UPDATE)

[6.4 DELETE](#6.4 DELETE)

7、MySQL内置函数

[7.1 日期函数](#7.1 日期函数)

[7.2 字符串函数](#7.2 字符串函数)

[7.3 数学函数](#7.3 数学函数)

[7.4 其他函数](#7.4 其他函数)

8、MySQL索引(重点)

[8.1 索引结构](#8.1 索引结构)

[8.2 创建索引](#8.2 创建索引)

9、MySQL事务(重点)

[9.1 事务概念](#9.1 事务概念)

[9.2 事务操作](#9.2 事务操作)

[9.3 隔离性(Isolation)](#9.3 隔离性(Isolation))

10、视图

11、用户与权限管理

12、C/C++访问MySQL


1**、** MySQL 数据库基础

  • MySQL,关键字,不区分大小写。
  • MySQL,''和"",都可以表示字符串,一般使用''。

1.1****启动与关闭

cpp 复制代码
// MySQL的启动与关闭
启动:mysql -h(主机IP)127.0.0.1 -P(端口号)3306 -u(用户)root -p(密码)
关闭:quit

1.2****数据库的概念

  • mysql数据库服务客户端
  • mysqld数据库服务服务器端
  • 数据库 MySQL 是一种基于C (mysql )/S (mysqld )模式的网络服务 ,是在磁盘或内存 中进行数据存取服务,方便数据的处理。

1.3****数据库操作

  • 数据库所在的目录 :datadir=/var/lib/mysql。数据库 是一个目录
  • 创建数据库 :create database helloworld;
  • 选择数据库 :use helloworld;
  • 创建表 是在数据库目录下的文件
sql 复制代码
create table student(
id int,
name varchar(32),
age int,
gender varchar(2)
);
  • 向表中插入数据 :insert into student(id, name, age, gender) values(1, '张三', 20, '男');

1.4****数据库的逻辑关系

1.5 SQL****分类

  • DDL (data definition language):定义数据库和表的结构
  • createalterdrop
  • DML (data manipulation language):实现对表中数据的操作
  • insert select (DQL ) update delete
  • DCL (data control language):数据安全性控制
  • grant (授权 ) revoke (撤回 ) deny (拒绝)。

1.6****存储引擎

  • MySQ架构:
  • 查看存储引擎:show engines;

2**、** MySQL 库的操作 (DDL)

2.1****创建数据库

  • 数据库所在的目录 :datadir=/var/lib/mysql。数据库 是一个目录
  • 语法:
sql 复制代码
// 创建数据库的语法:
CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,create_specification] ...];

create_specification:
    [DEFAULT] CHARACTER SET charset_name  或者  CHARSET=charset_name
    [DEFAULT] COLLATE collation_name 或者 COLLATE=collation_name
  • 说明:
    • 大写的表示关键字;
    • \] 是可选项;

      • 数据库存储数据的格式。本文为utf8。
      • show variables like 'character_set_database';查看字符集。
      • show charset;查看数据库支持的字符集。
    • COLLATE:指定数据库字符集的校验规则。
      • 采用什么格式读取数据库中的数据。如:查询时进行比较,是否区分大小写。本文为utf8_general_ci,不区分大小写。
      • show variables like 'collation_database';查看校验规则。
      • show collation;查看数据库支持的校验规则。

2.2****查询 && 使用 && 修改 && 删除数据库

sql 复制代码
// 1. 查询数据库
    show databases; // 查看有哪些数据库
    select database(); // 查看当前在那个数据库
    show create database db_name; // 查看创建数据库db_name时的信息
    show processlist; // 查看数据库的连接情况
// 2. 使用数据库
    use db_name;
// 3. 修改数据库 不建议改
    // 与创建数据库相比,就是把CREATE换成了ALTER
    ALTER DATABASE db_name [alter_spacification [,alter_spacification]...]
   
    alter_spacification:
        [DEFAULT] CHARACTER SET charset_name  或者  CHARSET=charset_name
        [DEFAULT] COLLATE collation_name
// 4. 删除数据库 不建议删
    DROP DATABASE [IF EXISTS] db_ name;

2.3****数据库的备份与还原

sql 复制代码
// 1. 数据库的备份
    mysqldump -uroot -p -B db_name > path/db_new_name.sql // 备份一个数据库
    mysqldump -uroot -p db_name table_name1 table_name2  > path/mytest.sql // 数据库中的多个表
    mysqldump -uroot -p -B db_name1  db_name2 ... > path/ // 多个数据库
    如果备份一个数据库时,没有带上-B参数,
    在恢复数据库时,需要先创建(create)空数据库,然后使用(use)数据库,再使用source来还原,
    可以达到数据库重命名的效果。当然也可以在db_new_name.sql里面改。
// 2. 数据库的还原
    mysql> sourse path/db_new_name.sql

3**、** MySQL 表结构的操作 (DDL)

3.1****创建表

sql 复制代码
CREATE TABLE [IF NOT EXISTS] table_name(
    field1 datatype 约束...,
    field2 datatype 约束...,
    field3 datatype 约束...
) [character set 字符集 collate 校验规则 engine 存储引擎];
或者[charset=字符集 collate=校验规则 engine=存储引擎]

CREATE TABLE table_name1 LIKE table_name2;

3.2****查询 && 修改 && 删除表

sql 复制代码
// 1. 查询表
    show tables; // 查看有哪些表
    desc table_name; // 查看表的结构
    show create table table_name \G // 查看创建表时的信息
// 2. 修改表 不建议改
    // 语法
        // 新增属性
        ALTER TABLE table_name ADD column
            datatype [DEFAULT expr] [,column datatype]...;
        // 修改属性
        ALTER TABLE table_name MODIFY
            column datatype [DEFAULT expr] [,column datatype]...;
        // 删除属性和数据
        ALTER TABLE table_name DROP column;
    // 例子
        // 在users表添加一个属性,用于保存图片路径,放在birthday属性的后面
        mysql> alter table users add
            assets varchar(100) comment '图片路径' after birthday;
        // 修改表名users为employee
        mysql> alter table users rename [to] employee;
        // 修改属性名name为xingming。属性也应一并设置。
        mysql> alter table employee change name xingming varchar(60);
        // 修改name的属性,将其长度改成60。原有的任何数据,会被直接覆盖。
        mysql> alter table users modify
            name varchar(60);
        // 删除password属性。
        mysql> alter table users drop password;
// 3. 删除表 不建议删
    DROP [TEMPORARY] TABLE [IF EXISTS] table_name [,table_name]...

4**、** MySQL 的数据类型

  • 数据类型 本质就是约束 ,一旦超出数值范围报错 ,使数据库中的数值都是在指定的范围之内

4.1****数值类型

sql 复制代码
// 整数类型
    // 1. tinyint 1字节,默认是有符号的。
        tinyint  -128~127
        tinyint unsigned  0~255
    // 2. smallint 2字节
    // 3. mediumint 3字节
    // 4. int 4字节
    // 5. bigint 8字节
// 位类型
    bit[(M)] // M个比特位,M为1~64,默认为1。按ASCII值显示。
// 浮点数类型
    // 1. float[(M,D)] [unsigned] 4字节,默认是有符号的。无符号的,直接去掉负数的部分。
        <=M个数字,D是小数位数。
        如:float(4,2)是-99.99~99.99,
        整数部分<=2(M-D)位数,
        小数可以四舍五入后,但整体数值必须在范围之内。
        float表示的精度大约是7位。
    // 2. double[(M,D)] [unsigned] 8字节
    // 3. decimal(M,D) [unsigned]
        M<=65位,支持小数最大位数D是30;
        如果D被省略,默认为0;如果M被省略,默认是10;
        建议:如果希望小数的精度高,推荐使用decimal。

4.2****字符串类型

sql 复制代码
// 1. char(L),固定长度的字符串,
    L是字符的长度,最大长度为255个字符,
    (2字符,比如:'ab','中国'。注意是2个符号,不是两个字节)。
// 2. varchar(L),可变长的字符串,
    L表示字符最大长度,最大为21844个字符,有1~3个字节记录实际字符长度,
    当表的编码为utf8时,一个汉字三个字节,
    有效存储数据的长度为65532个字节(有3个字节记录长度)。
    实际用多少开多少。
  • char比varchar,一次开好空间,不用维护计数器,更高效;varchar,可以节省内存。

4.3****日期和时间类型

sql 复制代码
// 1. date,日期'yyyy-mm-dd',
    占用三字节。
// 2. datetime 时间日期格式'yyyy-mm-dd HH:ii:ss',
    占用八字节。
// 3. timestamp,时间戳,从1970年开始,格式'yyyy-mm-dd HH:ii:ss',和datetime一致,
    占用四字节。插入或更新数据时,会自动更新。

4.4****枚举和集合类型

sql 复制代码
// 1. enum('选项1', '选项2', ...),枚举类型,单选,
    只能是选项的其中之一,可以用下标索引(从1开始)。
   
// 2. set('选项1', '选项2', ...),集合类型,多选,
    只能是这些选项,可以多选(如:'选项1,选项2')。
    可以用数字(位图,如:1就是选项1),0不是NULL,而是''。
  • find_in_set(a,b),a是b中的一个元素,返回下标(真,从1开始);不是,返回0(假)。

5**、** MySQL 表的约束

  • 约束:保证数据的完整性。
  • 约束可以在属性类型的后面设置。

5.1****空属性

  • 属性默认NULL (空,允许插入空);NOT NULL(非空,不允许插入空)。

5.2****默认值

  • 默认值 (DEFAULT ):用户没有输入值 ,就使用默认值
  • 属性默认值没有指定时 ,默认为NULL 。所以,允许为空是允许插入默认值NULL和用户输入的NULL;非空约束 是为了防止插入默认值 NULL (其实设置为NOT NULL,DEFAULT没有被设置为NULL(因为设置了也插入不了),所以不指定值插入,会报没有默认值的错误。NOT NULL要指定插入或设置非空的默认值。)和用户输入的 NULL

5.3****列描述

  • 列描述 (COMMENT ):用来描述属性

5.4****填充 0

  • 如:age int(10) zerofill ,表示宽度为10位,位数不足 0 填充
  • 只是输出形式改变值不变
  • int unsigned,默认int(10),2^31 -1 ,有10位数;int,默认int(11),多个负号。

5.5****主键

  • 主键 (PRIMARY KEY ):一个元组非空唯一标识一个表最多有一个主键
  • 添加主键
  • 可以在属性后面设置 primary key。或者在设置属性的最后一行,primary key(属性集合)。建议创建表的时候,就设置好。
  • 也可以创建表后 ,alter table 表名 add primary key (属性集合)。
  • 删除主键 :是删除约束不是删除属性
  • alter table 表名 drop primary key;。

5.6****自增长

  • 自增长 (auto_increment):默认从1开始,从当前最大值+1开始。插入时,不用输入该值,会自动增长,。
  • 自增长的属性 必须是整数类型
  • 自增长的属性 必须是索引类型(索引后续再介绍)。
  • 一张表最多有一个自增长类型
  • 一般与主键搭配
  • create table table_name(id int auto_increment) auto_increment=100; 可以指定起始值
  • select last_insert_id();可以查看最后插入时的自增长的值。

5.7****唯一键

  • 唯一键 (UNIQUE 或者 UNIQUE KEY ):属性值唯一允许 NULL(NULL认为是未知值,不相等)。
  • 主键非空唯一键 ,侧重于一个元组的唯一标识一个表最多有一个
  • 唯一键允许为 NULL ,侧重于一个属性的唯一性一个表可以有多个

5.8****外键

  • 外键 (foreign key ):外键 必须是另一张表中主键 ,且外键的域包含于该主键的域 (即所有外键的值必须在主键中存在 或者外键为 NULL)。
  • foreign key(外键) references 主表(主键)。

6**、** MySQL 表数据的操作 (DML)

  • CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)。

6.1 INSERT

sql 复制代码
// 1. 基本语法
    INSERT [INTO] table_name [(column [, column] ...)]
        VALUES (value_list) [, (value_list)] ...
       
    value_list: value, [, value] ...
// 2. 使用说明
    t1表
        id int unsigned auto_increment,
        sno char(10) unique key,
        name varchar(20),
        primary key(id)
    // 基本插入(可以多行插入)
        // 指定全部属性
        insert into t1(id, sno, name) values(1,'01','Lzc');
        // 指定部分属性,没有指定的属性使用默认值
        insert into t1(sno, name)values('01','Lzc');
        // 不指定属性,默认指定全部属性
        insert into t1 values(1,'01','Lzc');
        或者
        insert into t1 values(default(占位符,使用默认值),'01','Lzc');
    // 插入或替换1
        INSERT ... ON DUPLICATE KEY UPDATE
            column = value [, column = value] ...
        -- 0 row affected:表中有冲突数据,但冲突数据的值和 update 的值相等
        -- 1 row affected:表中没有冲突数据,数据被插入
        -- 2 row affected: 表中有冲突数据,并且数据已经被更新(就地更新)
    // 插入或替换2
        REPLACE INTO table_name(sn, name) VALUES (22, 'dj'); // 在判断冲突前,id已经自增长为3了
        -- 1 row affected:表中没有冲突数据,数据被插入   
        -- 2 row affected:表中有冲突数据,删除后重新插入

**6.2 SELECT(**重点 )

  • 虽然是SQL SERVER,但用法基本相同。
  • MySQL中没有TOP,有LIMIT;MySQL没有全外连接(FULL [OUTER] JOIN)。
  • 对于相关子查询,可以转为下面样例中的构建临时表,形成多表查询。
sql 复制代码
// 1. 基本语法
    SELECT [ALL|DISTINCT] {* | <{column_name | condition_expression} [[as] 重命名]> [,...n] }
        [FROM table_name]
        [WHERE condition_expression]
        [GROUP BY <column_name> [,...n] [HAVING group_condition_expression]
        [ORDER BY <column_name [ASC|DESC]> [,...n]
        [LIMIT n]
    ALL|DISTINCT:默认ALL,结果不去重;DISTINCT,结果去重。
    FROM:从一个或多个表(视图)中查询。
    WHERE:condition_expression可以是
        a. 比较运算符:=、>、<、>=、<=、<>(!=)。NULL=NULL,NULL是未知的,所以为False。
        b. 逻辑运算符:AND(与)、OR(或)、NOT(非)。
        c. 确定范围运算符:BETWEEN AND(左闭右闭),NOT BETWEEN AND,可以用比较运算符代替。
        d. 集合成员运算符:IN、NOT IN。
        e. 字符匹配运算符:LIKE,NOT LIKE。
        f. 判空运算符:IS NULL、IS NOT NULL。
        g. SELECT 子句:SELECT可以嵌套。
        h. 谓词:IN、EXISTS、ALL、SOME、ANY。
        i. 集合运算符:UNION(并)、INTERSECT(交)、EXCEPT(差)。
    GROUP BY:按一个或多个列,分组。
    聚合函数:AVG()、MAX()、MIN()、SUM()、COUNT()。
    HAVING:在GROUP BY中可选(没有GROUP BY,不能单独写HAVING),给分组加上条件。
    ORDER BY:对最终的查询结果进行排序,默认ASC,升序,DESC降序。
    LIMIT n:前n行。
    LIMIT offset, n:从偏移量offset开始的n行。LIMIT n,默认偏移量offset为0。
    LIMIT n OFFSET offset:等价于LIMIT offset, n,只是写法更规范。
  • SELECT语句的执行顺序:FROM (指定表),WHERE (指定条件),GROUP BY (分组),HAVING (分组条件),SELECT (查询),ORDER BY (排序,可以使用SELECT中的别名),LIMIT(截取指定数量的行返回)。
  • 聚合函数 执行的顺序,在GROUP BY后,不能在WHRER中使用,一般在HAVINGSELECT使用 。可以在SELECT使用聚合函数 ,后面HAVING 中就可以使用别名少一次计算
  • 查询样例:
sql 复制代码
MySQL中,一切皆表。
想办法,多表 -> 单表。
// 1. 显示工资最高的员工的名字和工作岗位
    select ename, job from EMP where sal = (select max(sal) from EMP);
// 2. 显示每个部门的平均工资和最高工资
    select deptno, format(avg(sal), 2) , max(sal) from EMP group by deptno;
// 3. 显示平均工资低于2000的部门号和它的平均工资
    select deptno, avg(sal) as avg_sal from EMP group by deptno having avg_sal<2000;
// 4. 查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人
    select ename from EMP
    where (deptno, job)=(select deptno, job from EMP  where ename='SMITH')
    and ename != 'SMITH';
// 5. 显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资
    //获取各个部门的平均工资,将其看作临时表
    select ename, deptno, sal, format(asal,2) from EMP inner join
    (select avg(sal) asal, deptno dt from EMP group by deptno) tmp on EMP.deptno=tmp.dt
    where EMP.sal > tmp.asal;

6.3 UPDATE

  • 不指定条件,就全部更新。
sql 复制代码
// 基本语法
    UPDATE table_name SET <column = expression> [,...n]
        [WHERE ...]
        [ORDER BY ...]
        [LIMIT ...]

6.4 DELETE

  • 不指定条件,就全部删除。
sql 复制代码
// 1. 基本语法
    DELETE FROM table_name
        [WHERE ...]
        [ORDER BY ...]
        [LIMIT ...]
// 2. 删除表的全部数据
TRUNCATE [TABLE] table_name;
DELETE FROM table_name;

// 1. TRUNCATE是DDL语句,改变表的结构;DELETE是DML语句,改变表的数据。
// 2. TRUNCATE不支持事务回滚;DELETE支持事务回滚。
// 3. TRUNCATE会重置AUTO_INCREMENT项;DELETE不会重置AUTO_INCREMENT项。
// 4. TRUNCATE比DELETE快。

7**、** MySQL 内置函数

7.1****日期函数

sql 复制代码
// 1. current_date()
    当前日期,格式为'yyyy-mm-dd'
// 2. current_time()
    当前时间,格式为'HH:ii:ss'
// 3. current_timestamp()
    当前时间戳,格式为'yyyy-mm-dd HH:ii:ss'
// 4. date(datetime)
    返回datetime中的日期部分
// 5. date_add(date, interval num type)
    select date_add('2026-1-8 14:30:25', interval 10 day),
    type可以是year,month,day,hour,minute,second。
// 6. date_sub(date, interval num type)
// 7. datediff(date1, date2)
    两个日期的差值,单位是天
// 8. now()
    当前时间,格式为'yyyy-mm-dd HH:ii:ss' 

7.2****字符串函数

sql 复制代码
// 1. charset(str)
    返回字符串的存储格式
// 2. concat(str1,str2,num,...)
    返回拼接的字符串
// 3. instr(str, substr)
    如果substr在str中,返回起始下标(下标是从1开始的),不在,返回0
// 4. ucase(str)
    返回大写的字符串
// 5. lcase(str)
    返回小写的字符串
// 6. left(str, length)
    返回前面的length个字符
// 7. replace(str, search_str, replace_str)
    将str中的searcher全部替换成replace_str
// 8. strcmp(str1, str2)
// 9. length(str)
    返回str的字节数
// 10. substring(str, pos [, length])
// 11. ltrim(str),去除左边(开头)的空格
       rtrim(str),去除右边(结尾)的空格
       trim(str),去除左右两边的空格

7.3****数学函数

sql 复制代码
// 1. abs(num)
    返回绝对值
// 2. bin(num),十进制 -> 二进制字符串
      hex(num),十进制 -> 十六进制字符串
      conv(num, from_base, to_base),from_base原数的进制,to_base目标进制
// 3. ceiling(num),向上取整。
      floor(num),向下取整。
// 4. format(num, decimal_places)
        保留小数位数(四舍五入)。
// 5. rand()
    返回[0.0, 1.0)之间的随机数。
// 6. mod(num1, num2)
    等价于num1 % num2,以被除数的符号为准。

7.4****其他函数

sql 复制代码
// 1. user()
    显示当前用户
// 2. database()
    显示当前使用的数据库
// 3. md5(str)
    返回str的摘要,大小为32位字符
// 4. password(str)
    MySQL数据库使用该函数对用户密码进行加密
// 5. ifnull(val1, val2)
    如果val1 is null,返回val2,否则,返回val1

8**、** MySQL 索引 ( 重点 )

8.1****索引结构

  • MySQL中的数据文件,是以page(16KB)为单位保存在磁盘当中的。为什么是16KB,因为局部性原理。
  • MySQL中有Buffer Pool(128M),将page先写到操作系统的内核缓冲区,再写到磁盘中。
  • MySQL中有大量的page,需要 先描述,再组织。
  • B+树:
  • MySQL中的InnoDB的索引结构。
  • 叶子节点保存数据+目录项,非叶子节点只保存目录项。
  • 叶子节点用链表连接,可以进行范围查找。
  • 查找 时,性能决定性因素内存与磁盘的 I/O线性查找太慢
  • B+ 向下查找只加载部分的 page ,减少 I/Opage 里面也有目录支持索引
  • 为什么不用其他数据结构?
  • 其他数据结构:链表(线性),AVL、红黑(高度较高),HASH(不支持范围查找)。
  • B树:所有节点都保存数据+目录项(高度较高),叶子节点没有用链表连接(不支持范围查找)。
  • InnoDB 是将索引和数据一起叶子节点目录项和数据 ,称聚簇索引。如果还有一个聚簇索引,对于叶子节点,不放数据,放主键值,然后在主键索引中查询,称为回表查询。
  • MyISAM 是将索引与数据分离叶子节点目录项和数据指针 ,称非聚簇索引

8.2****创建索引

sql 复制代码
// 查看索引
    show index from table_name;
// 1. 主键索引 一个表只有一个
    // 创建主键索引
        -- 在创建表的时候,直接在字段名后指定 primary key
        create table  user1(id int primary key, name varchar(30));
        -- 在创建表的最后,指定某列或某几列为主键索引
        create table  user2(id int, name varchar(30), primary key(id));
        -- 创建表以后再添加主键
        create table  user3(id int, name varchar(30));
        alter table user3 add primary key(id);
    // 删除主键索引
        alter table table_name drop primary key;
// 2. 唯一索引 一个表可多个,允许为NULL,NULL为未知值,NULL!=NULL;主键是非空唯一索引
    // 创建唯一索引
        -- 在表定义时,在某列后直接指定unique唯一属性
        create table  user4(id int primary key, name varchar(30) unique);
        -- 创建表时,在表的后面指定某列或某几列为unique
        create table  user5(id int primary key, name varchar(30), unique(name));
        -- 创建表以后再添加唯一索引
        create table  user6(id int primary key, name varchar(30));
        alter table user6 add unique(name);
    // 删除唯一索引
        alter table table_name drop index index_name;
// 3. 普通索引 一个表可多个
    // 创建普通索引
        --在表的定义最后,指定某列为索引
        create table user7(id int primary key, name varchar(20), email varchar(30), index(name));
        --创建完表以后指定某列为普通索引
        create table user8(id int primary key,  name varchar(20),  email varchar(30));
        alter table user8 add index(name);
        -- 创建一个索引名为 idx_name 的索引 
        create table user9(id int primary key,  name varchar(20),  email varchar(30));
        create index idx_name on user9(name);
    // 删除普通索引
        alter table table_name drop index index_name;
  • 索引创建原则:频繁查询,有多种类别,更新不频繁。

9**、** MySQL 事务 ( 重点 )

9.1****事务概念

  • 事务:若干条SQL语句构成的任务。
  • 事务的性质:
  • 原子性 (A tomicity):事务不可分割最小单位 ,要么全部执行成功 ,要么全部回滚 。比如转账
  • 一致性 (C onsistency):事务前后数据规则不变 ,比如转账前和转账后加起来的总金额不变
  • 隔离性 (I solation):多个并发事务 之间相互隔离互不干扰
  • 持久性 (D urability):事务提交后数据永久保存 ,哪怕崩溃也不丢 。可以记录日志和备份

9.2****事务操作

  • 查看数据库引擎:show engines;。MySQL中只有使用了Innodb 数据库引擎 的数据库或表才支持事务MyISAM 不支持事务
sql 复制代码
// 1. 事务的提交方式
    // 查看事务的提交方式
        show variables like 'autocommit';
        +---------------+-------+
        | Variable_name | Value |
        +---------------+-------+
        | autocommit    | ON    |
        +---------------+-------+
        ON,是自动提交,OFF,是手动提交。
    // 设置事务的提交方式
        set autocommit=0; // 设置为OFF,手动提交
        set autocommit=1; // 设置为ON,自动提交
// 2. 事务的正常操作
   // 启动事务
       start transaction;
       -- 或者
       begin;
   // 设置标记
       savepoint 标记名;
   // 回滚事务
       rollback 标记名;
       如果没有标记名,将全部回滚,然后事务结束,无需commit。
   // 提交事务
       commit;
   a. 手动启动事务,需要手动commit,不受autocommit的影响。
   b. 事务,没有commit,会回滚,commit后,无法回滚,数据的修改具有持久性。
   c. 单条SQL,本身就是事务,默认autocommit为ON,自动commit。

9.3****隔离性 (Isolation)

  • 3 个并发问题
  • 脏读同一事务内 ,读了其他事务未提交 的修改(数据可能回滚,是 "脏数据");
  • 不可重复读同一事务内多次读同一行数据 」,结果不一样 (被其他事务提交修改了)。数据的值,UPDATE(更新已存在的数据)
  • 幻读同一事务内多次执行同一范围查询 」,结果不一样 (被其他事务提交插入 / 删除了)。数据的行数,INSERT 或 DELETE(新增或删除行)
  • 4 种隔离级别(从低到高):
  • 读未提交 (Read Uncommitted):同一事务内能读未提交的数据 ,存在脏读不可重复读幻读,性能最好但最不可靠;
  • 读已提交 (Read Committed):同一事务内只能读已提交的解决了脏读 ,但会有不可重复读幻读
  • 可重复读 (Repeatable Read):MySQL 默认的隔离级别同一事务内读数据,结果不变 (MVCC (多版本并发控制),会生成数据快照 ,解决了脏读不可重复读 ,但是新行不在快照里 ,会被直接读到 ,导致行数变化幻读 ),如果删除了行 ,要进行先查后改 的操作,也会造成幻读 (行数不对),可以通过InnoDB间隙锁 锁住 "数据之间的空隙",阻止其他事务插入 / 删除行)。
  • 串行化 (Serializable):事务一个接一个执行没任何并发问题 ,但性能最差,基本不用。
  • 隔离级别越高 ,数据越安全 ,但并发性能越差
sql 复制代码
// 1. 查看隔离级别
    // 查看全局的隔离级别
        select @@global.tx_isolation;
    // 查看当前会话的隔离级别
        select @@session.tx_isolation;
        -- 或
        select @@tx_isolation;
// 2. 设置隔离级别
    SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {
    READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE};

10**、视图**

sql 复制代码
// 1. 创建试图
    create view view_name as select语句;
// 2. 查看视图
    show tables;
// 3. 删除视图
    drop view view_name;
  • 修改视图,会修改基表。
  • 修改基表,会修改视图。

11**、用户与权限管理**

sql 复制代码
// 1. 创建用户
    create user '用户名'@'登陆主机/ip' identified by '密码';
// 2. 查看用户
    use mysql; -- 使用mysql数据库
    select * from user \G -- 查看用户信息
    select user(); -- 显示当前用户
// 3. 修改用户密码
    // 修改自己的密码
        set password=password('新的密码');
    // root用户修改任意用户的密码
        set password for '用户名'@'主机名'=password('新的密码');
// 3. 删除用户
    drop user '用户名'@'主机名';
  • MySQL数据库提供的权限列表:
sql 复制代码
// 1. 授予权限
    grant 权限列表 on 库.对象名 to 用户名@IP [identified by '密码'];
    权限列表:需要什么权限,就给什么权限,逗号分隔。
    *.* : 代表本系统中的所有数据库的所有对象
    库.* : 表示某个数据库中的所有数据对象
// 2. 查看权限
    show grants for 用户名@IP;
// 3. 撤回权限
    revoke 权限列表 on 库.对象名 from 用户名@IP;
// 4. 刷新权限
    flush privileges;

12**、** C/C++ 访问 MySQL

sql 复制代码
正常编译
// 1. 下载mysql.h和libmysqlclient.so,
    yum install -y mysql-community-devel
    -- mysql.h在/usr/include/mysql/mysql.h
    -- libmysqlclient.so在/usr/lib64/mysql/libmysqlclient.so
// 2. 编译选项
    g++ -o test.cc test -L /usr/lib64/mysql -l mysqlclient
sql 复制代码
// MySQL的常用接口
// 1. 初始化MySQL对象
    MYSQL *mysql_init(MYSQL *mysql);
    // 如:MySQL* mfp = mysql_init(nullptr);
    // error,返回nullptr
// 2. 连接MySQL
    MYSQL *mysql_real_connect(
        MYSQL *mysql, -- MySQL对象
        const char *host, // IP  本地连接可以使用 localhost 或者 127.0.0.1
        const char *user, // 用户名
        const char *passwd, // 密码
        const char *db, // 要使用的数据库
        unsigned int port, // MySQL的port
        const char *unix_socket, // 一般为nullptr
        unsigned long clientflag // 一般为0
        );
    // error,返回nullptr
// 3. 关闭MySQL连接
    void mysql_close(MYSQL *sock);
// 4. 设置字符集(存储格式)
    int mysql_set_character_set(MYSQL *mysql, const char *csname); // 一般为 "utf8"
    // success,返回0,errot,返回非0
// 5. 执行MySQL语句
    int mysql_query(MYSQL *mysql, const char *q);
    // success,返回0,errot,返回非0
// 6. 显示查询结果
    // 首先查询结果,就是一个表,看成二维数组。
    // 提取查询结果
        MYSQL_RES* mysql_store_result(MYSQL *mysql);
        // 如:MYSQL_RES* res= mysql_store_result(mfp);
    // 获取行数
        my_ulonglong mysql_num_rows(MYSQL_RES *result);
        // 如:my_ulonglong row = mysql_num_rows(res);
    // 获取列数
        unsigned int mysql_num_fields(MYSQL_RES *result);
        // 如:unsigned int col = mysql_num_fields(res);
    // 获取列属性
        MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES *result);
       
        MYSQL_FIELD *fields = mysql_fetch_fields(res);
        for(unsigned int i = 0; i < col; ++i) {
                std::cout << fields[i].name << " "; // 获取列名
        }
        std::cout << std::endl;
    // 显示查询结果
        // 返回查询结果中的一行数据
        // 类似迭代器,执行完,内部行指针会自动++。
        MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
       
        for(my_ulonglong i = 0; i < row; ++i) {
            MYSQL_ROW line = mysql_fetch_row(res);
            for(unsigned int j = 0; j < col; ++j) {
                std::cout << line[j] << " ";
            }
            std::cout << std::endl;
        }
// 7. 释放查询结果
    void mysql_free_result(MYSQL_RES *result);
    // 如:mysql_free_result(res);
相关推荐
岁岁种桃花儿2 小时前
深入理解MySQL SELECT语句执行顺序:从书写到内部流程全解析
数据库·mysql
想唱rap2 小时前
MySQL表得内外连接
服务器·数据库·c++·mysql·ubuntu
hunjinYang2 小时前
MySQL:一条SQL查询语句是如何执行的?
sql·mysql·adb
warton882 小时前
ubuntu24搭建mysql8.0.36 mgr
linux·运维·mysql
石像鬼₧魂石2 小时前
补充章节:WPScan 实战后的 “打扫战场 + 溯源” 流程
数据库·学习·mysql
tokepson9 小时前
Mysql下载部署方法备份(Windows/Linux)
linux·服务器·windows·mysql
什么都不会的Tristan13 小时前
MybatisPlus-扩展功能
数据库·mysql
想唱rap17 小时前
表的约束条件
linux·数据库·mysql·ubuntu·bash
千寻技术帮17 小时前
10341_基于Springboot的珠宝销售网站
spring boot·mysql·毕业设计·商城·珠宝商城