mysql面试题汇总(全面)

框架

考察的知识点较深入,以阿里巴巴为例,这些大厂的面试都是类似的,通常从一个大的面试点切入,然后层层深入,直到问到你不会为止,比如,你了解哪些数据库引擎?这个数据库引擎的特点是什么?这个数据库引擎是如何存储数据的?为什么要采用这种存储方式?等等。
所以针对以上两个问题,作者结合自己 10 余年的工作和面试的经验,经过讨论和修改,最终制定了八大模块,汇总并介绍 MySQL 中的典型面试问题,它包含的内容如下。

第一部分:通用模块。此部分对 MySQL 整体概念、执行流程、数据库引擎、查询缓存、表空间、回表查询、数据类型间的区别、内存表、临时表、删除表的 n 种方式、枚举、视图、数据恢复等相关知识点对应的面试题进行解答。
第二部分:索引模块。索引的好坏直接影响数据库的性能,所以索引的面试题也是面试中必问的问题,此部分为索引对应的面试题合集。
第三部分:事务模块。事务决定了程序的稳定性,在 MySQL 中的地位也是首屈一指,也是面试中必问的面试题,此部分为事务对应的面试题合集。
第四部分:锁。锁包括:全局锁、表锁、行锁、死锁、乐观锁、悲观锁等,不同的数据库引擎支持的锁支持粒度也是不同的,此部分的面试题,让你彻底搞定锁相关的面试题。
第五部分:日志。日志看似不起眼,却是 MySQL 主备同步和容灾恢复以及问题排除的关键,当然也是面试中必问的问题,这部分会对不同的数据库引擎中的重点日志,进行详细的介绍。
第六部分:MySQL 操作命令和内置函数。MySQL 的操作命令,对于程序员或者 DBA 来说也是必须具备的一项技能,比如,用户和权限的创建、数据库相关信息的查询等,都离不开对 MySQL 命令行的掌握。对内置函数的掌握程度,代表了你对 MySQL 的掌握程度,善用 MySQL 提供的内置函数,会让你有事半功倍的效果,内置函数也是笔试中必考的面试题。
第七部分:性能优化和分布式。性能优化和分布式是面试中决定你高度的关键指标,其中性能优化包括了慢查询的分析和处理,对分布式的掌握体现了你的技术深度。
第八部分:开放性问题。很多大公司最后也会问一下没有标准答案的开放性问题,以考察面试者的技术能力边界和对待问题的分析思路,这部分助你更平稳的获得 offer。
对应的知识图谱如下:在这里插入图片描述

事务四大特性

原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态
一致性:如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的;
隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
持久性:事务一旦提交,其结果就是永久的。即便发生系统故障,也能恢复。

事务隔离级别

未提交读(Read Uncommitted):允许脏读,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。也就是可能读取到其他会话中未提交事务修改的数据
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)。
可重复读(Repeated Read):可重复读。无论其他事务是否修改并提交了数据,在这个事务中看到的数据值始终不受其他事务影响。
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

MySQL数据库(InnoDB引擎)默认使用可重复读( Repeatable read)

索引相关

数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用 B_TREE。B_TREE 索引加速了数据访问,因为存储引擎不会再去扫描整张表得到需要的数据;相反,它从根节点开始,根节点保存了子节点的指针,存储引擎会根据指针快速寻找数据。

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址,即:MyISAM索引文件和数据文件是分离的,MyISAM的索引文件仅仅保存数据记录的地址。MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。MyISAM的索引方式也叫做“非聚集”的。

InnoDB引擎也使用B+Tree作为索引结构,但是InnoDB的数据文件本身就是索引文件,叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。这种索引叫做“聚焦索引”。InnoDB的辅助索引的data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。InnoDB的索引实现后,不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。在Innodb中也不建议使用非单调的字段作为主键,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,建议使用自增字段作为主键。

MySQL数据库的四类索引:

index ---- 普通索引,数据可以重复,没有任何限制。
  unique ---- 唯一索引,要求索引列的值必须唯一,但允许有空值;如果是组合索引,那么列值的组合必须唯一。

primary key ---- 主键索引,是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值,一般是在创建表的同时创建主键索引。

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

fulltext ---- 全文索引,是对于大表的文本域:char,varchar,text列才能创建全文索引,主要用于查找文本中的关键字,并不是直接与索引中的值进行比较。fulltext更像是一个搜索引擎,配合match against操作使用,而不是一般的where语句加like。

注:全文索引目前只有MyISAM存储引擎支持全文索引,InnoDB引擎5.6以下版本还不支持全文索引

所有存储引擎对每个表至少支持16个索引,总索引长度至少为256字节,索引有两种存储类型,包括B型树索引和哈希索引。

索引可以提高查询的速度,但是创建和维护索引需要耗费时间,同时也会影响插入的速度,如果需要插入大量的数据时,最好是先删除索引,插入数据后再建立索引。

索引生效条件

假设index(a,b,c)
最左前缀匹配:模糊查询时,使用%匹配时:’a%‘会使用索引,’%a‘不会使用索引
条件中有or,索引不会生效
a and c,a生效,c不生效
b and c,都不生效
a and b > 5 and c,a和b生效,c不生效。

检测索引的效果:

show status like ‘%handler_read%’ 越大越好
sql语句分类:
DDL:数据定义语言(create drop)
DML:数据操作语句(insert update delete)
DQL:数据查询语句(select )
DCL:数据控制语句,进行授权和权限回收(grant revoke)
TPL:数据事务语句(commit collback savapoint)

数据库三范式:

第一范式:1NF是对属性的原子性约束,要求字段具有原子性,不可再分解;(只要是关系型数据库都满足1NF)

第二范式:2NF是在满足第一范式的前提下,非主键字段不能出现部分依赖主键;解决:消除复合主键就可避免出现部分以来,可增加单列关键字。

第三范式:3NF是在满足第二范式的前提下,非主键字段不能出现传递依赖,比如某个字段a依赖于主键,而一些字段依赖字段a,这就是传递依赖。解决:将一个实体信息的数据放在一个表内实现。

脏读、幻读、不可重复读

脏读: 是指事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。

不可重复读 :是指在数据库访问时,一个事务范围内的两次相同查询却返回了不同数据。在一个事务内多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么在第一个事务中的两次读数据之间,由于第二个事务的修改,第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

幻读: 是指当事务不是独立执行时发生的一种现象,比如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么就会发生,操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

不可重复读&幻读区别:

如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。
不可重复读重点在于update和delete,而幻读的重点在于insert。如何通过锁机制来解决他们产生的问题

存储引擎 MyISAM 和 InnoDB区别:

InnoDB支持事务,MyISAM不支持。
MyISAM适合查询以及插入为主的应用,InnoDB适合频繁修改以及涉及到安全性较高的应用。
InnoDB支持外键,MyISAM不支持。
从MySQL5.5.5以后,InnoDB是默认引擎。
MyISAM支持全文类型索引,而InnoDB不支持全文索引。
InnoDB中不保存表的总行数,select count() from table时,InnoDB需要扫描整个表计算有多少行,但MyISAM只需简单读出保存好的总行数即可。注:当count()语句包含where条件时MyISAM也需扫描整个表。
对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引。
清空整个表时,InnoDB是一行一行的删除,效率非常慢。MyISAM则会重建表。MyisAM使用delete语句删除后并不会立刻清理磁盘空间,需要定时清理,命令:OPTIMIZE table dept;
InnoDB支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like ‘%lee%’)
Myisam创建表生成三个文件:.frm 数据表结构 、 .myd 数据文件 、 .myi 索引文件,Innodb只生成一个 .frm文件,数据存放在ibdata1.log
现在一般都选用InnoDB,主要是MyISAM的全表锁,读写串行问题,并发效率锁表,效率低,MyISAM对于读写密集型应用一般是不会去选用的。

