数据库面试

目录

1.索引的作用?它的优点缺点是什么?   

2.什么样的字段适合建索引?

3.使用索引查询一定能提高查询的性能吗?为什么?

4.mysql的三大引擎是啥?

5.索引底层用什么实现的

6.在数据库中查询语句速度很慢,如何优化?

7.什么是存储过程?有哪些优缺点?

8.什么是事务?

9.乐观锁和悲观锁是什么?

10.什么是主键?什么是外键?

11.什么是存储过程?用什么来调用?

12.事务的隔离级别有哪些?

13.事务特性(ACID)

14.数据库的三个范式

15.说下常见的数据库有哪些

17.了解sql注入吗?

18.如果一张表有大量的数据,如何处理

19.分库分表

20.主从复制 

21.读写分离

22.用过redis和memcached吗

23.数据库挂了怎么办?

24.讲下慢查询

26.常见的sql优化

1.索引的作用?它的优点缺点是什么?   
创建索引可以大大提高系统的性能

优点:

第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 

第二,可以大大加快 数据的检索速度,这也是创建索引的最主要的原因。 

第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 

第四,在使用分组和排序 子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 

第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能

缺点:

一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 

第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 

第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

2.什么样的字段适合建索引?
    在经常需要搜索的列上,可以加快搜索的速度; 

在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 

在经常用在连接的列上,这 些列主要是一些外键,可以加快连接的速度; 

在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 

在经常需要排序的列上创 建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; 

在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 

3.使用索引查询一定能提高查询的性能吗?为什么?
第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因 为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 

第二,对于那 些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 

第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。 

第四,当修改性能远远大于检索性能时,不应该创建索 引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因 此,当修改性能远远大于检索性能时,不应该创建索引。 

4.mysql的三大引擎是啥?
   1.MyISAM

 特性:①不支持事务。

②表级锁定,并发性能大大降低。

③读写互相阻塞。

  适用场景:

  ①不支持事务。

       ②并发相对较低,表锁定。
      ③执行大量select语句操作的表。

  ④count(*)操作较快。

       ⑤不支持外键。

 注:查询速度快的原因:a.MyISAM存储的直接是文件的offset。b.不用维护mvcc。

2.InnoDB

  特征:①良好的事务支持:支持事务隔离的四个级别。

②行级锁定:使用间隙锁
③外键约束。

④支持丢失数据的自动恢复。

3.Memory

  在内存中,默认使用hash索引,等值条件查找快速快,范围查找慢,断电后数据丢失,但表结构存在

5.索引底层用什么实现的
    索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构。

   本质:索引是数据结构。

   B+Tree与B-Tree的差异在于:

1、B+Tree非叶子节点不存储data,只存储key;

2、所有的关键字全部存储在叶子节点上;

3、每个叶子节点含有一个指向相邻叶子节点的指针,带顺序访问指针的B+树提高了区间查找能力;

4、非叶子节点可以看成索引部分,节点中仅含有其子树(根节点)中的最大(或最小)关键字;

1、MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址;

     MyISAM主索引和辅助索引在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复;

2、InnoDB的数据文件本身就是索引文件,叶节点包含了完整的数据记录,这种索引叫做聚集索引。

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键。

     InnoDB的辅助索引data域存储相应记录主键的值而不是地址;

     辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录

6.在数据库中查询语句速度很慢,如何优化?
1.建索引(a 提高查询检索的性能b 创建唯一索引c 创建主键d

归类)
2.减少表之间的关联
3.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,

应该走索引,把数据量大的表排在前面
4.简化查询字段,没用的字段不要,已经对返回结果的控制,尽

量返回少量数据

  1、对查询进行优化,应尽可能避免全表扫描

     首先应考虑在 where 及 order by 涉及的列上建立索引。 

      建立索引查询

2、写数据语句时尽可能减少表的全局扫描

2.1 减少where 字段值null判断,就会导致引擎放弃使用索引而进行全表扫描

       应该这样去设置(也就是在没有值时,我们在存数据库时自动默认给个o值,而不是什么都不写):

