Mysql总结以及相关面试题

InnoDB和MyIASM区别

  1. 事物的支持(InnoDB)、行数的获取(MYIASM)、行级锁和外键约束(InnoDB)、表级锁(MYISAM)、在内存中建立缓冲池,缓冲数据和索引(InnoDB)、全文搜索FULL_TEXT(MYIASM)、保存行数(MYIASM)

  2. 大容量的数据集时趋向于选择Innodb。因为它支持事务处理和故障的恢复。Innodb可以利用数据日志来进行数据的恢复。主键的查询在Innodb也是比较快的。

  3. 大批量的插入语句时(这里是INSERT语句)在MyIASM引擎中执行的比较的快,但是UPDATE语句在Innodb下执行的会比较的快,尤其是在并发量大的时候。

  4. 读大于写操作时(不需要事务)首选MYIASM

两种引擎所使用的索引的数据结构是什么?

都是B+树!

MyIASM引擎,B+树的数据结构中存储的内容实际上是实际数据的地址值。也就是说它的索引和实际数据是分开的,只不过使用索引指向了实际数据。这种索引的模式被称为非聚集索引

Innodb引擎的索引的数据结构也是B+树,只不过数据结构中存储的都是实际的数据,这种索引有被称为聚集索引

聚集索引

顺便提一下聚集索引:
指实际的数据行和相关的键值都保存在一起。每个表只能有一个聚集索引。

覆盖索引可以模拟多个聚集索引。存储引擎负责实现索引,因此不是所有的存储索引都支持聚集索引。当前,SolidDB和InnoDB是唯一支持聚集索引的存储引擎。

优点:

可以把相关数据保存在一起。这样从磁盘上提取几个页面的数据就能把某个用户的数据全部抓取出来。如果没有使用聚集,读取每个数据都会访问磁盘。
  数据访问快。聚集索引把索引和数据都保存到了同一棵B-TREE中,因此从聚集索引中取得数据通常比在非聚集索引进行查找要快。

缺点:

1.聚集能最大限度地提升I/O密集负载的性能。如果数据能装入内存,那么其顺序也就无所谓了。这样聚集就没有什么用处。
  2.插入速度严重依赖于插入顺序。更新聚集索引列是昂贵的,因为强制InnoDB把每个更新的行移到新的位置。
  3.建立在聚集索引上的表在插入新行,或者在行的主键被更新,该行必须被移动的时候会进行分页。
  4.聚集表可会比全表扫描慢,尤其在表存储得比较稀疏或因为分页而没有顺序存储的时候。
  第二(非聚集)索引可能会比预想的大,因为它们的叶子节点包含了被引用行的主键列。第二索引访问需要两次索引查找,而不是一次。 InnoDB的第二索引叶子节点包含了主键值作为指向行的“指针”,而不是“行指针”。 这种策略减少了在移动行或数据分页的时候索引的维护工作。使用行的主键值作为指针使得索引变得更大,但是这意味着InnoDB可以移动行,而无须更新指针。

上面两个问题详细解释见我的另一篇文章:《mysql的存储引擎以及InnoDB和MYISAM的索引结构》

索引

详细解释见我的另一篇博客《Mysql中的索引(联合索引)》
索引类型见另一篇文章:《Mysql中的索引类型》
在这里简单总结一下:
索引的优点:索引可以快速定位某个列中有一个特定值的行:快速定位。即索引用于提高查询效率;降低数据库的排序成本 减少扫描和锁定的数据行数。

索引的缺点:占用磁盘空间,减慢了数据更新速度,增加了磁盘IO。

添加索引语句:

普通索引 添加INDEX
    ALTER TABLE ‘table_name’ ADD INDEX index_name (‘column’);
  主键索引 添加PRIMARY KEY
    ALTER TABLE ‘table_name’ ADD PRIMARY KEY (‘column’);
  唯一索引 添加UNIQUE
    ALTER TABLE ‘table_name’ ADD UNIQUE (‘column’);
  全文索引 添加FULLTEXT (MYIASM才支持)
    ALTER TABLE ‘table_name’ ADD FULLTEXT (‘column’);
  多列索引
    ALTER TABLE ‘table_name’ ADD INDEX index_name (‘column1’, ‘column2’, ‘column3’)

删除索引:DROP INDEX index_name ON table_name