应用场景:

MyISAM不支持事务处理等高级功能,但它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。
InnoDB用于需要事务处理的应用程序,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。

CHAR和VARCHAR的区别:

CHAR和VARCHAR类型在存储和检索方面有所不同
CHAR列长度固定为创建表时声明的长度,长度值范围是1到255
当CHAR值被存储时,它们被用空格填充到特定长度,检索CHAR值时需删除尾随空格。

Mysql中的锁类型

MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁
表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低
行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高

存储过程

我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。

优点:

(1).存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

(2).存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。

(3).存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。

(4).存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。

(5).存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。

delete、drop、truncate区别

truncate 和 delete只删除数据,不删除表结构 ,drop删除表结构,并且释放所占的空间。
删除数据的速度,drop> truncate > delete
delete属于DML语言,需要事务管理,commit之后才能生效。drop和truncate属于DDL语言,操作立刻生效,不可回滚。

使用场合:
当你不再需要该表时, 用 drop;
当你仍要保留该表,但要删除所有记录时, 用 truncate;
当你要删除部分记录时(always with a where clause), 用 delete.

注意: 对于有主外键关系的表,不能使用truncate而应该使用不带where子句的delete语句,由于truncate不记录在日志中,不能够激活触发器。

MySQL的复制原理以及流程

基本原理流程,3个线程以及之间的关联;

  1. 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中;

  2. 从:io线程——在使用start slave 之后,负责从master上拉取 binlog 内容,放进 自己的relay log中;

  3. 从:sql执行线程——执行relay log中的语句;

mysql主从复制

MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的拓展。多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负载性能。

下图就描述了一个多个数据库间主从复制与读写分离的模型:在这里插入图片描述
一主多从的数据库体系中,多个从服务器采用异步的方式更新主数据库的变化,业务服务器在执行写或者相关修改数据库的操作是在主服务器上进行的,读操作则是在各从服务器上进行。如果配置了多个从服务器或者多个主服务器又涉及到相应的负载均衡问题,关于负载均衡具体的技术细节还没有研究过,今天就先简单的实现一主一从的主从复制功能。

Mysql主从复制的实现原理图大致如下:在这里插入图片描述

MySQL之间数据复制的基础是二进制日志文件(binary log file)。一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。

InnoDB引擎的四大特性

插入缓冲,二次写,自适应哈希索引,预读

InooDB和MyISAM的select count(*)哪个更快,为什么?

myisam更快,因为myisam内部维护了一个计算器,可以直接调取。MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小。

MySQL中的varchar和char的区别以及varchar(50)中的50代表的涵义

char是一种固定长度的类型,varchar则是一种可变长度的类型。

varchar(50)最多存放50个字符,varchar(50)和(200)存储hello所占空间一样,但后者在排序时会消耗更多的内存,因为order by col采用fixed_length计算col长度(memory引擎也一样)

日志的实现方式

错误日志:记录出错信息,也记录一些警告信息或者正确的信息

查询日志:记录所有对数据库请求的信息,不论这些请求是否得到了正确的执行

慢查询日志:设置一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询的日志文件中

二进制日志:记录对数据库执行更改的所有操作

中继日志,事务日志。

InnoDB事务的4种隔离级别

读未提交:

读未提交产生脏读问题。

读已提交:

这种隔离级别出现的问题是——不可重复读(Nonrepeatable Read):不可重复读意味着我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果。

(1)这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)
(2)它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变

可重复读:

(1)这是MySQL的默认事务隔离级别
(2)它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行
(3)此级别可能出现的问题——幻读(Phantom Read):当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行

串行化:

(1)这是最高的隔离级别
(2)它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。
(3)在这个级别,可能导致大量的超时现象和锁竞争

在这里插入图片描述

一张表里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把mysql重启,再insert一条记录,这条记录的ID是18还是15 ?看引擎是内存还是数据文件!

在这里插入图片描述

mysql为什么用自增列作为主键?

  1. 如果我们定义了主键(PRIMARY
    KEY),那么InnoDB会选择主键作为聚集索引、如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。
  2. 数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)
  3. 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
  4. 如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE
    TABLE来重建表并优化填充页面。

为什么使用数据索引能提高效率

数据索引的存储是有序的
在有序的情况下,通过索引查询一个数据是无需遍历索引记录的
极端情况下,数据索引的查询效率为二分法查询效率,趋近于 log2(N)

B+树索引和哈希索引的区别

B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且叶子节点的指针相互链接,是有序的在这里插入图片描述
哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从跟节点到叶子节点逐级查找,只需要 一次哈希算法即可,是无序的
在这里插入图片描述

哈希索引的优势:

等值查询。哈希索引具有绝对优势(前提是:没有大量重复键值,如果大量重复键值时,哈希索引的效率很低,因为存在所谓的哈希碰撞问题。)

哈希索引不适用的场景:

不支持范围查询
不支持索引完成排序
不支持联合索引的最左前缀匹配规则
通常,B+树索引结构适用于绝大多数场景,像下面这种场景用哈希索引才更有优势:

在HEAP表中,如果存储的数据重复度很低(也就是说基数很大),对该列数据以等值查询为主,没有范围查询、没有排序的时候,特别适合采用哈希索引,例如这种SQL:


select id,name from table where name='李明'; — 仅等值查询

而常用的InnoDB引擎中默认使用的是B+树索引,它会实时监控表上索引的使用情况,如果认为建立哈希索引可以提高查询效率,则自动在内存中的“自适应哈希索引缓冲区”建立哈希索引(在InnoDB中默认开启自适应哈希索引),通过观察搜索模式,MySQL会利用index key的前缀建立哈希索引,如果一个表几乎大部分都在缓冲池中,那么建立一个哈希索引能够加快等值查询。

注意:在某些工作负载下,通过哈希索引查找带来的性能提升远大于额外的监控索引搜索情况和保持这个哈希表结构所带来的开销。但某些时候,在负载高的情况下,自适应哈希索引中添加的read/write锁也会带来竞争,比如高并发的join操作。like操作和%的通配符操作也不适用于自适应哈希索引,可能要关闭自适应哈希索引。

B树和B+树的区别

1、B树,每个节点都存储key和data,所有的节点组成这可树,并且叶子节点指针为null,叶子节点不包含任何关键字信息
在这里插入图片描述

2、B+树,所有的叶子节点中包含全部关键字的信息,及指向含有这些关键字记录的指针,且叶子节点本身依关键字的大小自小到大的顺序链接,所有的非终端节点可以看成是索引部分,节点中仅含有其子树根节点中最大(或最小)关键字在这里插入图片描述

为什么说B+比B树更适合实际应用中操作系统的文件索引和数据库索引?

B+的磁盘读写代价更低 B+的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。

B+tree的查询效率更加稳定 由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

mysql联合索引

联合索引是两个或更多个列上的索引。对于联合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a 、 a,b 、 a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。
利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知 道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。

什么情况下应不建或少建索引

表记录太少
经常插入、删除、修改的表
数据重复且分布平均的表字段,假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一般不会提高数据库的查询速度。
经常和主字段一块查询但主字段索引值比较多的表字段

MySQL分区

什么是表分区?

表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。

表分区与分表的区别

分表:指的是通过一定规则,将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。

分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。

表分区有什么好处?

分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。 2. 和单个磁盘或者文件系统相比,可以存储更多数据
优化查询。在where语句中包含分区条件时,可以只扫描一个或多个分区表来提高查询效率;涉及sum和count语句时,也可以在多个分区上并行处理,最后汇总结果。
分区表更容易维护。例如:想批量删除大量数据可以清除整个分区。
可与使用分区表来避免某些特殊的瓶颈,例如InnoDB的单个索引的互斥访问,ext3问价你系统的inode锁竞争等。

