MySQL三层结构、用户权限、索引设计原则

时间:2022-11-13 16:33:03

一.守护进程是什么?

Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。

  守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户(root)权限运行,因为它们要使用特殊的端口(1-1024)或访问某些特殊的资源。

  一个守护进程的父进程是init进程,因为它真正的父进程在fork出子进程后就先于子进程exit退出了,所以它是一个由init继承的孤儿进程。守护进程是非交互式程序,没有控制终端,所以任何输出,无论是向标准输出设备stdout还是标准出错设备stderr的输出都需要特殊处理。守护进程的名称通常以d结尾,比如sshd、xinetd、crond等

mysqld(后台进程,守护进程) 启动时:

  1、自动派生 master thread ------生成工作线程(read write 等)

  2、预分配内存区域

实例是什么: 后台进程 +线程 +预分配内存区域

二.mysqld的三层结构:

SQL语言是集数据定义和数据操作为一体的数据库语言。是一种通用的/功能强大的关系数据库语言,它的主要功能是数据查询、数据操作、数据定义

和数据控制。

SQL的特点:

(1)综合统一

(2)高度非过程化

(3)面向集合的操作方式

SQL类型:

 (1)DDL:数据定义子语言(对库和表的定义)

 (2)DML:数据操作子语言

 (3)DCL:数据控制子语言

SQL的两种使用方式:一是在终端键入SQL命令直接操作数据库;二是将SQL嵌入高级语言中去。

SQL支持关系数据库的三级模式结构,其中视图对应外模式、基本表对应模式、存储文件对应内模式。

=============================================

||ps:MySQL数据库的核心,关系到数据库性能,运维相关||

=============================================

结构化的查询语言:select * from user;

执行该语句时:

  1、连接层:

      验证 该用户的用户名、密码、端口号,并提供连接

         连接层作用: 1、提供连接协议(TCP/IP socket)

                2. 验证功能身份信息

                3、提供一个专门的连接线程(接受用户发来的SQL语句,并在执行完成之后返回最终结果,但不能读和执行sql语句,会将SQL语句丢给下一层)

  2、SQL层 (与优化相关)
        1、接收上层发来的SQL
        2、语法检查模块进行语法检查
        3、语义检查模块检查语义,分辨SQL语句的类型,将不同种类的语句,交给不同的解析器
        4、解析器接收到SQL语句,进行解析操作,得到语句的执行计划(explain)
        5、优化器负责基于 “成本” 找到执行开销最小的执行计划 (优化SQL,让优化器选择最有的执行方式,了解优化器的规则)
        6、执行器基于优化器的选择,执行SQL语句,并得到获取数据的方法,交由下一层继续处理
        7、接收存储引擎层取到的二进制数据,结构化成表
        8、查询缓存:SQL语句的 哈希值+数据结果(在修改类业务操作很多的情况下,并不适用)---》redis Tair(memcached)   3、存储引擎层
        1、根据上层获取数据的方法,将数据提取出来
        2、重新再交给SQL层

三、用户权限

1.权限分类:

ALL privileges(所有权限)

  SELECT, INSERT, UPDATE, DELETE, CREATE, RELOAD,

  SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER,

  SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, DROP

  LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT,

  CREATE VIEW, SHOW VIEW, CREATE ROUTINE,

  ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE

2、开发人员可能会用到的权限

CRESTE、 UPDATE、 INSERT、  SELECT、  CREATE VIEW、  CREATE ROUTINE、     SHOW VIEW 、CREATE TEMPORARY TABLES、  ALTER

3、用户组成:

  用户名@‘主机范围’
  用户名通常和数据库的名字保持一致
  主机范围被称之为白名单

4、主机范围:

  即IP地址范围,有如下几种写法:

10.0.0.200          -------->指定就这一个
aaa.o.o.% -------> 10.0.0.1--10.0.0.254 范围的ip地址
10.0.0.5% -------> 10.0.0.50-- 10.0.0.59
% ------>所有的地址都可以

5、权限作用范围

*.*     ------->所有库的所有表
py.*  ------->py库的所有表
bbs.*  ------->bbs库的所有表
py.t1  ------->py库的t1表

6、设置权限的语句

grant 权限 on 权限作用范围 to 用户 identified by '密码';

三、索引

1、什么是索引?

索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。 索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。 但是索引又不是越多越好。倘若索引太多,应用程序的性能可能会受到影响。而索引太少,对查 询性能又会产生影响,要找到一个平衡点,这对应用程序的性能至关重要。