添加索引有如下原则:
        1 选择唯一性索引。
        2.为经常需要排序、分组和联合操作的字段建立索引。
        3.为常作为查询条件的字段建立索引。
        4.限制索引的数据,索引不是越多越好。
        5.尽量使用数据量少的索引,对于大字段可以考虑前缀索引。
        6.删除不再使用或者很少使用的索引。
        7.结合核心SQL优先考虑覆盖索引。
        8.忌用字符串做主键。

联合索引:

作用:

  1. 避免回表;
  2. 两个单列查询返回行较多,同时查返回行较少,联合索引更高效。

如果我们创建了(area, age, salary)的复合索引,那么其实相当于创建了(area,age,salary)、 (area,age)、(area)三个索引,这被称为最佳左前缀特性
因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。

索引的注意事项

索引优化:

  1. 单一列索引可以出现在where 条件中的任何位置,而联合索引需要按一定的顺序来写.
  2. 尽量使用短索引;
  3. 索引不能包含含有null值的列;
  4. 排序问题:mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
  5. like语句操作:一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
  6. 不要在列上进行运算
      select * from users where YEAR(adddate)
  7. 不使用NOT IN和 != 操作
      NOT IN和操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id != 3则可使用id>3 or id < 3
单一索引、联合索引的选择:
  1. 单一索引占内存少、维护简单;
  2. 数据量很少(表很小),或者经常(经常更新)insert、删除或者修改的表,或者数据重复且平均分布的表、或者经常和主字段一块查询但主字段索引值比较多的表字段 就不要建索引了。

如何查看, 分析索引信息?

show index from tablename;
explain select ……;或者慢查询日志

explain查看一个查询用到了哪个索引 index

explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。

使用方法,在select语句前加上explain就可以了。

MYSQL锁的类型

根据锁的类型分,可以分为共享锁,排他锁,意向共享锁和意向排他锁。
根据锁的粒度分,又可以分为行锁,表锁。
还有Gap间隙锁、next-key锁、意图锁、显式隐式锁等,在这里不与说明,有兴趣可以看一下https://blog.csdn.net/markinlqx/article/details/79322377,写的很详细。

共享锁(S):(允许事务读一行数据)由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写
  排它锁(X):(允许事务删除或更新一行数据)由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁,典型是mysql事务中的更新操作
  意向共享锁(IS):(事务想要获得一张表中某几行的共享锁)事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
  意向排他锁(IX):(事务想要获得一张表中某几行的排他锁)事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

索引与锁的说明:对于更新操作(读不上锁),只有走索引才可能上行锁;否则会对聚簇索引的每一行上写锁,实际等同于对表上写锁。
  若多个物理记录对应同一个索引,若同时访问,也会出现锁冲突;
  当表有多个索引时,不同事务可以用不同的索引锁住不同的行,另外innodb会同时用行锁对数据记录(聚簇索引)加 锁。
  
  MVCC(多版本并发控制)并发控制机制下,任何操作都不会阻塞读操作,读操作也不会阻塞任何操作,只因为读不上锁。

解决mysql数据库中文乱码的问题

1、在数据库安装的时候指定字符集
2、如果在安完了以后可以更改以配置文件
3、建立数据库时候:指定字符集类型
4、建表的时候也指定字符集

MYSQL调优

硬件配置的优化就不说了。

1.在编译时优化

  1. 使用合适的编译器;
  2. 选择想要使用的字符集编译mysql
  3. 将mysqld编译成静态执行文件
  4. 配置样本

2.表类型的选择

MySQL确实为用户提供5种不同的表类型,称为DBD、HEAP、ISAM、MERGE和MyIASM。DBD归为事务安全类,而其他为非事务安全类。

DBD:包括BDB和InnoDB。

BDB 全称是”Brekeley DB”,它是Mysql最早的具有事务能力的表的类型。最新版本的Mysql已经计划移除对BDB的支持,转而全力发展InnoDB。

InnoDB 是较新的事务安全型存储引擎,用于事务处理应用程序,支持BDB的几乎所有特性,并具有众多新特性,包括ACID事务支持。

3.优化工具的使用