分区表的限制因素

1、一个表最多只能有1024个分区

2、MySQL5.1中,分区表达式必须是整数,或者返回整数的表达式。在MySQL5.5中提供了非整数表达式分区的支持。

3、如果分区字段中有主键或者唯一索引的列,那么多有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。

4、分区表中无法使用外键约束

5、MySQL的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。

如何判断当前Mysql是否支持分区?

命令:show variables like ‘%partition%’

Mysql支持的分区类型有哪些?

1、RANGE分区:这种模式允许将数据划分不同范围。例如可以将一个表通过年份划分成若干个分区

2、List分区:这种模式允许系统通过预定义的列表的值来对数据进行分割。按照list中的值分区,与RANGE的区别是,range分区的区间范围值是连续的

3、HASH分区:这种模式允许通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。例如可以建立一个对表主键进行分区的表

4、KEY分区:上面Hash模式的一种延伸,这里的Hash Key是Mysql系统产生的

行级锁定的优点

1、当在许多线程中访问不同的行时只存在少量锁定冲突

2、回滚时只有少量的更改

3、可以长时间锁定单一的行

18、行级锁定的缺点
1、比页级或表级锁定占用更多的内存

2、当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁

3、如果你在大部分数据上经常进行GROUP BY操作或者必须经常扫描整个表,比其它锁定明显慢很多

4、用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定

Mysql优化

1、开启查询缓存,优化查询

2、explain你的select查询,这可以帮你分析你的查询语句或是表结构的性能瓶颈。EXPLAIN的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序

3、当只要一行数据时使用limit 1,Mysql数据库引擎会在找到一条数据后停止搜索,而不是继续往后查找下一条符合记录的数据

4、为搜索字段建索引

5、使用ENUM而不是VARCHAR,如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用ENUM而不是VARCHAR

6、Prepared Statement Prepared Statements很像存储过程,是一种运行在后台的sql语句集合,我们可以从使用prepared statement获得很多好处,无论是性能问题还是安全问题。Prepared Statements可以检查一些你绑定好的变量,这样可以保护你的程序不会受到“SQL注入式”攻击

7、垂直分表

8、选择正确的存储引擎

key和index的区别

1、key是数据库的物理结构,它包含两层意义和作用,一是约束(偏重于约束和规范数据库的结构完整性),二是索引(辅助查询用的)。包括primary key,unique key,foregin key等

2、index是数据库的物理结构,它只是辅助查询的,它创建时会在另外的表空间(mysql中的innodb表空间)以一个类似目录的结构存储。索引要分类的话,分为前缀索引、全文本索引等

与Oracle相比,Mysql有什么优势?

1.Mysql是开源软件,随时可用,无需付费。
2.Mysql是便携式的
3.带有命令提示符的GUI。
4.使用Mysql查询浏览器支持管理

如何区分FLOAT和DOUBLE?

  浮点数以8位精度存储在FLOAT中,并且有四个字节。
  浮点数存储在DOUBLE中,精度为18位,有八个字节。

区分CHAR_LENGTH和LENGTH?

CHAR_LENGTH是字符数,而LENGTH是字节数。Latin字符的这两个数据是相同的,但是对于Unicode和其他编码,它们是不同的。

5、请简洁描述Mysql中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别?

SQL标准定义的四个隔离级别为:
read uncommited :读到未提交数据
read committed:脏读,不可重复读
repeatable read:可重读
serializable :串行事物
在这里插入图片描述

列的字符串类型可以是什么?

字符串类型是:
SET
BLOB
ENUM
CHAR
TEXT
VARCHAR

Mysql中使用什么存储引擎?

存储引擎称为表类型,数据使用各种技术存储在文件中。
技术涉及:
Storage mechanism
Locking levels
Indexing
Capabilities and functions.

Mysql驱动程序是什么?

以下是Mysql中可用的驱动程序:
PHP驱动程序
JDBC驱动程序
ODBC驱动程序
CWRAPPER
PYTHON驱动程序
PERL驱动程序
RUBY驱动程序
CAP11PHP驱动程序
Ado.net5.mxj

TIMESTAMP在UPDATE CURRENT_TIMESTAMP数据类型上做什么?

创建表时TIMESTAMP列用Zero更新。只要表中的其他字段发生更改,UPDATE CURRENT_TIMESTAMP修饰符就将时间戳字段更新为当前时间。

主键和候选键有什么区别?

表格的每一行都由主键唯一标识,一个表只有一个主键。

主键也是候选键。按照惯例,候选键可以被指定为主键,并且可以用于任何外键引用。

myisamchk是用来做什么的?

它用来压缩MyISAM表,这减少了磁盘或内存使用。

MYSQL数据库服务器性能分析的方法命令有哪些?

在这里插入图片描述

如果一个表有一列定义为TIMESTAMP,将发生什么?

每当行被更改时,时间戳字段将获取当前时间戳。

列设置为AUTO INCREMENT时,如果在表中达到最大值,会发生什么情况?

它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。

怎样才能找出最后一次插入时分配了哪个自动增量?

LAST_INSERT_ID将返回由Auto_increment分配的最后一个值,并且不需要指定表名称。

你怎么看到为表格定义的所有索引?

索引是通过以下方式为表格定义的:SHOW INDEX FROM ;

LIKE声明中的%和_是什么意思?%对应于0个或更多字符,_只是LIKE语句中的一个字符。

如何在Unix和Mysql时间戳之间进行转换?

UNIX_TIMESTAMP是从Mysql时间戳转换为Unix时间戳的命令
FROM_UNIXTIME是从Unix时间戳转换为Mysql时间戳的命令

我们如何得到受查询影响的行数?


SELECT COUNT(user_id)FROM users;

SELECT COUNT(user_id)FROM users;Mysql查询是否区分大小写?不区分

LIKE和REGEXP操作有什么区别?

LIKE和REGEXP运算符用于表示^和%。
1.SELECT * FROM employee WHERE emp_name REGEXP “^b”;
2.SELECT * FROM employee WHERE emp_name LIKE “%b”;

BLOB和TEXT有什么区别?

BLOB是一个二进制对象,可以容纳可变数量的数据。有四种类型的BLOB :TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB

它们只能在所能容纳价值的最大长度上有所不同。

TEXT是一个不区分大小写的BLOB。四种TEXT类型 TINYTEXT、TEXT、MEDIUMTEXT和 LONGTEXT

它们对应于四种BLOB类型,并具有相同的最大长度和存储要求。

BLOB和TEXT类型之间的唯一区别在于对BLOB值进行排序和比较时区分大小写,对TEXT值不区分大小写。

mysql_fetch_array和mysql_fetch_object的区别是什么?

mysql_fetch_array() - 将结果行作为关联数组或来自数据库的常规数组返回。

mysql_fetch_object - 从数据库返回结果行作为对象。

我们如何在mysql中运行批处理模式?

mysql;

mysql mysql.out

MyISAM表格将在哪里存储,并且还提供其存储格式?

每个MyISAM表格以三种格式存储在磁盘上:

·“.frm”文件存储表定义

·数据文件具有“.MYD”(MYData)扩展名

索引文件具有“.MYI”(MYIndex)扩展名

Mysql中有哪些不同的表格?

共有5种类型的表格:MyISAM、Heap、Merge、INNODB、ISAM

ISAM是什么?ISAM简称为索引顺序访问方法。它是由IBM开发的,用于在磁带等辅助存储系统上存储和检索数据。

Mysql如何优化DISTINCT?

DISTINCT在所有列上转换为GROUP BY,并与ORDER BY子句结合使用。

SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;

如何显示前50行?

SELECT*FROM

LIMIT 0,50;

可以使用多少列创建索引?任何标准表最多可以创建16个索引列。

