关系型数据库 - MySQL

Posted on Sun, Feb 26, 2023 大数据 MySQL 数据库

什么是关系型数据库?

关系型数据库 (RDB) 是一种在表、行和列中构建信息结构的方法。RDB 可以通过联接表来在信息之间建立关联或关系,从而使用户可以轻松理解和分析各种数据点之间的关系。

每个应用程序都各自写自己的读写数据的代码,一方面效率低,容易出错,另一方面,每个应用程序访问数据的接口都不相同,数据难以复用。而基于关系数据库,应用程序不需要自己管理数据,而是通过数据库软件提供的接口来读写数据。

关系数据库模型

层次模型

层次模型就是以“上下级”的层次关系来组织数据的一种方式,层次模型的数据结构看起来就像一颗树。

网状模型

网状模型把每个数据节点和其他很多节点都连接起来,它的数据结构看起来类似于多个城市之间的路网。

关系模型

SQL

SQL是结构化查询语言的缩写,用来访问和操作数据库系统。SQL语句既可以查询数据库中的数据,也可以添加、更新和删除数据库中的数据,还可以对数据库进行管理和维护操作。不同的数据库,都支持SQL,这样,我们通过学习SQL这一种语言,就可以操作各种不同的数据库。

总的来说,SQL语言定义的几种操作数据库的能力如下描述:

MySQL

基础架构及SQL执行过程

连接器: 身份认证和权限相关(登录 MySQL 的时候)。

连接器主要和身份认证和权限相关的功能相关,就好比一个级别很高的门卫一样。

主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作,如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。

作者:Levng链接:https://juejin.cn/post/7052198717557833741来源:稀土掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

查询缓存: 执行查询语句的时候,会先查询缓存。(MySQL 8.0 版本后移除,因为这个功能不太实用)。

查询缓存主要用来缓存我们所执行的 SELECT 语句以及该语句的结果集。

连接建立后,执行查询语句的时候,会先查询缓存,MySQL 会先校验这个 sql 是否执行过,以 Key-Value 的形式缓存在内存中,Key 是查询预计,Value 是结果集。如果缓存 key 被命中,就会直接返回给客户端,如果没有命中,就会执行后续的操作,完成后也会把结果缓存起来,方便下一次调用。当然在真正执行缓存查询的时候还是会校验用户的权限,是否有该表的查询条件。

MySQL 查询不建议使用缓存,因为查询缓存失效在实际业务场景中可能会非常频繁,假如你对一个表更新的话,这个表上的所有的查询缓存都会被清空。对于不经常更新的数据来说,使用缓存还是可以的。所以,在大多数情况下不推荐使用查询缓存。

分析器: 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。
  • 第一步:词法分析,一条 SQL 语句有多个字符串组成,首先要提取关键字,比如 select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。
  • 第二步:语法分析,主要就是判断你输入的 SQL 是否正确,是否符合 MySQL 的语法。
优化器: 按照 MySQL 认为最优的方案去执行。

优化器的作用就是它认为的最优的执行方案去执行。例如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等。可以说,经过了优化器之后可以说这个语句具体该如何执行就已经定下来。

执行器

当选择了执行方案后,MySQL 就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果。

查询/修改/定义 语句

查询语句
  • 基本查询
  • 条件查询
  • 投影查询
  • 排序
  • 分页查询
  • 聚合查询
  • 多表查询
  • 连接查询
修改语句
  • INSERT
  • UPDATE
  • DELETE
定义语句
  • CREATE
  • ALTER
WHERE LIKE Operator
选取一列 替换/截取/删除/切割 字段名

select

  • 替换法 replace(列名, '被替换部分','替换后的结果') — device_id, replace(blog_url,'http:/url/','') as user_name
  • 截取法 substr(列名, start_point, length可选参数) — device_id, substr(blog_url,11,length(blog_url)-10) as user_name
  • 删除法 trim('被删除字段' from 列名) — device_id, trim('http:/url/' from blog_url) as user_name
  • 字段切割法 substring_index(string, '切割标志', n)
    • 当n大于0时取第n个分隔符(n从1开始)之后全部内容
    • 当n小于0时取倒数第n个分隔符(n从-1开始)之前全部内容

    — device_id, substring_index(blog_url,'/',-1) as user_name

from user_submit;

https://www.w3schools.com/sql/

PROCEDURE, FUNCTION, TRIGGER

Trigger

Procedure and Function