MySQL服务器本身提供了几条内置命令用于帮助优化。

  1. SHOW
        SHOW还能做更多的事情。它可以显示关于日志文件、特定数据库、表、索引、进程和权限表中有价值的信息。
  2. EXPLAIN
        当你面对SELECT语句时**,EXPLAIN解释SELECT命令如何被处理**。这不仅对决定是否应该增加一个索引,而且对决定一个复杂的Join如何被MySQL处理都是有帮助的。
  3. OPTIMIZE
        OPTIMIZE语句允许你恢复空间和合并数据文件碎片,对包含变长行的表进行了大量更新和删除后,这样做特别重要。OPTIMIZE目前只工作于MyIASM和BDB表。InnoDB不能用

4.表的设计

字段类型的选择、表和字段的命名规则、针对InnoDB的主键选择、尽量使用Not Null(原因1.使用含有NULL列做索引的话会占用更多的磁盘空间,因为索引NULL列需要而外的空间来保存。 2.进行比较的时候,程序会更复杂。 3.含有NULL的列比较特殊,SQL难优化,如果是一个组合索引,那么这个NULL 类型的字段会极大影响整个索引的效率。 )等等

5.mysql语句级优化

1.性能差的读语句,在innodb中统计行数,建议另外弄一张统计表,采用myisam,定期做统计.一般的对统计的数据不会要求太精准的情况下适用。
    2.尽量不要在数据库中做运算。
    3.避免负向查询和%前缀模糊查询。
    4.不在索引列做运算或者使用函数。
    5.不要在生产环境程序中使用select * from 的形式查询数据。只查询需要使用的列。
    6.查询尽可能使用limit减少返回的行数,减少数据传输时间和带宽浪费。
    7.where子句尽可能对查询列使用函数,因为对查询列使用函数用不到索引。
    8.避免隐式类型转换,例如字符型一定要用’’,数字型一定不要使用’’。
    9.所有的SQL关键词用大写,养成良好的习惯,避免SQL语句重复编译造成系统资源的浪费。
    10.联表查询的时候,记得把小结果集放在前面,遵循小结果集驱动大结果集的原则。
    11.开启慢查询,定期用explain优化慢查询中的SQL语句。

还有索引上的优化。(见上文)
以及配置文件上的优化(自行查询)

6.服务器的选择

  1. 开启mysql复制,实现读写分离、负载均衡,将读的负载分摊到多个从服务器上,提高服务器的处理能力。
  2. 使用推荐的GA版本,提升性能
  3. 利用分区新功能进行大数据的数据拆分

数据库备份

一、备份的目的
    做灾难恢复:对损坏的数据进行恢复和还原
    需求改变:因需求改变而需要把数据还原到改变以前
    测试:测试新功能是否可用
  二、备份需要考虑的问题
    可以容忍丢失多长时间的数据;
    恢复数据要在多长时间内完;
    恢复的时候是否需要持续提供服务;
    恢复的对象,是整个库,多个表,还是单个库,单个表。
  三、备份的类型
    1、根据是否需要数据库离线
      冷备(cold backup):需要关mysql服务,读写请求均不允许状态下进行;
      温备(warm backup): 服务在线,但仅支持读请求,不允许写请求;
      热备(hot backup):备份的同时,业务不受影响。
    注:
      1、这种类型的备份,取决于业务的需求,而不是备份工具
      2、MyISAM不支持热备,InnoDB支持热备,但是需要专门的工具
    2、根据要备份的数据集合的范围
      完全备份:full backup,备份全部字符集。
      增量备份: incremental backup 上次完全备份或增量备份以来改变了的数据,不能单独使用,要借助完全备份,备份的频率取决于数据的更新频率。
      差异备份:differential backup 上次完全备份以来改变了的数据。
      建议的恢复策略:
        完全+增量+二进制日志
        完全+差异+二进制日志
    3、根据备份数据或文件
      物理备份:直接备份数据文件
      优点:备份和恢复操作都比较简单,能够跨mysql的版本,恢复速度快,属于文件系统级别的
      建议:不要假设备份一定可用,要测试mysql>check tables;检测表是否可用
      逻辑备份: 备份表中的数据和代码
      优点:恢复简单、备份的结果为ASCII文件,可以编辑与存储引擎无关可以通过网络备份和恢复
      缺点:备份或恢复都需要mysql服务器进程参与备份结果占据更多的空间,浮点数可能会丢失精度 还原之后,缩影需要重建
  四:备份的对象
    1、 数据;
    2、配置文件;
    3、代码:存储过程、存储函数、触发器
    4、os相关的配置文件
    5、复制相关的配置
    6、二进制日志
  五、备份和恢复的实现
    1、利用select into outfile实现数据的备份与还原。
    2、利用mysqldump工具对数据进行备份和还原
    3、利用lvm快照实现几乎热备的数据备份与恢复
    4、基于Xtrabackup做备份恢复。

    优势:
      1、快速可靠的进行完全备份
      2、在备份的过程中不会影响到事务
      3、支持数据流、网络传输、压缩,所以它可以有效的节约磁盘资源和网络带宽。
      4、可以自动备份校验数据的可用性。