NOW()和CURRENT_DATE()有什么区别?

NOW() 命令用于显示当前年份,月份,日期,小时,分钟和秒。

CURRENT_DATE() 仅显示当前年份,月份和日期。

什么样的对象可以使用CREATE语句创建?

DATABASE、EVENT、FUNCTION、INDEX、PROCEDURE、TABLE、TRIGGER、USER、 VIEW

Mysql表中允许有多少个TRIGGERS?

在Mysql表中允许有六个触发器,如下:

BEFORE INSERT

AFTER INSERT

BEFORE UPDATE

AFTER UPDATE

BEFORE DELETE

AFTER DELETE

什么是非标准字符串类型?

TINYTEXT

TEXT

MEDIUMTEXT

LONGTEXT

什么是通用SQL函数

 CONCAT(A, B) - 连接两个字符串值以创建单个字符串输出。通常用于将两个或多个字段合并为一个字段。

   FORMAT(X, D)- 格式化数字X到D有效数字。

   CURRDATE(), CURRTIME()- 返回当前日期或时间。

   NOW() - 将当前日期和时间作为一个值返回。

   MONTH(),DAY(),YEAR(),WEEK(),WEEKDAY() - 从日期值中提取给定数据。

   HOUR(),MINUTE(),SECOND() - 从时间值中提取给定数据。

   DATEDIFF(A,B) - 确定两个日期之间的差异,通常用于计算年龄

   SUBTIMES(A,B) - 确定两次之间的差异。

   FROMDAYS(INT- 将整数天数转换为日期值。

MYSQL支持事务吗?

在缺省模式下,MYSQL是autocommit模式的,所有的数据库更新操作都会即时提交,所以在缺省情况下,mysql是不支持事务的。

但是如果你的MYSQL表类型是使用InnoDB Tables 或 BDB tables的话,你的MYSQL就可以使用事务处理,使用SET AUTOCOMMIT=0就可以使MYSQL允许在非autocommit模式,在非autocommit模式下,你必须使用COMMIT来提交你的更改,或者用ROLLBACK来回滚你的更改。

START TRANSACTION;

SELECT @A:=SUM(salary) FROM table1 WHERE type=1;

UPDATE table2 SET summmary=@A WHERE type=1;

COMMIT;

MYSQL数据表在什么情况下容易损坏?

服务器突然断电导致数据文件损坏。
强制关机,没有先关闭mysql 服务等。

如何设计一个高并发的系统

① 数据库的优化,包括合理的事务隔离级别、SQL语句优化、索引的优化

② 使用缓存,尽量减少数据库 IO

③ 分布式数据库、分布式缓存

④ 服务器的负载均衡

  1. 锁的优化策略

① 读写分离

② 分段加锁

③ 减少锁持有的时间

④ 多个线程尽量以相同的顺序去获取资源

等等,这些都不是绝对原则,都要根据情况,比如不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。这部分跟面试官谈了很久

索引的底层实现原理和优化

B+树,经过优化的B+树

主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此InnoDB建议为大部分表使用默认自增的主键作为主索引。

什么情况下设置了索引但无法使用

① 以“%”开头的LIKE语句,模糊匹配

② OR语句前后没有同时使用索引

③ 数据类型出现隐式转化(如varchar不加单引号的话可能会自动转换为int型)

SQL语句的优化

order by要怎么处理

alter尽量将多次合并为一次

insert和delete也需要合并

等等

实践中如何优化MySQL

四条从效果上第一条影响最大,后面越来越小。

① SQL语句及索引的优化

② 数据库表结构的优化

③ 系统配置的优化

④ 硬件的优化

sql注入的主要特点

变种极多,攻击简单,危害极大

sql注入的主要危害

未经授权操作数据库的数据

恶意纂改网页

私自添加系统账号或者是数据库使用者账号

网页挂木马

优化数据库的方法

· 选取最适用的字段属性,尽可能减少定义字段宽度,尽量把字段设置NOTNULL,例如’省份’、'性别’最好适用ENUM

· 使用连接(JOIN)来代替子查询

· 适用联合(UNION)来代替手动创建的临时表

· 事务处理

· 锁定表、优化事务处理

· 适用外键,优化锁定表

· 建立索引

· 优化查询语句

简单描述mysql中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。
普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。也就是说,唯一索引可以保证数据记录的唯一性。
主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字 PRIMARY KEY 来创建。
索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引,这就是联合索引。
索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件。

数据库中的事务是什么?

事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。ACID 四大特性,原子性、隔离性、一致性、持久性。

了解XSS攻击吗?如何防止?

XSS是跨站脚本攻击,首先是利用跨站脚本漏洞以一个特权模式去执行攻击者构造的脚本,然后利用不安全的Activex控件执行恶意的行为。
使用htmlspecialchars()函数对提交的内容进行过滤,使字符串里面的特殊符号实体化。

SQL注入漏洞产生的原因?如何防止?

SQL注入产生的原因:程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。

防止SQL注入的方式:

开启配置文件中的magic_quotes_gpc 和 magic_quotes_runtime设置

执行sql语句时使用addslashes进行sql语句转换

Sql语句书写尽量不要省略双引号和单引号。

过滤掉sql语句中的一些关键词:update、insert、delete、select、 * 。

提高数据库表和字段的命名技巧,对一些重要的字段根据程序的特点命名,取不易被猜到的。

Php配置文件中设置register_globals为off,关闭全局变量注册

控制错误信息,不要在浏览器上输出错误信息,将错误信息写到日志文件中。

对于关系型数据库而言,索引是相当重要的概念,请回答有关索引的几个问题:

a)、索引的目的是什么?

快速访问数据表中的特定信息,提高检索速度

创建唯一性索引,保证数据库表中每一行数据的唯一性。

加速表和表之间的连接

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

b)、索引对数据库系统的负面影响是什么?

负面影响:
创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。

c)、为数据表建立索引的原则有哪些?

在最频繁使用的、用以缩小查询范围的字段上建立索引。

在频繁使用的、需要排序的字段上建立索引

d)、 什么情况下不宜建立索引?

对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。

对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等

简述在MySQL数据库中MyISAM和InnoDB的区别

区别于其他数据库的最重要的特点就是其插件式的表存储引擎。切记:存储引擎是基于表的,而不是数据库。

InnoDB与MyISAM的区别:

InnoDB存储引擎: 主要面向OLTP(Online Transaction Processing,在线事务处理)方面的应用,是第一个完整支持ACID事务的存储引擎(BDB第一个支持事务的存储引擎,已经停止开发)。

特点:

· 行锁设计、支持外键,支持事务,支持并发,锁粒度是支持mvcc得行级锁;

MyISAM存储引擎: 是MySQL官方提供的存储引擎,主要面向OLAP(Online Analytical Processing,在线分析处理)方面的应用。
特点:

不支持事务,锁粒度是支持并发插入得表级锁,支持表所和全文索引。操作速度快,不能读写操作太频繁;

解释MySQL外连接、内连接与自连接的区别

先说什么是交叉连接: 交叉连接又叫笛卡尔积,它是指不使用任何条件,直接将一个表的所有记录和另一个表中的所有记录一一匹配。

内连接 则是只有条件的交叉连接,根据某个条件筛选出符合条件的记录,不符合条件的记录不会出现在结果集中,即内连接只连接匹配的行。
外连接 其结果集中不仅包含符合连接条件的行,而且还会包括左表、右表或两个表中
的所有数据行,这三种情况依次称之为左外连接,右外连接,和全外连接。

左外连接,也称左连接,左表为主表,左表中的所有记录都会出现在结果集中,对于那些在右表中并没有匹配的记录,仍然要显示,右边对应的那些字段值以NULL来填充。右外连接,也称右连接,右表为主表,右表中的所有记录都会出现在结果集中。左连接和右连接可以互换,MySQL目前还不支持全外连接。