2.2 应尽量避免在 where 子句中使用!=或<>操作符

应尽量避免在 where 子句中使用 or 来连接条件 ,可以用union代替

2.4 in 和 not in 也要慎用  可以换成 between

2.5 少使用模糊匹配 like  %不要在前

2.6 应尽量避免在 where 子句中对字段进行表达式(函数),运算操作

2.7 任何地方都不要使用*通配符去查询所有

SELECT * FROM "tb_real_time_car" where rowid/4 =100;

以通配符*去查询所有数据,这样做也是非常耗时的,我们应该需要什么字段就查询什么字段.

7.什么是存储过程?有哪些优缺点?
 就是一些编译好了的SQL语句,这些SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后给这些代码块取一个名字,在用到这个功能的时候调用即可。

存储过程详解参考:

http://www.cnblogs.com/knowledgesea/archive/2013/01/02/2841588.html

优点:

存储过程是一个预编译的代码块,执行效率比较高

存储过程在服务器端运行,减少客户端的压力

允许模块化程序设计,只需要创建一次过程,以后在程序中就可以调用该过程任意次,类似方法的复用

一个存储过程替代大量T_SQL语句 ,可以降低网络通信量,提高通信速率

可以一定程度上确保数据安全

缺点:

调试麻烦(没有像开发程序那样容易)

可移植性不灵活(因为存储过程依赖于具体的数据库

8.什么是事务?
事务的概念

含义:事务由单独单元的一个或者多个sql语句组成,在这个单元中,每个mysql语句时相互依赖的。而整个单独单元作为一个不可分割的整体,如果单元中某条sql语句一旦执行失败或者产生错误,整个单元将会回滚,也就是所有受到影响的数据将会返回到事务开始以前的状态;如果单元中的所有sql语句均执行成功,则事务被顺利执行。

事务的属性

原子性:一个事务不可在分割,要么都执行要么都不执行。

一致性:一个事务的执行会使数据从一个一致状态切换到另一个一致的状态。

隔离性:一个事务的执行不受其他事物的干扰

持久性: 一个事务一旦提交,则会永久的改变数据库的数据

事务的创建

隐式事务:事务没有明显的开启和结束的标记

显式事务:事务具有明显的开启和结束的标记 前提:必须先设置自动提交功能为禁用

9.乐观锁和悲观锁是什么?
当我们要对一个数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。

这种借助数据库锁机制在修改数据之前先锁定,再修改的方式被称之为悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)。

乐观锁

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

两种锁的使用场景

从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

10.什么是主键?什么是外键?
主键、外键和索引的区别?

主键:唯一标识一条记录,不能有重复的,不允许为空

外键:表的外键是另一表的主键, 外键可以有重复的, 可以是空值

索引:该字段没有重复值,但可以有一个空值

作用:

主键:用来保证数据完整性

外键:用来和其他表建立联系用的

索引:是提高查询排序的速度

个数:
主键只能有一个,一个表可以有多个外键,一个表可以有多个索引

11.什么是存储过程?用什么来调用?
简单版的:存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。 调用: 1)可以用一个命令对象来调用存储过程。 2)可以供外部程序调用,比如:java程序。

存储过程是一个预编译的SQL语句,比如一些场景的sql比较复杂,并且需要经常使用或者多次使用的。存储过程的优点是说只需创建一次编译一次,以后在该程序中就可以多次直接调用。如果一个sql是经常需要操作的,并且逻辑不容易改变,使用存储过程比单纯SQL语句执行要快,因为sql每次查询而且都需要编译。而且网络开销也大,存储过程只需要传一个名字,在数据库调用就行了,而且这样程序可移植高。

优势:

1、提高性能

SQL语句在创建过程时进行分析和编译。 存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的存储计划,这样,在执行过程时便可节省此开销。

2、降低网络开销

存储过程调用时只需用提供存储过程名和必要的参数信息,从而可降低网络的流量。

3、便于进行代码移植

数据库专业人员可以随时对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的提高了程序的可移植性。

4、更强的安全性