2.索引的原理

本质都是:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。 数据库也是一样,但显然要复杂的多,因为不仅面临着等值查询,还有范围查询(>、<、between、in)、模糊查询(like)、并集查询(or)等等。

3.磁盘IO与预读磁盘IO:

磁盘读取数据靠的是机械运动,每次读取数据花费的时间可以分为寻道时间、旋转延迟、传输时间三个部分。

寻道时间指的是磁臂移动到指定磁道所需要的时间,主流磁盘一般在5ms以下; 旋转延迟就是我们经常听说的磁盘转速,比如一个磁盘7200转,表示每分钟能转7200次,也就是说1秒钟能转120次,旋转延迟就是1/120/2 = 4.17ms; 传输时间指的是从磁盘读出或将数据写入磁盘的时间,一般在零点几毫秒,相对于前两个时间可以忽略不计。那么访问一次磁盘的时间,即一次磁盘IO的时间约等于5+4.17 = 9ms左右。

听起来还挺不错的,但要知道一台500 -MIPS(Million Instructions Per Second)的机器每秒可以执行5亿条指令,因为指令依靠的是电的性质,换句话说执行一次IO的时间可以执行约450万条指令,数据库动辄十万百万乃至千万级数据,每次9毫秒的时间,那简直就是个灾难。

预读:当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内,因为局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会被访问到。每一次IO读取的数据我们称之为一页(page)。具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助。

4.聚集索引和辅助索引

在数据库中,B+树的高度一般都在2~4层,这也就是说查找某一个键值的行记录时最多只需要2到4次IO,这倒不错。因为当前一般的机械硬盘每秒至少可以做100次IO,2~4次的IO意味着查询时间只需要0.02~0.04秒。

数据库中的B+树索引可以分为聚集索引(clustered index)和辅助索引(secondary index),

聚集索引与辅助索引相同的是:不管是聚集索引还是辅助索引,其内部都是B+树的形式,即高度是平衡的,叶子结点存放着所有的数据。

聚集索引与辅助索引不同的是:叶子结点存放的是否是一整行的信息。

(1)聚集索引

#InnoDB存储引擎表示索引组织表,即表中数据按照主键顺序存放。而聚集索引(clustered index)就是按照每张表的主键构造一棵B+树,同时叶子结点存放的即为整张表的行记录数据,
也将聚集索引的叶子结点称为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。同B+树数据结构一样,每个数据页都通过一个双向链表来进行链接。 #如果未定义主键,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚簇索引。 #如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作为聚簇索引。 #由于实际的数据页只能按照一棵B+树进行排序,因此每张表只能拥有一个聚集索引。在多少情况下,查询优化器倾向于采用聚集索引。因为聚集索引能够在B+树索引的叶子节点上直接找到
数据。此外由于定义了数据的逻辑顺序,聚集索引能够特别快地访问针对范围值得查询。

聚集索引的好处之一:它对主键的排序查找和范围查找速度非常快,叶子节点的数据就是用户所要查询的数据。如用户需要查找一张表,查询最后的10位用户信息,由于B+树索引是双向链表,所以用户可以快速找到最后一个数据页,并取出10条记录

聚集索引的好处之二:范围查询(range query),即如果要查找主键某一范围内的数据,通过叶子节点的上层中间节点就可以得到页的范围,之后直接读取数据页即可。

(2)辅助索引

表中除了聚集索引外其他索引都是辅助索引(Secondary Index,也称为非聚集索引),与聚集索引的区别是:辅助索引的叶子节点不包含行记录的全部数据。

叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含一个书签(bookmark)。该书签用来告诉InnoDB存储引擎去哪里可以找到与索引相对应的行数据。

由于InnoDB存储引擎是索引组织表,因此InnoDB存储引擎的辅助索引的书签就是相应行数据的聚集索引键。

辅助索引的存在并不影响数据在聚集索引中的组织,因此每张表上可以有多个辅助索引,但只能有一个聚集索引。当通过辅助索引来寻找数据时,InnoDB存储引擎会遍历辅助索引并通过叶子
级别的指针获得只想主键索引的主键,然后再通过主键索引来找到一个完整的行记录。

5.索引的功能

1)加速查找
2)mysql中的primary key,unique,联合唯一也都是索引,这些索引除了加速查找以外,还有约束的功能

6.常用索引

普通索引INDEX:加速查找