写出三种以上MySQL数据库存储引擎的名称(提示:不区分大小写)

MyISAM、InnoDB、BDB(BerkeleyDB)、Merge、Memory(Heap)、Example、Federated、
Archive、CSV、Blackhole、MaxDB 等等十几个引擎

Myql中的事务回滚机制概述

事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位,事务回滚是指将该事务已经完成的对数据库的更新操作撤销。

要同时修改数据库中两个不同表时,如果它们不是一个事务的话,当第一个表修改完,可能第二个表修改过程中出现了异常而没能修改,此时就只有第二个表依旧是未修改之前的状态,而第一个表已经被修改完毕。而当你把它们设定为一个事务的时候,当第一个表修改完,第二表修改出现异常而没能修改,第一个表和第二个表都要回到未修改的状态,这就是所谓的事务回滚

SQL语言包括哪几部分?每部分都有哪些操作关键字?

SQL语言包括数据定义(DDL)、数据操纵(DML),数据控制(DCL)和数据查询(DQL)四个部分。

数据定义:Create Table,Alter Table,Drop Table, Craete/Drop Index等

数据操纵:Select ,insert,update,delete,

数据控制:grant,revoke

数据查询:select

完整性约束包括哪些?

数据完整性(Data Integrity)是指数据的精确(Accuracy)和可靠性(Reliability)。

分为以下四类:

  1. 实体完整性:规定表的每一行在表中是惟一的实体。

  2. 域完整性:是指表中的列必须满足某种特定的数据类型约束,其中约束又包括取值范围、精度等规定。

  3. 参照完整性:是指两个表的主关键字和外关键字的数据应一致,保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据库中扩散。

  4. 用户定义的完整性:不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。用户定义的完整性即是针对某个特定关系数据库的约束条件,它反映某一具体应用必须满足的语义要求。

与表有关的约束:包括列约束(NOT NULL(非空约束))和表约束(PRIMARY KEY、foreign key、check、UNIQUE) 。

什么是事务?及其特性?

事务:是一系列的数据库操作,是数据库应用的基本逻辑单位。

事务特性:

(1)原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。

(2)一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态

(3)隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务,

(4) 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。

或者这样理解:

事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。

什么是锁?

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

基本锁类型:锁包括行级锁和表级锁

什么叫视图?游标是什么?

视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。

游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。

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

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

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

索引就一种特殊的查询表,数据库的搜索引擎可以利用它加速对数据的检索。它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。索引可以是唯一的,创建索引允许指定单个列或者是多个列。缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。

如何通俗地理解三个范式?

第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;

第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;

第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。。

范式化设计优缺点:

优点:可以尽量得减少数据冗余,使得更新快,体积小

缺点:对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引优化

反范式化:

优点:可以减少表得关联,可以更好得进行索引优化

缺点:数据冗余以及数据异常,数据得修改需要更多的成本

什么是基本表?什么是视图?

基本表是本身独立存在的表,在 SQL 中一个关系就对应一个表。 视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库中,是一个虚表

试述视图的优点?

(1) 视图能够简化用户的操作 (2) 视图使用户能以多种角度看待同一数据; (3) 视图为数据库提供了一定程度的逻辑独立性; (4) 视图能够对机密数据提供安全保护。

NULL是什么意思

答:NULL这个值表示UNKNOWN(未知):它不表示“”(空字符串)。对NULL这个值的任何比较都会生产一个NULL值。您不能把任何值与一个 NULL值进行比较,并在逻辑上希望获得一个答案。

使用IS NULL来进行NULL判断

主键、外键和索引的区别?

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

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

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

作用:

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

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

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

个数:

主键–主键只能有一个

外键–一个表可以有多个外键

索引–一个表可以有多个唯一索引

你可以用什么来确保表格里的字段只接受特定范围里的值?

Check限制,它在数据库表格里被定义,用来限制输入该列的值。

触发器也可以被用来限制数据库表格里的字段能够接受的值,但是这种办法要求触发器在表格里被定义,这可能会在某些情况下影响到性能。

说说对SQL语句优化有哪些方法?(选择几条)

(1)Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。

(2)用EXISTS替代IN、用NOT EXISTS替代NOT IN。

(3) 避免在索引列上使用计算

(4)避免在索引列上使用IS NULL和IS NOT NULL

(5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

(6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描

(7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描

SQL语句中‘相关子查询’与‘非相关子查询’有什么区别?

子查询:嵌套在其他查询中的查询称之。

子查询又称内部,而包含子查询的语句称之外部查询(又称主查询)。

所有的子查询可以分为两类,即相关子查询和非相关子查询

(1)非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。

(2)相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。

故非相关子查询比相关子查询效率高

char和varchar的区别?

char是一种固定长度的类型,varchar则是一种可变长度的类型,它们的区别是:

char(M)类型的数据列里,每个值都占用M个字节,如果某个长度小于M,MySQL就会在它的右边用空格字符补足.(在检索操作中那些填补出来的空格字符将被去掉)在varchar(M)类型的数据列里,每个值只占用刚好够用的字节再加上一个用来记录其长度的字节(即总长度为L+1字节).

varchar得适用场景:

字符串列得最大长度比平均长度大很多 2.字符串很少被更新,容易产生存储碎片 3.使用多字节字符集存储字符串

Char得场景:

存储具有近似得长度(md5值,身份证,手机号),长度比较短小得字符串(因为varchar需要额外空间记录字符串长度),更适合经常更新得字符串,更新时不会出现页分裂得情况,避免出现存储碎片,获得更好的io性能

Mysql 的存储引擎,myisam和innodb的区别。

MyISAM 是非事务的存储引擎;适合用于频繁查询的应用;表锁,不会出现死锁;适合小数据,小并发

innodb是支持事务的存储引擎;合于插入和更新操作比较多的应用;设计合理的话是行锁(最大区别就在锁的级别上);适合大数据,大并发。

数据表类型有哪些

MyISAM、InnoDB、HEAP、BOB,ARCHIVE,CSV等。

MyISAM:成熟、稳定、易于管理,快速读取。一些功能不支持(事务等),表级锁。

InnoDB:支持事务、外键等特性、数据行锁定。空间占用大,不支持全文索引等。

MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?

a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。

b. 选择合适的表字段数据类型和存储引擎,适当的添加索引。

c. mysql库主从读写分离。

d. 找规律分表,减少单表中的数据量提高查询速度。

e。添加缓存机制,比如memcached,apc等。

f. 不经常改动的页面,生成静态页面。

g. 书写高效率的SQL。比如 SELECT * FROM TABEL 改为 SELECT field_1, field_2, field_3 FROM TABLE.

对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题?

a. 确认服务器是否能支撑当前访问量。

b. 优化数据库访问。

c. 禁止外部访问链接(盗链), 比如图片盗链。

d. 控制文件下载。

e. 使用不同主机分流。

f. 使用浏览统计软件,了解访问量,有针对性的进行优化。

4、如何进行SQL优化?(关于后边的解释同学们可以进行理解,到时根据自己的理解把大体意思说出来即可)

(1)选择正确的存储引擎

以 MySQL为例,包括有两个存储引擎 MyISAM 和 InnoDB,每个引擎都有利有弊。

MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。

InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。但是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。

(2)优化字段的数据类型

记住一个原则,越小的列会越快。如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多。当然,你也需要留够足够的扩展空间。

(3)为搜索字段添加索引

索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索,那么最好是为其建立索引,除非你要搜索的字段是大的文本字段,那应该建立全文索引。

(4)避免使用Select 从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。即使你要查询数据表的所有字段,也尽量不要用通配符,善用内置提供的字段排除定义也许能给带来更多的便利。

(5)使用 ENUM 而不是 VARCHAR

ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。例如,性别、民族、部门和状态之类的这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。

(6)尽可能的使用 NOT NULL

除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。 NULL其实需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。 当然,这里并不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。

(7)固定长度的表会更快

如果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”。 例如,表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。

固定长度的表会提高性能,因为MySQL搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键。

并且,固定长度的表也更容易被缓存和重建。不过,唯一的副作用是,固定长度的字段会浪费一些空间,因为定长的字段无论你用不用,他都是要分配那么多的空间。

为表中得字段选择合适得数据类型(物理设计)

字段类型优先级: 整形>date,time>enum,char>varchar>blob,text

优先考虑数字类型,其次是日期或者二进制类型,最后是字符串类型,同级别得数据类型,应该优先选择占用空间小的数据类型

存储时期

Datatime:以 YYYY-MM-DD HH:MM:SS 格式存储时期时间,精确到秒,占用8个字节得存储空间,datatime类型与时区无关

Timestamp:以时间戳格式存储,占用4个字节,范围小1970-1-1到2038-1-19,显示依赖于所指定得时区,默认在第一个列行的数据修改时可以自动得修改timestamp列得值

Date:(生日)占用得字节数比使用字符串.datatime.int储存要少,使用date只需要3个字节,存储日期月份,还可以利用日期时间函数进行日期间得计算

Time:存储时间部分得数据

注意:不要使用字符串类型来存储日期时间数据(通常比字符串占用得储存空间小,在进行查找过滤可以利用日期得函数)

使用int存储日期时间不如使用timestamp类型

主键 超键 候选键 外键

1)超键(super key) :在关系中能唯一标识元组的属性集称为关系模式的超键
2)候选键(candidate key):不含有多余属性的超键称为候选键

3)主键(primary key):用户选作元组标识的一个候选键程序主键