1)系统管理员可以对执行的某一个存储过程进行权限限制,避免非授权用户对数据的访问

2)在通过网络调用过程时,只有对执行过程的调用是可见的。 因此,恶意用户无法看到表和数据库对象名称、嵌入自己的 Transact-SQL 语句或搜索关键数据。

3)使用过程参数有助于避免 SQL 注入攻击。 因为参数输入被视作文字值而非可执行代码,所以,攻击者将命令插入过程内的 Transact-SQL 语句并损害安全性将更为困难。

4)可以对过程进行加密,这有助于对源代码进行模糊处理。 

劣势:

1、存储过程需要专门的数据库开发人员进行维护,但实际情况是,往往由程序开发员人员兼职

2、设计逻辑变更,修改存储过程没有SQL灵活 

应该是可以用一个命令对象来调用存储过程

12.事务的隔离级别有哪些?
1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

  小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

MySQL事务隔离级别

事务隔离级别

脏读

不可重复读

幻读

读未提交(read-uncommitted)

不可重复读(read-committed)

可重复读(repeatable-read)

串行化(serializable)

  mysql默认隔离级别为repeatable-read

13.事务特性(ACID)
   1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

   2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

   3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

   4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚

14.数据库的三个范式
1、1NF:字段不可分,每个字段是原子级别的,上节中看到第一个字段为ID,它就是ID不能在分成两个字段了,不能说我要把这个人的ID、名称、班级号都塞在一个字段里面,这个是不合适的,对以后的应用造成很大影响;

2、2NF:有主键,非主键字段依赖主键,ID字段就是主键,它能表示这一条数据是唯一的,有的读者朋友记性很好,“unique”表示唯一的、不允许重复的,确实它经常会修饰某个字段,保证该字段唯一性,然后再设置该字段为主键;

3、3NF:非主键字段不能相互依赖,这个怎么理解呢,比如student表,班级编号受人员编号的影响,如果在这个表中再插入班级的班主任、数学老师等信息,你们觉得这样合适吗?肯定不合适,因为学生有多个,这样就会造成班级有多个,那么每个班级的班主任、数学老师都会出现多条数据,而我们理想中的效果应该是一条班级信息对应一个班主任和数学老师,这样更易于我们理解,这样就形成class表,那么student表和class表中间靠哪个字段来关联呢,肯定是通过“classNo”,这个字段也叫做两个表的外键

15.说下常见的数据库有哪些
 

大类

类别

前3~5名

说明

SQL

关系数据库

Oracle、MySQL/MariaDB、SQL Server、PostgrcSQL、 DB2

遵循“表一记录”模型。按行存储在文件中(先第 1 行,然后第 2 行……)

NoSQL

时序数据库

InfluxDB、RRDtool、Graphite、OpcnTSDB、Kdb+

存储时间序列数据,每条记录都带有时间戳。如存储从感应器采集到的数据

键/值数据库

Redis、Memcached、Riak KV、Hazelcast、Ehcache

遵循“键——值”模型,是最简单的数据库管理系统

文档数据库

MongoDB、Couchbase、Amazon DynamoDB、CouchDB、MarkLogic

无固定结构,不同的记录允许有不同的列数和列类型。列允许包含多值,记录允许嵌套

图数椐库

Neo4j、OrientDB、Titan、Virtuoso、ArangoDB

以“点——边”组成的网络(图结构)来存储数据

搜索引擎

Elasticsearch、Solr、Splunk、MarkLogic、Sphinx

存储的目的是为了搜索,主要功能是搜索

对象数据库

Caché、db4o、Versant Object Database、ObjcctStore、Matisse

受面向对象编程语言的启发,把数据定义为对象并存储在数据库中,包括对象之问的关系,如继承

宽列数据库

Cassandra、HBase、Accumulo

按照列(由“键——值”对组成的列表)在数据文件中记录数据,以获得更好的请求及遍历效率。一行中的列数允许动态变化,且列的数目可达数百万,每条记录的关键码不同,支持多

16.nosql为啥比sql快?

Key value 在内存去读数据 ,不需要sql编译