EXAMPLES
  • Function
    CREATE FUNCTION CalculateAverageSalary(@departmentName varchar(50))
    RETURNS MONEY
    AS
    BEGIN
        DECLARE @averageSalary MONEY;
        SELECT @averageSalary = AVG(Salary)
        FROM Employees
        WHERE Department = @departmentName;
        RETURN @averageSalary;
    END;
    /*
    上面的Function用于计算特定部门的员工平均薪资。
    它接受一个部门名称departmentName作为输入参数,并返回一个平均薪资值。
    在函数体内,我们使用SELECT语句查询Employees表中属于特定部门的员工的薪资,并计算平均值。
    */
  • Procedure
    CREATE PROCEDURE DeleteEmployee(@employeeId int)
    AS
    BEGIN
        DELETE FROM Employees
        WHERE EmployeeID = @employeeId;
    END;
    /*
    上面的Procedure用于删除Employees表中指定EmployeeID的员工记录。
    它接受一个EmployeeID作为输入参数,并执行一个DELETE语句来删除对应记录。
    在Procedure中,我们没有返回任何值,而是通过执行DELETE语句来删除数据。
    */

EVENT

在SQL中,Event是指一种特殊的数据库对象,用于定期执行指定的SQL语句或者存储过程。Event对象可以被视为与任务调度或计划程序类似的功能,它们可以自动化执行一些数据库操作。

一个Event对象由以下几个部分组成:

通过使用Event对象,数据库管理员可以自动化执行某些任务或操作,例如定期清理数据库、备份数据、生成报表等。

在MySQL中,可以使用CREATE EVENT语句创建Event对象,语句如下所示。
CREATE EVENT my_event
ON SCHEDULE
EVERY 1 DAY
STARTS '2023-03-22 00:00:00'
DO
BEGIN
   DELETE FROM my_table WHERE timestamp < DATE_SUB(NOW(), INTERVAL 7 DAY);
END;
/*
上面的示例创建了一个名为“my_event”的Event对象,它将在每天执行一次,并删除“mytable”表中7天之前的记录。可以看到,我们在Event对象中使用了SQL语句来执行具体的操作。
*/

VIEW

View是指一种虚拟表格,是通过对一个或多个基础表执行SELECT语句而创建的。View本身不存储数据,而是根据查询条件从基础表中获取数据,并提供了一种方便和安全的方式来访问和处理数据。

View的主要特点包括:

View的创建可以使用CREATE VIEW语句,语句如下所示。
CREATE VIEW my_view AS
SELECT column1, column2, ...
FROM my_table
WHERE condition;
/*
上面的示例创建了一个名为“my_view”的View对象,
它基于“my_table”表格执行一个SELECT查询,只返回满足特定条件的列。*/

/* “my_view”现在可以像表格一样使用SELECT语句查询数据,例如:*/
SELECT column1, column2, ...
FROM my_view
WHERE condition;

MySQL索引(Index)

什么是索引?

索引的优缺点

优点

缺点

语句

CREATE TABLE table_name[col_name data type]
[unique|fulltext][index|key][index_name](col_name[length])[asc|desc]
  1. unique | fulltext 为可选参数,分别表示唯一索引、全文索引
  2. index和key为同义词,两者作用相同,用来指定创建索引
  3. col_name为需要创建索引的字段列,该列必须从数据表中该定义的多个列中选择
  4. index_name指定索引的名称,为可选参数,如果不指定,默认col_name为索引值
  5. length为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度
  6. asc或desc指定升序或降序的索引值存储

索引类型

  1. 普通索引

    是最基本的索引,它没有任何限制。

    它有以下几种创建方式
    /* 直接创建索引 */
    CREATE INDEX index_name ON table(column(length))
    
    /* 修改表结构的方式添加索引 */
    ALTER TABLE table_name ADD INDEX index_name ON (column(length))
    
    /* 创建表的时候同时创建索引 */
    CREATE TABLE `table` (
        `id` int(11) NOT NULL AUTO_INCREMENT ,
        `title` char(255) CHARACTER NOT NULL ,
        `content` text CHARACTER NULL ,
        `time` int(10) NULL DEFAULT NULL ,
        PRIMARY KEY (`id`),
        INDEX index_name (title(length))
    )
  2. 唯一索引

    与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

    它有以下几种创建方式
    /* 创建唯一索引 */
    CREATE UNIQUE INDEX indexName ON table(column(length))
    
    /* 修改表结构 */
    ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))
    
    /* 创建表的时候直接指定 */
    CREATE TABLE `table` (
        `id` int(11) NOT NULL AUTO_INCREMENT ,
        `title` char(255) CHARACTER NOT NULL ,
        `content` text CHARACTER NULL ,
        `time` int(10) NULL DEFAULT NULL ,
        UNIQUE indexName (title(length))
    );
  3. 主键索引

    是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。

    一般是在建表的时候同时创建主键索引。
    CREATE TABLE `table` (
        `id` int(11) NOT NULL AUTO_INCREMENT ,
        `title` char(255) NOT NULL ,
        PRIMARY KEY (`id`)
    );

    在 MySQL 的 InnoDB 的表中,当没有显示的指定表的主键时,InnoDB 会自动先检查表中是否有唯一索引且不允许存在 null 值的字段,如果有,则选择该字段为默认的主键,否则 InnoDB 将会自动创建一个 6Byte 的自增主键。

  4. 组合索引

    指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。

    使用组合索引时遵循最左前缀集合。
    ALTER TABLE `table` ADD INDEX name_city_age (name,city,age);
  5. 全文索引

    主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like。它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。

    值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。

    CREATE FULLTEXT INDEX index_content ON table_name(content)