4)外键(foreign key):如果关系模式R1中的某属性集不是R1的主键,而是另一个关系R2的主键则该属性集是关系模式R1的外键

假设有如下两个表:

     学生(学号,姓名,性别,身份证号,教师编号)

    教师(教师编号,姓名,工资)

超键:由超键的定义可知,学生表中含有学号或者身份证号的任意组合都为此表的超键。如:(学号)、(学号,姓名)、(身份证号,性别)等。

候选键:候选键属于超键,它是最小的超键,就是说如果再去掉候选键中的任何一个属性它就不再是超键了。学生表中的候选键为:(学号)、(身份证号)。

主键:主键就是候选键里面的一个,是人为规定的,例如学生表中,我们通常会让“学号”做主键,教师表中让“教师编号”做主键。

外键:外键比较简单,学生表中的外键就是“教师编号”。外键主要是用来描述两个表的关系。

数据库事务

数据库事务transanction正确执行的四个基本要素:ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。

原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样

一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。

持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

drop,delete与truncate的区别

drop直接删掉表;truncate删除表中数据,再插入时自增长id又从1开始 ;delete删除表中数据,可以加where字句。

1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。

2) 表和索引所占空间。当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。

3) 一般而言,drop > truncate > delete

4) 应用范围。TRUNCATE 只能对TABLE;DELETE可以是table和view

5) TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)。

6) truncate与不带where的delete :只删除数据,而不删除表的结构(定义)drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。

7) delete语句为DML(data maintain Language),这个操作会被放到 rollback segment中,事务提交后才生效。如果有相应的 tigger,执行的时候将被触发。

8) truncate、drop是DLL(data define language),操作立即生效,原数据不放到 rollback segment中,不能回滚

9) 在没有备份情况下,谨慎使用 drop 与 truncate。要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。要删除表用drop;若想保留表而将表中数据删除,如果于事务无关,用truncate即可实现。如果和事务有关,或老师想触发trigger,还是用delete。

10) Truncate table 表名 速度快,而且效率高,因为:truncate table 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。

11) TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。

12) 对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。

索引的工作原理及其种类

数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动。

图展示了一种可能的索引方式。左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在O(log2n)的复杂度内获取到相应数据。

索引优点

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

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

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

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

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

索引缺点

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

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

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

建议创建索引列

    1)在经常需要搜索的列上,可以加快搜索的速度;

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

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

    4)在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;

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

不建议创建索引列

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

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

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

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

索引分类

    唯一索引:唯一索引是不允许其中任何两行具有相同索引值的索引。
    当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。 

    主键索引 

    数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。 

     聚集索引 

     在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。
     如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。

局部性原理与磁盘预读

    由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。
    由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。
    预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。

B-/+Tree索引的性能

   上文说过一般使用磁盘I/O次数评价索引结构的优劣。先从B-Tree分析,根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:

   每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。

   B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。

   而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。

   综上所述,用B-Tree作为索引结构效率是非常高的。

连接种类

外连接
1)左连接:left join 或 left outer join

select * from table1 left join table2 on table1.id=table2.id

注释:包含table1的所有子句,根据指定条件返回table2相应的字段,不符合的以null显示

2)右连接:right join 或 right outer join

select * from table1 right join table2 on table1.id=table2.id

注释:包含table2的所有子句,根据指定条件返回table1相应的字段,不符合的以null显示

3)完整外部联接:full join 或 full outer join

select * from table1 full join table2 on table1.id=table2.id

注释:返回左右连接的和(见上左、右连接)

内连接:join 或 inner join

select * from table1 join table2 on table1.id=table2.id

注释:只返回符合条件的table1和table2的列

等价:
1)select a.,b. from table1 a,table2 b where a.id=b.id

2)select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件只能用where,不能用on)

交叉连接(完全)

1) 概念:没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录)

2) 交叉连接:cross join (不带条件where…)

3) sql语句
select * from table1 cross join table2

注释:笛卡尔积

4) 等价(与下列执行效果相同)

select * from table1,table2

数据库范式

第一范式(1NF)
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之第一范式就是无重复的列。

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。

第三范式(3NF)

满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。(我的理解是消除冗余)

数据库优化的思路

SQL语句优化
1)应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

   2)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null。可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0

   3)很多时候用 exists 代替 in 是一个好的选择

   4)用Where子句替换HAVING 子句 因为HAVING 只会在检索出所有记录之后才对结果集进行过滤

索引优化

数据库结构优化

   1)范式优化: 比如消除冗余(节省空间。。) 

   2)反范式优化:比如适当加冗余等(减少join) 

   3)拆分表: 垂直拆分和水平拆分

服务器硬件优化

MySql的复制原理以及流程

基本原理流程,3个线程以及之间的关联;
1) 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中;
2) 从:io线程——在使用start slave 之后,负责从master上拉取 binlog 内容,放进 自己的relay log中;
3) 从:sql执行线程——执行relay log中的语句;

MySQL中myisam与innodb的区别,至少5点

1)InnoDB支持事物,而MyISAM不支持事物

2)InnoDB支持行级锁,而MyISAM支持表级锁

3)InnoDB支持MVCC, 而MyISAM不支持

4)InnoDB支持外键,而MyISAM不支持

5)InnoDB不支持全文索引,而MyISAM支持。

innodb引擎的4大特性

插入缓冲(insert buffer)、二次写(double write)、自适应哈希索引(ahi)、预读(read ahead)

两者select count(*)哪个更快,为什么

myisam更快,因为myisam内部维护了一个计数器,可以直接调取。

int(20)中20的涵义

    指显示字符的长度,但要加参数的,最大为255,比如它是记录行数的id,插入10笔资料,它就显示00000000001 ~~~00000000010,当字符的位数超过11,它也只显示11位,如果你没有加那个让它未满11位就前面加0的参数,它不会在前面加0。20表示最大显示宽度为20,但仍占4字节存储,存储范围不变;