简单来讲:
  可以使用逻辑备份和双机热备份

  1. 逻辑备份:使用mysql自带的mysqldump工具进行备份。备份成sql文件形式;
  2. 物理备份:直接拷贝mysql的数据目录。(只适用于myisam类型的表。这种类型的表是与机器独立的)
  3. 双机热备份。
      mysql数据库没有增量备份的机制。当数据量太大的时候备份是一个很大的问题。还好mysql数据库提供了一种主从备份的机制(也就是双机热备)
        优点:适合数据量大的时候。现在明白了。大的互联网公司对于mysql数据备份,都是采用热机备份。搭建多台数据库服务器,进行主从复制

另外两种备份:
  完全备份:完整备份一般一段时间进行一次,且在网站访问量最小的时候,这样常借助批处理文件定时备份。主要是写一个批处理文件在里面写上处理程序的绝对路径然后把要处理的东西写在后面,即完全备份数据库。
  增量备份:对ddl和dml语句进行二进制备份。且5.0无法增量备份,5.1后可以。如果要实现增量备份需要在my.ini文件中配置备份路径即可,重启mysql服务器,增量备份就启动了。

逻辑备份的优缺点
优点:最大好处是能够与正在运行的mysql自动协同工作,在运行期间可以确保备份是当时的点,它会自动将对应操作的表锁定,不允许其他用户修改(只能访问)。可能会阻止修改操作。sql文件通用方便移植。
缺点:备份的速度比较慢。如果是数据量很多的时候。就很耗时间。如果数据库服务器处在提供给用户服务状态,在这段长时间操作过程中,意味着要锁定表(一般是读锁定,只能读不能写入数据)。那么服务就会影响的。

MySQL数据库同步怎样实现

1、安装配置,两台服务器,分别安装好MySQL。采用单向同步的方式,就是Master的数据是主的数据,然后slave主动去Master哪儿同步数据回来。两台服务器的配置一样,把关键的配置文件拷贝一下,两台服务器做相同的拷贝配置文件操作。
  2、配置Master服务器,要考虑我们需要同步那个数据库,使用那个用户同步,我们这里为了简单起见,就使用root用户进行同步,并且只需要同步数据库abc。
  3、配置Slave服务器,我们的slave服务器主要是主动去Master服务器同步数据回来。
  4、测试安装,首先查看一下slave的主机日志:检查是否连接正常, 在Master查看信息,查看Master状态:查看Master下MySQL进程信息:在slave上查看信息:查看slave状态:查看slave下MySQL进程信息:再在Master的abc库里建立表结构并且插入数据,然后检查slave有没有同步这些数据,就能够检查出是否设置成功。

其他小问题

MySQL取得当前时间的函数是?以及格式化日期的函数

取得当前时间用 now() 就行。
  在数据库中格式化时间 用DATE_FORMAT(date, format)。根据格式串
format 格式化日期或日期时间值date,返回结果串。

你如何确定 MySQL 是否处于运行状态?

答案: Debian 上运行命令 service mysql status,在RedHat 上运行命令 service mysqld status。然后看看输出即可。

如何开启或停止 MySQL 服务?

答案:运行命令 service mysqld start 开启服务;运行命令 service mysqld stop 停止服务。

查看MYSQL数据库中所有用户
SELECT DISTINCT CONCAT(‘User: ”’,user,”’@”’,host,”’;’) AS query FROM mysql.user; 
查看数据库中具体某个用户的权限

show grants for ‘cactiuser’@’%’;

部分转自:https://blog.csdn.net/derrantcm/article/details/51534411

猜你喜欢

转载自blog.csdn.net/mulinsen77/article/details/86563953