Nosql和sql的区别参考:https://blog.csdn.net/aaronthon/article/details/81714528

17.了解sql注入吗?

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。[1] 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击。

1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和
双"-"进行转换等。
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。

参考:http://www.imooc.com/article/22070

18.如果一张表有大量的数据,如何处理

1、索引优化和SQL语句优化是必须的,避免模糊查询和非索引查询,删改操作根据聚集索引进行,删改操作太频繁的话还是需要考虑分表

2、看需求,如果需求不限制,那就分表

分区会增加管理复杂度和成本这个很难理解,分区增加不了多少工作,如果需求要求必须单表,分区是解决在千万到几亿数据量的比较合适的方法

可能更大数据量还是要回到分的路上,但是可能更多考虑分布式

3、我们一般都是把历史数据定期转存其他表(一样的表名后加年月例如TABLE201205)归档~ 
这样该表本年度的查询的压力也小点(90%查询量集中在本年度),即使查询历史数据也不影响性能,强力推荐!

4、 
(1)从结构上来说,分区很有必要,我听过一些培训,微软给客户的建议是一个表如果大小超过50M,那就建议分区了。而且分区几乎是“一次性”的事情,不会增加什么管理成本。 
(2)可以使用归档方式管理历史数据。其实你的数据量不大啦,我以前做银行系统,单表就2亿多,40G的大小。 
(3)优化你的语句和设计。 
(4)结合你的业务去完善结构。有时候可以考虑用空间去换时间。

参考:https://blog.csdn.net/weixin_42476601/article/details/82774940

19.分库分表
读写分离: 不同的数据库,同步相同的数据,分别只负责数据的读和写;

分区: 指定分区列表达式,把记录拆分到不同的区域中(必须是同一服务器,可以是不同硬盘),应用看来还是同一张表,没有变化;

分库:一个系统的多张数据表,存储到多个数据库实例中;

分表: 对于一张多行(记录)多列(字段)的二维数据表,又分两种情形:

(1) 垂直分表: 竖向切分,不同分表存储不同的字段,可以把不常用或者大容量、或者不同业务的字段拆分出去;

(2) 水平分表(最复杂): 横向切分,按照特定分片算法,不同分表存储不同的记录。

2、MySQL为什么分库分表

当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,可能会死在那儿。分表的目的就在于此,减小数据库的负担,缩短查询时间。目前我们系统将近20亿数据每张表最大的接近519w条/表,每条数据大约3k,1131M将近1G的表数据。查询经常超时,单条SQLcount(*)查询时间达到最大260ms,0.26s。标准是超过0.1s的数据为慢SQL。

3、如何分库分表

维度:

 垂直拆分

 垂直分库(根据业务不同与微服务类似单独服务对应单独库)

 垂直分表

 垂直分表是基于数据库中的”列”进行,某个表字段较多,可以新建一张扩展表,将不经常用或字段长度较大的字段拆分出去到扩展表中。在字段很多的情况下(例如一个大表有100多个字段),通过”大表拆小表”,更便于开发与维护,也能避免跨页问题,MySQL底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘IO,从而提升了数据库性能。

拆分字段的操作建议在数据库设计阶段就做好。如果是在发展过程中拆分,则需要改写以前的查询语句,会额外带来一定的成本和风险,建议谨慎

 垂直拆分优缺点:

 优点:

解决业务系统层面的耦合,业务清晰

与微服务的治理类似,也能对不同业务的数据进行分级管理、维护、监控、扩展等

高并发场景下,垂直切分一定程度的提升IO、数据库连接数、单机硬件资源的瓶颈

 缺点:

部分表无法join,只能通过接口聚合方式解决,提升了开发的复杂度

依然存在单表数据量过大的问题(需要水平切分)

分布式事务处理复杂

 水平拆分(根据表内数据内在的逻辑关系,将同一个表按不同的条件分散到多个数据库或多个表中,每个表中只包含一部分数据,从而使得单个表的数据量变小,达到分布式的效果。)

 优缺点:

 优点:

不存在单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力

应用端改造较小,不需要拆分业务模块