事务是如何通过日志来实现的

   事务日志是通过redo和innodb的存储引擎日志缓冲(Innodb log buffer)来实现的,当开始一个事务的时候,会记录该事务的lsn(log sequence number)号; 当事务执行时会往InnoDB存储引擎的日志的日志缓存里面插入事务日志;当事务提交时,必须将存储引擎的日志缓冲写入磁盘(通过innodb_flush_log_at_trx_commit来控制),也就是写数据前,需要先写日志。这种方式称为“预写日志方式”。

MySQL binlog的几种日志录入格式以及区别

1)Statement:每一条会修改数据的sql都会记录在binlog中

优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。(相比row能节约多少性能与日志量,这个取决于应用的SQL情况,正常同一条记录修改或者插入

row格式所产生的日志量还小于Statement产生的日志量,但是考虑到如果带条件的update操作,以及整表删除,alter表等操作,ROW格式会产生大量日志,因此在考虑是否使

用ROW格式日志时应该跟据应用的实际情况,其所产生的日志量会增加多少,以及带来的IO性能问题。)

缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执

行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有很多相关问题(如sleep()函数, last_insert_id(),以user-defined-functions(udf)会出现问题).

使用以下函数的语句也无法被复制:

  • LOAD_FILE()
  • UUID()
  • USER()
  • FOUND_ROWS()
  • SYSDATE() (除非启动时启用了 --sysdate-is-now 选项)
    同时在INSERT …SELECT 会产生比 RBR 更多的行级锁

2)Row:不记录sql语句上下文相关信息,仅保存哪条记录被修改

优点: binlog中可以不记录执行的sql语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节

而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题

缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比如一条update语句,修改多条记录,则binlog中每一条修改

都会有记录,这样造成binlog日志量会很大,特别是当执行alter table之类的语句的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中。

3)Mixedlevel: 是以上两种level的混合使用

   一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区

分对待记录的日志形式,也就是在Statement和Row之间选择一种.新版本的MySQL中队row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变

更的时候就会以statement模式来记录。至于update或者delete等修改数据的语句,还是会记录所有行的变更。

MySQL数据库cpu飙升到500%的话他怎么处理

1)列出所有进程:show processlist

2)观察所有进程:多秒没有状态变化的(干掉)

3)查看超时日志或者错误日志 (做了几年开发,一般会是查询以及大批量的插入会导致cpu与i/o上涨 … 当然不排除网络状态突然断了,导致一个请求服务器只接受到一半,比如where子句或分页子句没有发送,当然的一次被坑经历)

一个6亿的表a,一个3亿的表b,通过外间tid关联,你如何最快的查询出满足条件的第50000到第50200中的这200条数据记录

1)如果A表TID是自增长,并且是连续的,B表的ID为索引

select * from a,b where a.tid = b.id and a.tid>500000 limit 200;

2)如果A表的TID不是连续的,那么就需要使用覆盖索引.TID要么是主键,要么是辅助索引,B表ID也需要有索引

select * from b , (select tid from a limit 50000,200) a where b.id = a .tid;

MySQL中InnoDB引擎的行锁是通过加在什么上完成

答:InnoDB是基于索引来完成行锁

例: select * from tab_with_index where id = 1 for update;

for update 可以根据条件来完成行锁锁定,并且 id 是有索引键的列,

如果 id 不是索引键那么InnoDB将完成表锁,并发将无从谈起

xtrabackup实现原理

    在InnoDB内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改。当InnoDB启动时,InnoDB会检

查数据文件的事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。

存储过程与触发器的区别

    触发器与存储过程非常相似,触发器也是SQL语句集,两者唯一的区别是触发器不能用EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发

(激活)执行。触发器是在一个修改了指定表中的数据时执行的存储过程。通常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性和一致性。由于

用户不能绕过触发器,所以可以用它来强制实施复杂的业务规则,以确保数据的完整性。触发器不同于存储过程,触发器主要是通过事件执行触发而被执行的,

存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时,SQLSERVER就会自动执行触发器所定义的

SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则。
索引是什么?有什么作用以及缺点
定义:索引是存储引擎用于快速查找数据的一种数据结构。

MySQL数据库基本的索引类型:普通索引、唯一索引、主键索引和全文索引。

普通索引:允许被索引的数据列包含重复的列

唯一索引:不允许被索引的数据包含重复的列

主键索引:在一张表中只能定义一个主键索引,主键索引用于唯一标识一条记录(主键索引必然属于唯一索引),使用关键字PRIMARY KEY创建

索引的目的是什么

快速访问数据表中的特定信息,提高检索速度
创建唯一性索引,保证数据库表中每一行数据的唯一性
加速表和表之间的连接
使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序时间
索引对数据库系统的负面影响

创建和维护索引需要耗费时间。这个时间随着数据量增加而增加
索引需要占用额外的物理空间。
对表进行增、删、改的时候需要动态维护,降低了数据的维护速度。
建立索引的原则

频繁使用的字段
选择性高的字段
需要排序的字段
主键、外键和唯一索引的区别
主键:唯一标识一条记录,不能有重复,不允许为空。一个表只能有一个主键

外键:表的外键是另一个表的主键,外键可以有重复的,可以为空值(但是无意义,不推荐使用)。一个表可以有多个外键

唯一索引:用来提高查询排序的速度,没有重复值,但允许有一个空值。一个表可以有多个唯一索引。

MySQL底层实现,MySQL有什么引擎

MySQL底层采用B+树实现,B+树可以看作2-3树的一种扩展,B+树是每个节点允许存在多个元素,并且每个节点有多个孩子的多叉查找树,B+树的非叶子节点存储的是导航信息,不包含实际的值,而叶子节点存储了实际的值,所有的叶子节点和相邻的节点采用链表连接,便于区间查找和遍历。

关于叶子节点存储的值,在InnoDB中非主键索引中,存储的是主键的信息,而聚簇索引(主键索引)中存储的是实际数据。而在MyISAM中叶子节点存储的是指向实际数据存储位置的指针。MySQL在5.5版本采用的是MyISAM作为默认的数据库引擎,之后就被更优秀的InnoDB引擎替代。

InnoDB和MyISAM区别,InnoDB替代了MyISAM,那么MyISAM是否一无是处。

MyISAM支持全文索引,不支持事务,不支持外键,只支持表级锁,不支持行级锁。

InnoDB支持事务,支持全文索引,支持外键,支持行级锁。

采用MyISAM(可被压缩,需要的存储空间较小)的场景:

读多写少,R/W>100:1
并发不高
表数据量小
什么是事务,事务特性
事务指的是满足ACID特性的一组操作。

Atomicity 原子性:事务被视为不可分割的最小单元,要么全部提交成功,要么全部失败回滚。

Consistency 一致性:数据库在事务执行前后保持一致的状态。

Isolation 隔离性:一个事务所做的修改在最终提交之前,对其他事务是不可见的。

Durability 持久性:一旦事务提交,则其修改将会被永久保存到数据库中。

如何设计一个高并发的系统

数据库的优化,包括合理的事务隔离级别、SQL语句优化、索引优化
使用缓存,尽量减少数据库IO
分布式数据库、分布式缓存
服务器的负载均衡
锁的优化策略
读写分离
分段加锁
减少锁持有的时间
多个线程尽量以相同的顺序去获取资源
优化SQL的方法
MySQL数据库优化的八种方式(经典必看)

选取最适用的字段属性,尽可能减少定义字段宽度,尽量把字段设置NOTNULL,例如’省份’、'性别’最好适用ENUM

使用连接(JOIN)来代替子查询

适用联合(UNION)来代替手动创建的临时表

事务处理

锁定表、优化事务处理

适用外键,优化锁定表

建立索引