正确使用索引的建议

见如下八点
  1. 选择合适的字段创建索引
    1. 不为 NULL 的字段 :索引字段的数据应该尽量不为 NULL,因为对于数据为 NULL 的字段,数据库较难优化。如果字段频繁被查询,但又避免不了为 NULL,建议使用 0,1,true,false 这样语义较为清晰的短值或短字符作为替代。
    2. 被频繁查询的字段 :我们创建索引的字段应该是查询操作非常频繁的字段。
    3. 被作为条件查询的字段 :被作为 WHERE 条件查询的字段,应该被考虑建立索引。
    4. 频繁需要排序的字段 :索引已经排序,这样查询可以利用索引的排序,加快排序查询时间。
    5. 被经常频繁用于连接的字段 :经常用于连接的字段可能是一些外键列,对于外键列并不一定要建立外键,只是说该列涉及到表与表的关系。对于频繁被连接查询的字段,可以考虑建立索引,提高多表连接查询的效率。
  2. 被频繁更新的字段应该慎重建立索引

    虽然索引能带来查询上的效率,但是维护索引的成本也是不小的。 如果一个字段不被经常查询,反而被经常修改,那么就更不应该在这种字段上建立索引了。

  3. 限制每张表上的索引数量

    索引并不是越多越好,建议单张表索引不超过 5 个。索引可以提高效率同样可以降低效率。索引可以增加查询效率,但同样也会降低插入和更新的效率,甚至有些情况下会降低查询效率。因为 MySQL 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估,以生成出一个最好的执行计划,如果同时有很多个索引都可以用于查询,就会增加 MySQL 优化器生成执行计划的时间,同样会降低查询性能。

  4. 尽可能的考虑建立联合索引而不是单列索引

    因为索引是需要占用磁盘空间的,可以简单理解为每个索引都对应着一颗 B+树。如果一个表的字段过多,索引过多,那么当这个表的数据达到一个体量后,索引占用的空间也是很多的,且修改索引时,耗费的时间也是较多的。如果是联合索引,多个字段在一个索引上,那么将会节约很大磁盘空间,且修改数据的操作效率也会提升。

  5. 注意避免冗余索引

    冗余索引指的是索引的功能相同,能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引。如(name,city)和(name)这两个索引就是冗余索引,能够命中前者的查询肯定是能够命中后者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。

  6. 字符串类型的字段使用前缀索引代替普通索引

    前缀索引仅限于字符串类型,较普通索引会占用更小的空间,所以可以考虑使用前缀索引带替普通索引。

  7. 避免索引失效

    索引失效也是慢查询的主要原因之一,常见的导致索引失效的情况有下面这些:

    • 使用 SELECT * 进行查询;
    • 创建了组合索引,但查询条件未准守最左匹配原则;
    • 在索引列上进行计算、函数、类型转换等操作;
    • % 开头的 LIKE 查询比如 like '%abc';
    • 查询条件中使用 or,且 or 的前后条件中有一个列没有索引,涉及的索引都不会被使用到;
    • 发生隐式转换open in new window;
  8. 删除长期未使用的索引

    删除长期未使用的索引,不用的索引的存在会造成不必要的性能损耗。

    MySQL 5.7 可以通过查询 sys 库的 schema_unused_indexes 视图来查询哪些索引从未被使用。

MySQL事务(Transaction)

MySQL事务 - 成九 - 博客园

一、事务(Transaction)及其ACID属性 事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性:1.原子性(Atomicity):事务是一个原子操作单

MySQL锁(Lock)

MySQL锁详解 - 成九 - 博客园

一、概述 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外。My

WINDOW FUNCTION

  1. Window Function是指一种用于对结果集执行计算操作的函数,它可以在不影响查询结果的情况下对查询结果集中的某些行进行计算和排名。
  2. Window Function的主要特点包括:
    • Window Function通过在查询结果集的特定列或窗口中执行计算操作来实现功能。常见的Window Function包括SUM、AVG、MAX、MIN、ROW_NUMBER等。
    • Window Function可以根据查询结果集中的某些列进行分组、排序、分区等操作,并且可以基于分组和排序的结果执行计算操作。
    • Window Function可以通过OVER子句指定窗口的范围和排序方式,可以使用ROWS或RANGE关键字指定窗口的边界,也可以使用ORDER BY子句指定窗口内的排序方式。
    • Window Function可以用于生成报表、计算比率、排名等各种操作,可以让查询更加灵活和高效。
  3. More Examples
  4. 教学
通俗易懂的学会:SQL窗口函数

一.窗口函数有什么用? 在日常工作中,经常会遇到需要在每组内排名,比如下面的业务需求:排名问题:每个部门按业绩来排名 topN问题:找出每个部门排名前N的员工进行奖励面对这类需求,就需要使用sql的高级功能窗…