唯一索引:
-主键索引PRIMARY KEY:加速查找+约束(不为空、不能重复)
-唯一索引UNIQUE:加速查找+约束(不能重复) 联合索引:
-PRIMARY KEY(id,name):联合主键索引
-UNIQUE(id,name):联合唯一索引
-INDEX(id,name):联合普通索引

7.两大索引类型

(一)Hash 索引
  哈希索引只有Memory, NDB两种引擎支持,Memory引擎默认支持哈希索引,如果多个hash值相同,出现哈希碰撞,那么索引以链表方式存储。但是,Memory引擎表只对能够
适合机器的内存的切实有限的数据集。
  要使InnoDB或MyISAM支持哈希索引,可以通过伪哈希索引来实现,叫自适应哈希索引。主要通过增加一个字段,存储hash值,将hash值建立索引,在插入和更新的时候,建
立触发器,自动添加计算后的hash到表里。 (二)fulltext 全文索引(B树)
cluster indexes 聚集索引 ,随机IO变成顺序IO
辅助索引 ------>人为管控的:unique 普通的 index (三)前缀索引和联合索引
前缀索引:根据字段的前N个字符建立索引
  alter table student add note varchar(200);
  alter table student add index idx_note(note(10)); 联合索引:多个字段建立一个索引。
  联合主键是联合索引的特殊形式:alter table people add index idx(a,b,c);
  特点:前缀生效特性。
    a,ab,abc,ac 可以走索引或部分走索引(5.6之后 ac 可以走主键索引)
    b bc c ca ba 不走索引。
  原则:把最常用来作为条件查询的列放在前面。 (四)主键索引
  只能有一个主键。
  主键索引:列的内容是唯一值,例如学号.
  表创建的时候至少要有一个主键索引,最好和业务无关。 (五)普通索引
  加快查询速度,工作中优化数据库的关键。
  在合适的列上建立索引,让数据查询更高效。
    create index index_name on test(name);
    alter table test add index index_name(name);
  在where条件关键字后面的列建立索引才会加快查询速度.
    select id,name from test where state=1 order by id group by name; (六)唯一索引
  内容唯一,但不是主键。
    create unique index index_name on test(name);

8.创建/删除索引

#方法一:创建表时
  CREATE TABLE 表名 (
字段名1 数据类型 [完整性约束条件…],
字段名2 数据类型 [完整性约束条件…],
[UNIQUE | FULLTEXT | SPATIAL ] INDEX | KEY
[索引名] (字段名[(长度)] [ASC |DESC])
); #方法二:CREATE在已存在的表上创建索引
CREATE [UNIQUE | FULLTEXT | SPATIAL ] INDEX 索引名
ON 表名 (字段名[(长度)] [ASC |DESC]) ; #方法三:ALTER TABLE在已存在的表上创建索引
ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL ] INDEX
索引名 (字段名[(长度)] [ASC |DESC]) ; #删除索引:DROP INDEX 索引名 ON 表名字;

四、数据库索引的设计原则

为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引。那么索引设计原则又是怎样的?

1.选择唯一性索引
  唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。
  例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度。 2.为经常需要排序、分组和联合操作的字段建立索引
  经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。 3.为常作为查询条件的字段建立索引
  如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高整个表的查询速度。 4.限制索引的数目
  索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。 5.尽量使用数据量少的索引
  如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。 6.尽量使用前缀来索引
  如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。 7.删除不再使用或者很少使用的索引
  表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。 8.小表不应建立索引
  包含大量的列并且不需要搜索非空值的时候可以考虑不建索引

五、不走索引的情况

1.查询结果集是原表的大部分数据——mysql30%以上,oracle20%以上
解决办法:limit控制;数据放在redis中 2.索引失效,统计数据不真实
原因:表内容变化多,索引有自我维护能力
解决办法:重建索引 3.隐式转换。例如,列类型为字符串类型,查询时没有用单引号引起来 4.order by 和 limit 结合使用,如果where 字段,order by字段都是索引,那么有limit索引会使用order by字段所在的索引。没有limit会使用where 条件的索引。 5.time和data的时间格式不一致。
DATE_FORMAT()格式化时间,格式化后的时间再去比较,可能会导致索引失效。 6.<>,not in ,like "%_%"不走索引 在where查询语句中使用表达式,或对字段进行NULL值判断 ,在where查询中使用了or关键字, myisam表能用到索引, innodb不行;(用UNION替换OR,可以使用索引) 7.对小表查询(全表扫描更快