“冷热数据分离”实现方案

 缺点:

跨分片事务难以保证

跨分片的复杂查询如join关联查询

数据多次扩展难度和维护量极大

 数据分片规则

 冷热数据隔离(近6个月或者1年的数据作为热数据,历史数据作为冷数据再进行时间维度拆分)

 地域区域或者其他拆分方式

 userNo范围分表,比如0~500w用户在user1表,501w-1000w在user2表等

 优点:

单表大小可控

天然便于水平扩展,后期如果想对整个分片集群扩容时,只需要添加节点即可,无需对其他分片的数 据进行迁移

使用分片字段进行范围查找时,连续分片可快速定位分片进行快速查询,有效避免跨分片查询的问题

 缺点:

热点数据成为性能瓶颈。连续分片可能存在数据热点

 hash取模mod的切分方式

 优点:根据主键id进行数据切分,达到数据均匀分布,使用一致性hash算法可以避免后期扩展问题

 缺点:跨分片聚合操作

中间件:

可以参考:https://blog.csdn.net/wolf_love666/article/details/82773300

20.主从复制 
数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。

架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的评率,提高单个机器的I/O性能。

读写分离,使数据库能支持更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。

参考:https://blog.csdn.net/weixin_43879074/article/details/88525006

主从复制的原理:https://baijiahao.baidu.com/s?id=1617888740370098866&wfr=spider&for=pc

21.读写分离
在开发工作中,有时候会遇见某个sql 语句需要锁表,导致暂时不能使用读的服务,这样就会影响现有业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。

参考:https://blog.csdn.net/u013421629/article/details/78793966

22.用过redis和memcached吗
redis和memcache这两个作为目前市面上最火的两款缓存,在内存中存储数据,防止高并发影响数据库性能,减少数据库压力,并提高查询速度

从数据结构上来说,redis在kv模式上,支持5中数据结构,String、list、hash、set、zset,并支持很多相关的计算,比如排序、阻塞等,而memcache只支持kv简单存储。所以当你的缓存中不只需要存储kv模型的数据时,redis丰富的数据操作空间,绝对是非常好的选择,另外说一句,利用redis可以高效的实现类似于单集群下的阻塞队列、锁及线程通信等功能。

从可靠性的角度来说,redis支持持久化,有快照和AOF两种方式,而memcache是纯的内存存储,不支持持久化的。

从内存管理方面来说,redis也有自己的内存机制,redis采用申请内存的方式,会把带过期时间的数据存放到一起,redis理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上。而memcache把所有的数据存储在物理内存里。memcache使用预分配池管理,会提前把内存分为多个slab,slab又分成多个不等大小的chunk,chunk从最小的开始,根据增长因子增长内存大小。redis更适合做数据存储,memcache更适合做缓存,memcache在存储速度方面也会比redis这种申请内存的方式来的快。

从数据一致性来说,memcache提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。 redis是串行操作,所以不用考虑数据一致性的问题。

从IO角度来说,选用的I/O多路复用模型,虽然单线程不用考虑锁等问题,但是还要执行kv数据之外的一些排序、聚合功能,复杂度比较高。memcache也选用非阻塞的I/O多路复用模型,速度更快一些。

从线程角度来说,memcahce使用多线程,主线程listen,多个worker子线程执行读写,可能会出现锁冲突。redis是单线程的,这样虽然不用考虑锁对插入修改数据造成的时间的影响,但是无法利用多核提高整体的吞吐量,只能选择多开redis来解决。

从集群方面来说,redis天然支持高可用集群,支持主从,而memcache需要自己实现类似一致性hash的负载均衡算法才能解决集群的问题,扩展性比较低。

另外,redis集成了事务、复制、lua脚本等多种功能,功能更全。redis功能这么全,是不是什么情况下都使用redis就行了呢?

非也,redis确实比memcache功能更全,集成更方便,但是memcache相比redis在内存、线程、IO角度来说都有一定的优势,可以利用cpu提高机器性能,在不考虑扩展性和持久性的访问频繁的情况下,只存储kv格式的数据,建议使用memcache,memcache更像是个缓存,而redis更偏向与一个存储数据的系统。但是,觉得不要拿redis当数据库用!!