如何进行SQL优化

  1. 选择正确的存储引擎
    以 MySQL为例,包括有两个存储引擎 MyISAM 和 InnoDB,每个引擎都有利有弊。

MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。

InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。但是它支持行级锁 ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务、外键等。

  1. 优化字段的数据类型
    记住一个原则,越小的列会越快。如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。

如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多。当然,你也需要留够足够的扩展空间。

  1. 为搜索字段添加索引
    索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索,那么最好是为其建立索引,除非你要搜索的字段是大的文本字段,那应该建立全文索引。

  2. 避免使用SELECT * 从数据库中读取多余的信息
    避免使用Select 从数据库里读出越多的数据,那么查询就会变得越慢。

并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。

即使你要查询数据表的所有字段,也尽量不要用*通配符,善用内置提供的字段排除定义也许能给带来更多的便利。

  1. 使用ENUM而不是VARCHAR
    ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。

这样一来,用这个字段来做一些选项列表变得相当的完美。

例如,性别、民族、部门和状态之类的这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。

  1. 尽可能使用NOT NULL
    NULL值需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。

除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。

当然,并不是说就不能使用NULL值了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。

  1. 固定长度的表会提高性能
    如果表中所有字段都是固定长度的,整个表都会被认为是static的。固定长度的表会提高性能,因为这些字段固定后,MySQL很容易计算下一行数据的偏移量,读取速度自然会变快。另外固定长度的表也很容易被缓存和重建。

唯一的副作用是固定长度的字段会浪费一些空间。另外表中一旦有了VARCHAR、TEXT、BLOB这些类型字段之一,就不再是固定长度静态表了。

自己瞎想的口诀:亲自说select* enum not null=(引擎选择,字段索引,建立索引,不要使用select *,使用enum不要使用varchar,尽量不要使用not null)

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

存储过程是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数(如果该存储过程带有参数)来执行它。

1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2.当对数据库进行复杂操作时(如对多个表进行Update,Insert,Query,Delete 时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
3.存储过程可以重复使用,可减少数据库开发人员的工作量
4.安全性高,可设定只有某此用户才具有对指定存储过程的使用权

相对于直接使用SQL 语句,在应用程序中直接调用存储过程有以下好处:
(1)减少网络通信量。
调用一个行数不多的存储过程与直接调用SQL 语句的网络通信量可能不会有很大的差别,可是如果存储过程包含上百行SQL 语句,那么其性能绝对比一条一条的调用SQL 语句要高得多。
(2)执行速度更快。
有两个原因:首先,在存储过程创建的时候,数据库已经对其进行了一次解析和优化。其次,存储过程一旦执行,在内存中就会保留一份这个存储过程,这样下次再执行同样的存储过程时,可以从内存中直接调用。
(3)更强的适应性。
由于存储过程对数据库的访问是通过存储过程来进行的,因此数据库开发人员可以在不改动存储过程接口的情况下对数据库进行任何改动,而这些改动不会对应用程序造成影响。
(4) 分布式工作。
应用程序和数据库的编码工作可以分别独立进行,而不会相互压制。

缺点:
1.如果更改范围大到需要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则您仍需要更新程序集中的代码以添加参数、更新 GetValue() 调用,等等,这时候估计比较繁琐了。
2.可移植性差。由于存储过程将应用程序绑定到 SQL Server,因此使用存储过程封装业务逻辑将限制应用程序的可移植性。

谈谈三大范式,什么时候使用反范式设计

三大范式
第一范式:1NF要求字段属性具有原子性,不可再分解。是对属性的原子性约束。
第二范式:2NF要求非主属性完全函数依赖于键码。是对记录的唯一性约束,要求记录有唯一标识。
第三范式:3NF要求非主属性不传递函数依赖于键码。是对字段冗余性的约束,即任何字段不能由其他字段派生出来。
范式化设计的优缺点
优点:减少数据冗余,使得更新速度快,表格体积小

缺点:对于查询需要多个表进行关联的情况,降低了查询效率,难以进行索引优化。

反范式化设计
优点:可以减少表的关联,更好地进行索引优化

缺点:数据冗余以及数据异常,数据的修改需要更多的成本。

什么是视图,以及视图的使用场景

视图是一种虚拟的表,具有和物理表相同的功能。

可以对视图进行增,改,查操作。视图通常是有一个表或者多个表的行或列的子集。

对视图的修改不影响基本表。相比多表查询,它使得我们获取数据更容易。

drop、delete和truncate的区别及使用场景

相同点:drop、delete、truncate都是删除表的内容

不同点:

delete:删除表的内容,表的结构还存在,不释放空间,可以回滚恢复。
drop:删除内容和结构,释放空间,没有备份表之前要慎用。
truncate:删除表的内容,表的结构还在,可以释放空间,没有备份表之前要慎用。
解释MySQL外连接、内连接的区别
内联接:仅显示两个联接表中的匹配行的联接

左外联接:包括第一个命名表(“左表”,出现在JOIN子句的最左边)中的所有行。不包括右表中的不匹配行。

右外联接:包括右表中的所有行。不包括左表中的不匹配行。

对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题?

对于当今大流量的网站,每天几千万甚至上亿的流量,是如何解决访问量问题的呢?以下是一些总结的方法:
第一,确认服务器硬件是否足够支持当前的流量。
普通的P4服务器一般最多能支持每天10万独立IP,如果访问量比这个还要大,那么必须首先配置一台更高性能的专用服务器才能解决问题,否则怎么优化都不可能彻底解决性能问题。

第二,优化数据库访问。
服务器的负载过大,一个重要的原因是CPU负荷过大,降低服务器CPU的负荷,才能够有效打破瓶颈。而使用静态页面可以使得CPU的负荷最小化。前台实现完全的静态化当然最好,可以完全不用访问数据库,不过对于频繁更新的网站,静态化往往不能满足某些功能。
缓存技术就是另一个解决方案,就是将动态数据存储到缓存文件中,动态网页直接调用这些文件,而不必再访问数据库,WordPress和Z-Blog都大量使用这种缓存技术。
如果确实无法避免对数据库的访问,那么可以尝试优化数据库的查询SQL.避免使用Select *from这样的语句,每次查询只返回自己需要的结果,避免短时间内的大量SQL查询。

第三,禁止外部的盗链。
外部网站的图片或者文件盗链往往会带来大量的负载压力,因此应该严格限制外部对于自身的图片或者文件盗链,好在目前可以简单地通过refer来控制盗链,Apache自己就可以通过配置来禁止盗链,IIS也有一些第三方的ISAPI可以实现同样的功能。当然,伪造refer也可以通过代码来实现盗链,不过目前蓄意伪造refer盗链的还不多,可以先不去考虑,或者使用非技术手段来解决,比如在图片上增加水印。

第四,控制大文件的下载。
大文件的下载会占用很大的流量,并且对于非SCSI硬盘来说,大量文件下载会消耗CPU,使得网站响应能力下降。因此,尽量不要提供超过2M的大文件下载,如果需要提供,建议将大文件放在另外一台服务器上。目前有不少免费的Web2.0网站提供图片分享和文件分享功能,因此可以尽量将图片和文件上传到这些分享网站。

第五,使用不同主机分流主要流量
将文件放在不同的主机上,提供不同的镜像供用户下载。比如如果觉得RSS文件占用流量大,那么使用FeedBurner或者FeedSky等服务将RSS输出放在其他主机上,这样别人访问的流量压力就大多集中在FeedBurner的主机上,RSS就不占用太多资源了。

第六,使用流量分析统计软件。
在网站上安装一个流量分析统计软件,可以即时知道哪些地方耗费了大量流量,哪些页面需要再进行优化,因此,解决流量问题还需要进行精确的统计分析才可以。我推荐使用的流量分析统计软件是GoogleAnalytics(Google分析)。

  • 4
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值