23.数据库挂了怎么办?
 Mysql 的连接通常是一个请求占用一个连接,如果该请求(update,insert,delete,select)长时间没有执行完毕,则会造成连接的堆积,迅速的消耗完数据库的连接数,这个时候技术支持人员就要登录数据库进行排序,看看到底是那些sql 占用了连接;

通过SHOW FULL PROCESSLIST;查看数据库中有长时间没有执行完成的sql,一直占用着连接没有释放,而应用的请求一直持续不断的涌入数据库,这个时候数据库的连接很快就被使用完;所以这个时候需要排查为什么这些sql 为什么长时间没有执行完毕,是索引没有创建好,还是sql执行耗时严重。

最后排查出来一个sql运行之后mysql直接就卡死,然后贴到本地开始走在了优化sql的路上,该加的索引都加上了还是不行,最后将问题锁定了。

24.讲下慢查询
>o.1s 为慢查询

慢SQL的系统表现

首先,我们如何判别系统中遇到了SQL慢查询问题?个人认为慢SQL有如下三个特征:

1,数据库CPU负载高。一般是查询语句中有很多计算逻辑,导致数据库cpu负载。

2,IO负载高导致服务器卡住。这个一般和全表查询没索引有关系。

3,查询语句正常,索引正常但是还是慢。如果表面上索引正常,但是查询慢,需要看看是否索引没有生效。

开启SQL慢查询的日志

如果你的系统出现了上述情况,并且你不是用的阿里云的RDS这样的产品,那么下一步就需要打开Mysql的慢查询日志来进一步定位问题。MySQL 提供了慢查询日志,这个日志会记录所有执行时间超过 long_query_time(默认是10s)的 SQL 及相关的信息。

要开启日志,需要在 MySQL 的配置文件 my.cnf 的 [mysqld] 项下配置慢查询日志开启,如下所示:

[mysqld]slow_query_log=1

slow_query_log_file=/var/log/mysql/log-slow-queries.log

long_query_time=2

基于本文的思路,关于SQL慢查询的解决可以按照以下的步骤执行:

1. 打开慢日志查询,确定是否有SQL语句占用了过多资源,如果是,在不改变业务原意的前提下,对insert、group by、order by、join等语句进行优化。

2. 考虑调整MySQL的系统参数: innodb_buffer_pool_size、innodb_log_file_size、table_cache等。

3. 确定是否是因为高并发引起行锁的超时问题。

4. 如果数据量过大,需要考虑进一步的分库分表

25.分布式数据库的优缺点

26.常见的sql优化
 
 

参考:https://blog.csdn.net/qq1404510094/article/details/80249770?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3

27 redis和memcached的区别和使用场景

说到缓存技术,只要有一定经验的开发人员,肯定会想到redis和memcached这两个缓存技术,下面就来说一说这两个缓存技术的区别和使用场景。

区别

1、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等;

2、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储;

3、虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;

4、过期策略–memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10;

5、分布式–设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;

6、存储数据安全–memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);

7、灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;

8、Redis支持数据的备份,即master-slave模式的数据备份;

9、应用场景不一样:Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等。

使用场景

1、如果有持久方面的需求或对数据类型和处理有要求的应该选择redis。

2、如果简单的key/value 存储应该选择memcached。

Eg

在电子商务类的网站中,一般都有分类,然后还有搜索结果列表。

针对这种情况下,我们对分类的数据,可以使用memcached,因为分类数据一般不会改变,读多写少,直接存储在memcached中,每次查询都只需要从memcached中获取就可以了。

————————————————

原文链接:https://blog.csdn.net/u010398838/article/details/79995636

redis取代memcached的原因。:https://www.jianshu.com/p/21e9f2f6a0b2

28. n
————————————————
原文链接:https://blog.csdn.net/u013749274/java/article/details/105527539

原文地址:https://www.cnblogs.com/zhaoshaopeng/p/13306679.html