正确回答通过率:78.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
1、第一范式(1NF)
所谓第一范式(1NF)是指在关系模型中,对于添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。简而言之,第一范式就是无重复的域。
在任何一个关系数据库中,第一范式(1NF)是对关系模式的设计基本要求,一般设计中都必须满足第一范式(1NF)。不过有些关系模型中突破了1NF的限制,这种称为非1NF的关系模型。换句话说,是否必须满足1NF的最低要求,主要依赖于所使用的关系模型。
特点:属性不可分割,即每个属性都是不可分割的原子项。(实体的属性即表中的列)
2、第二范式(2NF)
在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)。
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。例如在员工表中的身份证号码即可实现每个一员工的区分,该身份证号码即为候选键,任何一个候选键都可以被选作主键。在找不到候选键时,可额外增加属性以实现区分,如果在员工关系中,没有对其身份证号进行存储,而姓名可能会在数据库运行的某个时间重复,无法区分出实体时,设计辟如ID等不重复的编号以实现区分,被添加的编号或ID选作主键。(该主键的添加是在ER设计时添加,不是建库时随意添加)。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是在第一范式的基础上属性完全依赖于主键。
特点:
满足第一范式;
第二范式需要确保数据表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言),每张表只描述一件事情;
消除部分依赖,要求一张表中的每一列都完全依赖于主键(针对于组合主键),也就是不会出现某一列只和部分主键相关。
3、第三范式(3NF)
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)。
第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性,也就是在满足2NF的基础上,任何非主属性不得传递依赖于主属性。
特点:
前提:满足第一范式和第二范式;
第三范式需要确保数据表中的每一列数据表和主键直接相关,而不能间接相关;
消除传递依赖,要求一张表中的每一列都和主键是直接依赖的,不是间接依赖。
巴斯-科德范式(BCNF)
3NF基础上,任何主属性不能对主键子集依赖(在3NF基础上消除主属性对主码子集的依赖)。巴斯-科德范式(BCNF)是第三范式(3NF)的一个子集,即满足巴斯-科德范式(BCNF)必须满足第三范式(3NF)。通常情况下,巴斯-科德范式被认为没有新的设计规范加入,只是对第二范式与第三范式中设计规范要求更强,因而被认为是修正第三范式,也就是说,它事实上是对第三范式的修正,使数据库冗余度更小。这也是BCNF不被称为第四范式的原因。某些书上,根据范式要求的递增性将其称之为第四范式是不规范,也是更让人不容易理解的地方。而真正的第四范式,则是在设计规范中添加了对多值及依赖的要求。
正确回答通过率:83.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
数据库表冗余的字段是在数据库中没有实际意义的字段,只是为了方便查询而添加的一个字段,一般出现 在多表联合查询中:
例如article表有以下冗余字段
fromUserName,toUserName
如何管理这两个字段呢?通过建立一个表,表结构如下id,objTable,objName,sourceTable, sourceId,level,isUpdate其中objTable=目标表 ,objName= 目标字段,sourceTable=源表,sourceId=源表ID,level=是否需要立即更新,isUpdate=是否已更新其中,level字段很有必要,有些 冗余字段并不需要在源表修改后立即更新,那么可以通过一个定期更新策略来更新。通过库表的管理,配合一个合理的存储过程,冗余字段的 使用将不再是难题。举例,如果上面两个字段发生变化,则使用触发器或者调用这个存储过程来检查是否有需要立即更新的冗余字段,需要则 立即更新,不需要则isUpdate置0,等到周期性的策略来更新同时isUpdate=1。
正确回答通过率:51.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
varchar和char的区别:
1.char的长度是不可变的,而varchar的长度是可变的。
定义一个char[10]和varchar[10]。
如果存进去的是‘csdn’,那么char所占的长度依然为10,除了字符‘csdn’外,后面跟六个空格,varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的。
2.char的存取速度还是要比varchar要快得多,因为其长度固定,方便程序的存储与查找。
char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率。
varchar是以空间效率为首位。
3.char的存储方式是:对英文字符(ASCII)占用1个字节,对一个汉字占用两字节。
varchar的存储方式是:对每个英文字符占用2个字节,汉字也占用2个字节。
4.两者的存储数据都非unicode的字符数据。
正确回答通过率:72.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
(1)集中式事务
单个节点参与的事务,单节点操作执行成功集中式事务即成功,单节点操作执行失败则集中式事务回滚
1.扁平式事务
一般扁平事务:由begin或start transaction开始,由commit或rollback结束的简单事务,完整commit或完整rollback
带保存点的扁平事务:在一般扁平事务基础上可以设置保存点,允许该事务回滚到保存点,相当于部分“回滚,一般扁平事务相当于保存点在事务开头的一般扁平事务
2.链式事务
在带保存点的扁平事务的基础上,将多个带保存点的扁平事务连接,前一个事务的提交和后一个事务的开始为原子操作,这样前一个事务的上下文就可以被后一个事务获取,链式事务本质是传递上下文的多个事务
3.嵌套事务
树状事务组织形式,根节点为顶层事务,每一棵子树都可以是嵌套事务,叶子节点为扁平事务,嵌套事务由顶层事务统一控制提交,但如果任意子事务回滚会导致整个嵌套事务回滚
4.自治事务
自治事务在嵌套事务的基础上,让子树管理其下事务而不受顶层事务节制,自治事务提交后即使顶层事务回滚也不会造成自治事务回滚。自治事务常用于在外层事务记录日志,无论外层成功提交还是失败回滚,自治事务都可以记录日志。MySQL原生不支持自治事务,Oracle原生支持。
(2)分布式事务
由多个节点参与的事务,各个节点操作都成功执行则分布式事务成功,任意节点操作失败则分布式事务全部回滚
正确回答通过率:78.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 中级
一、 什么是存储过程:
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。
二、为什么要用存储过程呢?
存储过程真的那么重要吗,它到底有什么好处呢?
笔者认为,存储过程说白了就是一堆 SQL 的合并。中间加了点逻辑控制。
1.存储过程处理比较复杂的业务时比较实用。具体分为两个方面:
(一)、响应时间上来说有优势:如果你在前台处理的话。可能会涉及到多次数据库连接。但如果你用存储过程的话,就只有一次。存储过程可以给我们带来运行效率提高的好处;
(二)、从安全上使用了存储过程的系统更加稳定:程序容易出现 BUG 不稳定,而存储过程,只要数据库不出现问题,基本上是不会出现什么问题的。
2.数据量小的,或者和钱没关系的项目不用存储过程也可以正常运作。
三、那么什么时候才可以用存储?
对于数据量不是很大以及业务处理不是很复杂的小项目就无需要了么?
存储过程不仅仅适用于大型项目,对于中小型项目,使用存储过程也是非常有必要的。其威力和优势主要体现在:
1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2.当对数据库进行复杂操作时(如对多个表进行 Update,Insert,Query,Delete 时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。这些操作,如果用程序来完成,就变成了一条条的 SQL 语句,可能要多次连接数据库。而换成存储,只需要连接一次数据库就可以了。
3.存储过程可以重复使用,可减少数据库开发人员的工作量。
4.安全性高,可设定只有某此用户才具有对指定存储过程的使用权。
5.更强的适应性:由于存储过程对数据库的访问是通过存储过程来进行的,因此数据库开发人员可以在不改动存储过程接口的情况下对数据库进行任何改动,而这些改动不会对应用程序造成影响。
6.布式工作:应用程序和数据库的编码工作可以分别独立进行,而不会相互压制。
一般来说,存储过程的编写比基本SQL语句复杂,编写存储过程需要更高的技能,更丰富的经验。经自已测试,一个有着十万条记录的表,通过php调用存储过程比通过PHP执行sql语句获取所有记录的时间,平均快0.4秒左右.
正确回答通过率:82.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
事务(Transaction)是并发控制的基本单位。事务就是一系列的操作,这些操作要么都执行,要么都不执行。
事务具有以下4个基本特征
Atomic(原子性) 事务中的一系列的操作要么都完成,要么全部失败
Consistency(一致性) 一个成功的事务应该讲数据写入的到数据库,否则就要回滚到最初的状态
Isolation(隔离性) 并发访问和修改的duli
Durability(持久性) 事务结束应该讲事务的处理结构存储起来
事务的语句
开始事物:BEGIN TRANSACTION
提交事物:COMMIT TRANSACTION
回滚事务:ROLLBACK TRANSACTION
正确回答通过率:68.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
1、数据库悲观锁
认为数据在被修改的时候一定会存在并发问题,因此在整个数据处理过程中将数据锁定。
数据库的行锁、表锁、排他锁等都是悲观锁,通过使用select…for update语句, 执行该语句后,会在表上加持行锁,一直到事务提交,解除行锁。
1.1 使用场景举例:
在秒杀案例中,生成订单和扣减库存的操作,可以通过商品记录的行锁,进行保护。通过使用select…for update语句,
在查询商品表库存时将该条记录加锁,待下单减库存完成后,再释放锁。
1.2 示例的SQL如下:
//0.开始事务
begin;
//1.查询出商品信息
select stockCount from seckill_good where id=1 for update;
//2.根据商品信息生成订单
insert into seckill_order (id,good_id) values (null,1);
//3.修改商品stockCount减一
update seckill_good set stockCount=stockCount-1 where id=1;
//4.提交事务
commit;
在对id = 1的记录修改前,先通过for update的方式进行加锁,然后再进行修改。
同一时间只有一个线程可以开启事务并获得id=1的锁,其它的事务必须等本次事务提交之后才能执行。
1.3 注意:
使用select_for_update,另外一定要写在事务中
要使用悲观锁,必须关闭mysql数据库中自动提交的属性,命令set autocommit=0
2、数据库乐观锁
2.1 主要就是两个步骤:冲突检测和数据更新。比较典型的就是Compare and Swap(CAS)技术。
多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新成功,失败的线程并不会被挂起,并可以再次尝试。
2.2 做法:在表中增加一个version字段,操作前先查询version信息,在数据提交时检查version字段是否被修改。
2.3 示例的SQL如下:
//1.查询出商品信息
select stockCount, version from seckill_good where id=1;
//2.根据商品信息生成订单
insert into seckill_order (id,good_id) values (null,1);
//3.修改商品库存
update seckill_good set stockCount=stockCount-1, version = version+1 where id=1, version=version;
在更新之前,先查询一下库存表中当前版本(version),然后在做update的时候,以version 作为一个修改条件。
CAS 乐观锁有两个问题:
a. CAS 存在一个比较重要的问题,即ABA问题. 解决的办法是version字段顺序递增。
b. 乐观锁的方式,在高并发时,只有一个线程能执行成功,会造成大量的失败,这给用户的体验显然是很不好的。
正确回答通过率:84.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 初级
超键在关系中能唯一标识元组的属性集称为关系模式的超键 ,一个或多个属性组合在一起作为超键。
候选键 最下超键,没有冗余元素的超键
主键 数据库中表中唯一和完整标识的数据列或属性集合。
外键 在一个表中存在另外一个表的主键叫做外键
正确回答通过率:72.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询;不包含任何列或数据。使用视图可以简化复杂的sql操作,隐藏具体的细节,保护数据;视图创建后,可以使用与表相同的方式利用它们。
视图不能被索引,也不能有关联的触发器或默认值,如果视图本身内有order by 则对视图再次order by将被覆盖。
创建视图:create view XXX as XXXXXXXXXXXXXX;
对于某些视图比如未使用联结子查询分组聚集函数Distinct Union等,是可以对其更新的,对视图的更新将对基表进行更新;但是视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新
正确回答通过率:76.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。
在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。
创建索引可以大大提高系统的性能。
第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?因为,增加索引也有许多不利的方面。
第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
索引是建立在数据库表中的某些列的上面。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列上创建索引:在经常需要搜索的列上,可以加快搜索的速度;在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。
同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点:
第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。
根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。
唯一索引
唯一索引是不允许其中任何两行具有相同索引值的索引。
当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。 主键索引 数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。 聚集索引 在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。
如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。
局部性原理与磁盘预读
由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。
由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。
预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。
B-/+Tree索引的性能分析
到这里终于可以分析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作为索引结构效率是非常高的。
正确回答通过率:45.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 高难
1 第一范式(1NF)
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列。
2 第二范式(2NF)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。
3 第三范式(3NF)
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。(我的理解是消除冗余)
正确回答通过率:47.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 高难
1.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 只会在检索出所有记录之后才对结果集进行过滤
2.索引优化
看上文索引
3.数据库结构优化
1)范式优化: 比如消除冗余(节省空间。。) 2)反范式优化:比如适当加冗余等(减少join) 3)拆分表: 分区将数据在物理上分隔开,不同分区的数据可以制定保存在处于不同磁盘上的数据文件里。这样,当对这个表进行查询时,只需要在表分区中进行扫描,而不必进行全表扫描,明显缩短了查询时间,另外处于不同磁盘的分区也将对这个表的数据传输分散在不同的磁盘I/O,一个精心设置的分区可以将数据传输对磁盘I/O竞争均匀地分散开。对数据量大的时时表可采取此方法。可按月自动建表分区。
4)拆分其实又分垂直拆分和水平拆分: 案例: 简单购物系统暂设涉及如下表: 1.产品表(数据量10w,稳定) 2.订单表(数据量200w,且有增长趋势) 3.用户表 (数据量100w,且有增长趋势) 以mysql为例讲述下水平拆分和垂直拆分,mysql能容忍的数量级在百万静态数据可以到千万 垂直拆分:解决问题:表与表之间的io竞争 不解决问题:单表中数据量增长出现的压力 方案: 把产品表和用户表放到一个server上 订单表单独放到一个server上 水平拆分: 解决问题:单表中数据量增长出现的压力 不解决问题:表与表之间的io争夺
方案: 用户表通过性别拆分为男用户表和女用户表 订单表通过已完成和完成中拆分为已完成订单和未完成订单 产品表 未完成订单放一个server上 已完成订单表盒男用户表放一个server上 女用户表放一个server上(女的爱购物 哈哈)
正确回答通过率:58.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
触发器与存储过程非常相似,触发器也是SQL语句集,两者唯一的区别是触发器不能用EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发(激活)执行。触发器是在一个修改了指定表中的数据时执行的存储过程。通常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性和一致性。由于用户不能绕过触发器,所以可以用它来强制实施复杂的业务规则,以确保数据的完整性。触发器不同于存储过程,
触发器主要是通过事件执行触发而被执行的,而存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时,SQLSERVER就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则。
正确回答通过率:76.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
l 数字类型
Float和double选择(尽量选择float)
区分开TINYINT / INT / BIGINT,能确定不会使用负数的字段,建议添加 unsigned定义
能够用数字类型的字段尽量选择数字类型而不用字符串类型的
l 字符类型
char,varchar,TEXT的选择:非万不得已不要使用 TEXT 数据类型,定长字段,建议使用 CHAR 类型(填空格),不定长字段尽量使用 VARCHAR(自动适应长度,超过阶段),且仅仅设定适当的最大长度
l 时间类型
按选择优先级排序DATE(精确到天)、TIMESTAMP、DATETIME(精确到时间)
l ENUM
对于状态字段,可以尝试使用 ENUM 来存放
l 避免使用NULL字段,很难查询优化且占用额外索引空间
正确回答通过率:85.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
同样的内容使用不同字符集表示所占用的空间大小会有较大的差异,所以通过使用合适的字符集,可以帮助我们尽可能减少数据量,进而减少IO操作次数。
1.纯拉丁字符能表示的内容,选择 latin1 字符编码
2.中文可选用utf-8
3.MySQL的数据类型可以精确到字段,所以当我们需要大型数据库中存放多字节数据的时候,可以通过对不同表不同字段使用不同的数据类型来较大程度减小数据存储量,进而降低 IO 操作次数并提高缓存命中率
正确回答通过率:75.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 初级
CSV是逗号分隔值(Comma-Separated Values)或也被称为字符分隔值(Character-Separated Values)的缩写。CSV表以纯文本和表格形式来存储数据。
每一条记录都使用特定的分隔符隔开(如逗号,分号,…),并且每条记录都有着顺序相同的列。CSV表最广泛地被用来存储用于导入和导出的电话联系人,并能够用来存储任何类型的纯文本数据
正确回答通过率:88.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
方法一:
create database DB character set gbk collater gbk_chinese_ci;
方法二:
mysql> create database DB;
mysql> alter database DB character set gbk;
mysql> show create database DB;
正确回答通过率:72.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
【原子性】
整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
【一致性】
一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。
也就是说:如果事务是并发多个,系统也必须如同串行事务一样操作。其主要特征是保护性和不变性(Preserving an Invariant),以转账案例为例,假设有五个账户,每个账户余额是100元,那么五个账户总额是500元,如果在这个5个账户之间同时发生多个转账,无论并发多少个,比如在A与B账户之间转账5元,在C与D账户之间转账10元,在B与E之间转账15元,五个账户总额也应该还是500元,这就是保护性和不变性
【隔离性】
隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
【持久性】
在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
由于一项操作通常会包含许多子操作,而这些子操作可能会因为硬件的损坏或其他因素产生问题,要正确实现ACID并不容易。ACID建议数据库将所有需要更新以及修改的资料一次操作完毕,但实际上并不可行。
目前主要有两种方式实现ACID:第一种是Write ahead logging,也就是日志式的方式(现代数据库均基于这种方式)。第二种是Shadow paging。
相对于WAL(write ahead logging)技术,shadow paging技术实现起来比较简单,消除了写日志记录的开销恢复的速度也快(不需要redo和undo)。shadow paging的缺点就是事务提交时要输出多个块,这使得提交的开销很大,而且以块为单位,很难应用到允许多个事务并发执行的情况——这是它致命的缺点。
WAL 的中心思想是对数据文件 的修改(它们是表和索引的载体)必须是只能发生在这些修改已经 记录了日志之后 – 也就是说,在日志记录冲刷到永久存储器之后. 如果我们遵循这个过程,那么我们就不需要在每次事务提交的时候 都把数据页冲刷到磁盘,因为我们知道在出现崩溃的情况下, 我们可以用日志来恢复数据库:任何尚未附加到数据页的记录 都将先从日志记录中重做(这叫向前滚动恢复,也叫做 REDO) 然后那些未提交的事务做的修改将被从数据页中删除 (这叫向后滚动恢复 - UNDO)。
正确回答通过率:82.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
就是将数据库的表与字段对应到模型层类名与属性的过程.
正确回答通过率:60.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 高难
创建标准索引:
CREATE INDEX 索引名 ON 表名 (列名) TABLESPACE 表空间名;
创建唯一索引:
CREATE unique INDEX 索引名 ON 表名 (列名) TABLESPACE 表空间名;
创建组合索引:
CREATE INDEX 索引名 ON 表名 (列名1,列名2) TABLESPACE 表空间名;
创建反向键索引:
CREATE INDEX 索引名 ON 表名 (列名) reverse TABLESPACE 表空间名;
索引使用原则:
索引字段建议建立NOT NULL约束
经常与其他表进行连接的表,在连接字段上应该建立索引;
经常出现在Where子句中的字段且过滤性很强的,特别是大表的字段,应该建立索引;
可选择性高的关键字 ,应该建立索引;
可选择性低的关键字,但数据的值分布差异很大时,选择性数据比较少时仍然可以利用索引提高效率
复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:
A、正确选择复合索引中的第一个字段,一般是选择性较好的且在where子句中常用的字段上;
B、复合索引的几个字段经常同时以AND方式出现在Where子句中可以建立复合索引;否则单字段索引;
C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
频繁DML的表,不要建立太多的索引;
不要将那些频繁修改的列作为索引列;
索引的优缺点:
有点:
正确回答通过率:77.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
create view 视图名 as select 列名 [别名] … from 表 [unio [all] select … ] ]
好处:
正确回答通过率:78.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
字符型,整数型、复合型
正确回答通过率:93.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
绑定变量是指在SQL语句中使用变量,改变变量的值来改变SQL语句的执行结果。
优点:使用绑定变量,可以减少SQL语句的解析,能减少数据库引擎消耗在SQL语句解析上的资源。提高了编程效率和可靠性。减少访问数据库的次数, 就能实际上减少ORACLE的工作量。
缺点:经常需要使用动态SQL的写法,由于参数的不同,可能SQL的执行效率不同;
绑定变量是相对文本变量来讲的,所谓文本变量是指在SQL直接书写查询条件,
这样的SQL在不同条件下需要反复解析,绑定变量是指使用变量来代替直接书写条件,查询bind value在运行时传递,然后绑定执行。
优点是减少硬解析,降低CPU的争用,节省shared_pool
缺点是不能使用histogram,sql优化比较困难
正确回答通过率:38.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 高难
如果你的系统需要在一张很大的表上创建一个索引,你会考虑哪些因素?
1)关于大表创建索引,如果从综合考虑多个维度来看,我会考虑:
2)以下关于几种考虑因素的分析过程:
1.为什么需要创建索引
A. 结合应用查询场景,比如是否存在相应关键业务的SQL需要使用到索引相关字段的条件,其SQL执行频繁是否较大;该部分业务SQL根据索引所返回的结果集大小,比如一个表有一个亿,每次根据相应条件返回了几千万的结果集,那创建该索引是否真正有效
B. 结合表数据分布情况,第一个是列数据选择性问题,如果选择性不高,有时索引回表的cost比全表扫描大,优化器选择执行计划路径是可能不选择索引。第二个列数据较为无序,导致创建索引后集群因子较高,增加索引回表成本等。
C. 结合表数据变化情况,,增加一个索引便需要多维护一个索引,对一张数据变化频率较高的表,索引太多会增加dml操作特别是insert时的索引维护成本,影响执行效率
2.创建什么样的索引
A.如果使用多个条件便可以创建复合索引
B.如果业务sql条件存在函数,那就要考虑函数索引
C.如果一个列基数较低,那是否考虑选择位图索引,前提是其列数据很少更新
D.分区表是否创建本地索引
3.创建索引的影响
我们都知道创建索引会与dml操作相互影响以及还有大量的IO操作等。
首先,是了解创建索引的过程,才能解决创建索引带来的问题,我做了个创建索引的实验,并通过10046追踪,创建索引的主要过程如下:
A. 开始读取数据字典如统计信息,对象信息等
B. 使用share mode nowait将表锁住,此时其他会话只可读该表但无法修改该表。
C. 读取一些信息等判断后在obj 初始化索引对象信息 D . 开始抓取表数据等一系列大量 I O 操作,该过程时间相对较长: E . 往 s e g 初始化索引对象信息 D.开始抓取表数据等一系列大量IO操作,该过程时间相对较长: E.往seg 初始化索引对象信息D.开始抓取表数据等一系列大量IO操作,该过程时间相对较长:E.往seg,icol , i n d ,ind ,ind等信息表中插入相应信息
完成整个索引排序创建索引,扫描表
从以上索引的创建过程,我们可以考虑的问题点总结是:
A.此过程会加共享锁以至于阻塞dml操作,因此创建索引尽量选择业务空闲期进行,同时也可以考虑online方式创建。
B.此过程需要大量读取表数据并排序操作,以及insert update操作,此时需要考虑存储IO性能
C.此过程会产生大量redo,可以考虑nologing模式
D.同时需要考虑索引的空间大小,关注表空间和临时表空间
E.同时可以使用并行加快操作,这也是我们常做的。
什么时候创建索引
不用考虑,业务空闲期
有没有其他方式来替代这个过程
可以考虑数据迁移方式,创建一张新表添加索引,在线迁入数据后 rename表
正确回答通过率:82.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 初级
事务是这样一种机制,它确保多个SQL语句被当作单个工作单元来处理。事务具有以下的作用: * 一致性:同时进行的查询和更新彼此不会发生冲突,其他用户不会看到发生了变化但尚未提交的数据。 * 可恢复性:一旦系统故障,数据库会自动地完全恢复未完成的事务
正确回答通过率:83.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 初级
DBMS是⼀个控制数据维护和使⽤的程序,它被认为是管理数据的⽂件管理器。有四种类型的DBMS:
· 关系DBMS
· 分层DBMS
· ⽹络DBMS
· ⾯向对象的关系DBMS
最有⽤的DBMS是Relational DBMS。它为数据提供了⼀个关系运算符。
正确回答通过率:49.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 高难
聚集索引——有助于轻松检索数据,并且只有⼀个聚集索引与⼀个表⼀起分配。它会更改记录在数据库中的保存⽅式。
⾮聚集索引——与聚集索引相⽐,⾮聚集索引很慢。并且在⾮集群索引的情况下,该表可以具有多个索引,为表创建⼀个对象,该表是搜索
后指向表的⼀个点。
正确回答通过率:89.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
触发器⽤于对表执⾏特定操作,例如INSERT、UPDATE或DELETE。它是⼀种存储过程。动作和事件是触发器的主要组成部分。执⾏
Action时,事件响应该操作⽽出现。
正确回答通过率:86.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
通常,这些属性称为ACID。它们在数据库事务中起作⽤。
Atomicity(原⼦性)——在连接两个或多个单独数据的事务中,要么所有部分都已提交,要么都没有。
Consistency(⼀致性)——事务或者⽣成新的有效数据状态,或者如果发⽣任何失望,则在事务启动之前将所有数据返回到其状态。
Isolation(隔离性)——正在进⾏且尚未提交的事务必须继续与任何其他操作隔离。
Durability(持久性)——在此操作中,系统保存已提交的数据,每当事件失败和系统重新启动时,所有数据都可在其正确位置获得。
正确回答通过率:92.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
在系统内存中执⾏SQL语句时,会创建⼀个临时⼯作区,称为“游标”。在select语句中,游标存储了信息。游标可以使⽤多⾏,但⼀次只
能处理⼀⾏。这组⾏称为活动集。
游标有两种类型:
· ImplicitCursor(隐式游标)
· ExplicitCursor(显式游标)
正确回答通过率:65.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
Null值是没有值的字段。它与0不同。假设有⼀个表,并且在表中有⼀个字段,可以在不添加值的情况下将记录插⼊字段,然后该字段将以
NULL值保存。
空格是我们提供的值。
正确回答通过率:84.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
使用create和replace来更新view。
create or replace view viewname as select columname from tablename where condition
正确回答通过率:79.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
有两种System privilege和object privilege。
System privilege主要做的工作有alter any index, alter any cache group, create, alter, delete table, create, alter,delete view等等。
对象privilege包含,execute, insert, update, delete. select, flush, load, index, references等操作。
正确回答通过率:89.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 初级
SQL注入(SQL injection),是发生于应用程序与数据库层的安全漏洞。只要是支持处理SQL指令的数据库服务器,都有可能受到此种手法的攻击。
SQL注入产生的原因,是未经检查或者未经充分检查的用户输入数据,意外变成了代码被执行。针对于SQL注入,则是用户提交的数据,被数据库系统编译而产生了开发者预期之外的动作。也就是,SQL注入是用户输入的数据,在拼接SQL语句的过程中,超越了数据本身,成为了SQL语句查询逻辑的一部分,然后这样被拼接出来的SQL语句被数据库执行,产生了开发者预期之外的动作。
是网站存在最多也是最简单的漏洞。主要原因是程序对用户输入数据的合法性没有判断和处理,导致攻击者可以在 Web 应用程序中事先定义好的 SQL 语句中添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步获取到数据信息。
正确回答通过率:73.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
临时表只在当前连接可见,当关闭连接时会被自动删除并释放所有空间,因此可以在不同连接中创建同名的临时表
临时表的创建与语法为CREATE TEMPOPARY TABLE tmp_table
临时表也可以手动删除DELETE TEMPOPARY TABLE IF EXISTS tmp_table
正确回答通过率:72.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
count 用于求行的个数;sum 用于累加求和
count() 对行的数目进行计算,包含NULL
count(1) 与 count() 效果相同
count(column) 对特定列的行数进行计算,不包含NULL
正确回答通过率:54.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
脏读(Dirty Read)
事务A读取了事务B更新但尚未提交的数据,然后事务B进行了回滚操作,那么事务A读取到的数据就是脏数据
不可重复读(Non-repeatable read)
事务A多次读取同一数据,而事务B在这个过程中对数据进行了更新并提交,导致事务A多次读取的结果不一致
幻读(Phantom Read)
事务A多次读取数据并统计读取数据的条数,在这个过程中事务B新增了数据行并提交,导致事务A多次读取得到的结果条数不一样
正确回答通过率:67.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
1 读取未提交(READ-UNCOMMITED)
最低隔离级别
2 读取已提交(READ-COMMITTED)
仅能够阻止脏读
3 可重复读(REPEATED-READ)
对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,该级别也是MySQL默认采取的隔离级别
4 可串行化(SERIALIZABLE)
最高隔离级别,完全符合ACID要求,即所有事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
注:隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,但在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
正确回答通过率:93.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
数据库是数据的结构化集合。
一个 数据库管理系统 (DBMS)是一个软件应用程序与用户,应用程序和数据库本身交互,以捕获和分析数据。
DBMS允许用户与数据库进行交互。可以修改,检索和删除存储在数据库中的数据,并且可以是任何类型,例如字符串,数字,图像等。
DBMS有两种类型:
关系数据库管理系统:数据存储在关系(表)中。示例– MySQL。
非关系数据库管理系统:没有关系,元组和属性的概念。示例– Mongo
正确回答通过率:84.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 初级
实体:现实世界中可以在数据库中存储有关数据的人,地方或事物。表存储代表一种实体类型的数据。例如–银行数据库有一个客户表来存储客户信息。客户表将此信息存储为每个客户的一组属性(表中的列)。
关系:实体之间有关联的关系或链接。例如–客户名称与客户帐号和联系信息相关,它们可能在同一表中。各个表之间也可能存在关系(例如,客户到帐户)
正确回答通过率:91.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 初级
关系或链接是在相互关联的实体之间。关系定义为数据库中表之间的连接。存在各种关系,即:
一对一关系。
一对多关系。
多对一关系。
自引用关系。
正确回答通过率:65.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
递归存储过程是指一个存储过程,它会自行调用直到达到某个边界条件。此递归函数或过程可帮助程序员多次使用同一组代码。
正确回答通过率:79.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
STUFF函数:此函数用于覆盖现有字符或将一个字符串插入另一个字符串。句法:
STUFF(字符串表达式,开始,长度,替换字符)
其中, string_expression:将替换字符的字符串
start:指起始位置 长度:指字符串中要替换的字符数。
replace_string:它们是注入字符串中的新字符。
REPLACE函数:此函数用于替换所有出现的现有字符。句法:
REPLACE(string_expression,search_string,replacement_string)
正确回答通过率:59.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 高难
B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接,是有序的
哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可,是无序的
正确回答通过率:56.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
等值查询,哈希索引具有绝对优势(前提是:没有大量重复键值,如果大量重复键值时,哈希索引的效率很低,因为存在所谓的哈希碰撞问题。)
哈希索引不适用的场景:
不支持范围查询
不支持索引完成排序
不支持联合索引的最左前缀匹配规则
通常,B+树索引结构适用于绝大多数场景,像下面这种场景用哈希索引才更有优势:
在HEAP表中,如果存储的数据重复度很低(也就是说基数很大),对该列数据以等值查询为主,没有范围查询、没有排序的时候,特别适合采用哈希索引,例如这种SQL:
#仅等值查询
select id, name from table where name=‘李明’;
而常用的 InnoDB 引擎中默认使用的是B+树索引,它会实时监控表上索引的使用情况。
如果认为建立哈希索引可以提高查询效率,则自动在内存中的“自适应哈希索引缓冲区”建立哈希索引(在InnoDB中默认开启自适应哈希索引)。
通过观察搜索模式,MySQL会利用index key的前缀建立哈希索引,如果一个表几乎大部分都在缓冲池中,那么建立一个哈希索引能够加快等值查询。
注意:在某些工作负载下,通过哈希索引查找带来的性能提升远大于额外的监控索引搜索情况和保持这个哈希表结构所带来的开销。
但某些时候,在负载高的情况下,自适应哈希索引中添加的read/write锁也会带来竞争,比如高并发的join操作。like操作和%的通配符操作也不适用于自适应哈希索引,可能要关闭自适应哈希索引。
正确回答通过率:47.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 高难
1、B树,每个节点都存储key和data,所有节点组成这棵树,并且叶子节点指针为nul,叶子结点不包含任何关键字信息。
2、B+树,所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接
所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。(而B 树的非终节点也包含需要查找的有效信息)
正确回答通过率:47.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 高难
1、B+的磁盘读写代价更低。
B+的内部结点并没有指向关键字具体信息的指针,因此其内部结点相对B树更小。
如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。
2、B±tree的查询效率更加稳定。
由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
正确回答通过率:34.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 高难
1、表记录太少
2、经常插入、删除、修改的表
3、数据重复且分布平均的表字段,假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一般不会提高数据库的查询速度。
4、经常和主字段一块查询但主字段索引值比较多的表字段
正确回答通过率:64.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。
【表分区与分表的区别】
分表:指的是通过一定规则,将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。
分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。
正确回答通过率:54.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
1、存储更多数据。分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。和单个磁盘或者文件系统相比,可以存储更多数据
2、优化查询。在where语句中包含分区条件时,可以只扫描一个或多个分区表来提高查询效率;涉及sum和count语句时,也可以在多个分区上并行处理,最后汇总结果。
3、分区表更容易维护。例如:想批量删除大量数据可以清除整个分区。
4、避免某些特殊的瓶颈,例如InnoDB的单个索引的互斥访问,ext3问价你系统的inode锁竞争等
正确回答通过率:75.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
1、一个表最多只能有1024个分区
2、MySQL5.1中,分区表达式必须是整数,或者返回整数的表达式。在MySQL5.5中提供了非整数表达式分区的支持。
3、如果分区字段中有主键或者唯一索引的列,那么多有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。
4、分区表中无法使用外键约束
5、MySQL的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。
正确回答通过率:52.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control)
注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Control
MVCC最大的好处:读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能,现阶段几乎所有的RDBMS,都支持了MVCC。
LBCC:Lock-Based Concurrency Control,基于锁的并发控制
MVCC:Multi-Version Concurrency Control
基于多版本的并发控制协议。纯粹基于锁的并发机制并发量低,MVCC是在基于锁的并发控制上的改进,主要是在读操作上提高了并发量。
正确回答通过率:79.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
快照读 (snapshot read):读取的是记录的可见版本 (有可能是历史版本),不用加锁(共享读锁s锁也不加,所以不会阻塞其他事务的写)
当前读 (current read):读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录
正确回答通过率:62.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
【行级锁定的优点】
1、当在许多线程中访问不同的行时只存在少量锁定冲突。
2、回滚时只有少量的更改
3、可以长时间锁定单一的行。
【行级锁定的缺点】
比页级或表级锁定占用更多的内存。
当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁。
如果你在大部分数据上经常进行GROUP BY操作或者必须经常扫描整个表,比其它锁定明显慢很多。
用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定。
正确回答通过率:54.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
1、字段名及字段配制合理性
剔除关系不密切的字段;
字段命名要有规则及相对应的含义(不要一部分英文,一部分拼音,还有类似a.b.c这样不明含义的字段);
字段命名尽量不要使用缩写(大多数缩写都不能明确字段含义);
字段不要大小写混用(想要具有可读性,多个英文单词可使用下划线形式连接);
字段名不要使用保留字或者关键字;
保持字段名和类型的一致性;
慎重选择数字类型;
-给文本字段留足余量;
2、系统特殊字段处理及建成后建议
添加删除标记(例如操作人、删除时间);
建立版本机制;
3、表结构合理性配置
多型字段的处理,就是表中是否存在字段能够分解成更小独立的几部分(例如:人可以分为男人和女人);
多值字段的处理,可以将表分为三张表,这样使得检索和排序更加有调理,且保证数据的完整性!
4、其它建议
对于大数据字段,独立表进行存储,以便影响性能(例如:简介字段);
使用varchar类型代替char,因为varchar会动态分配长度,char指定长度是固定的;
给表创建主键,对于没有主键的表,在查询和索引定义上有一定的影响;
避免表字段运行为null,建议设置默认值(例如:int类型设置默认值为0)在索引查询上,效率立显;
建立索引,最好建立在唯一和非空的字段上,建立太多的索引对后期插入、更新都存在一定的影响(考虑实际情况来创建);
正确回答通过率:85.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 初级
如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引、
如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、
如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。
数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)
如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新记录都要被插到现有索引页的中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。
正确回答通过率:85.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
优点:
1)存储过程是预编译过的,执行效率高。
2)存储过程的代码直接存放于数据库中,通过存储过程名直接调用,减少网络通讯。
3)安全性高,执行存储过程需要有一定权限的用户。
4)存储过程可以重复使用,可减少数据库开发人员的工作量。
缺点:
移植性差
正确回答通过率:91.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
优点:
1对数据库的访问,因为视图可以有选择性的选取数据库里的一部分。
2)用户通过简单的查询可以从复杂查询中得到结果。
3)维护数据的独立性,试图可从多个表检索数据。
4)对于相同的数据可产生不同的视图。
缺点:
性能:查询视图时,必须把视图的查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,那么就无法更改数据
正确回答通过率:67.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 中级
非关系型数据库的优势:
性能:NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
可扩展性:同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
关系型数据库的优势:
复杂查询:可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
事务支持:使得对于安全性能很高的数据访问要求得以实现。
其他:
1.对于这两类数据库,对方的优势就是自己的弱势,反之亦然。
2.NOSQL数据库慢慢开始具备SQL数据库的一些复杂查询功能,比如MongoDB。
3.对于事务的支持也可以用一些系统级的原子操作来实现例如乐观锁之类的方法来曲线救国,比如Redis set nx。
正确回答通过率:60.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 高难
多列索引:
ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);
为了提高搜索效率,我们需要考虑运用多列索引,由于索引文件以B-Tree格式保存,所以我们不用扫描任何记录,即可得到最终结果。
注:在mysql中执行查询时,只能使用一个索引,如果我们在lname,fname,age上分别建索引,执行查询时,只能使用一个索引,mysql会选择一个最严格(获得结果集记录数最少)的索引。
最左前缀原则:顾名思义,就是最左优先,上例中我们创建了lname_fname_age多列索引,相当于创建了(lname)单列索引,(lname,fname)组合索引以及(lname,fname,age)组合索引。
正确回答通过率:38.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 高难
聚合索引(clustered index):
聚集索引表记录的排列顺序和索引的排列顺序一致,所以查询效率快,只要找到第一个索引值记录,其余就连续性的记录在物理也一样连续存放。聚集索引对应的缺点就是修改慢,因为为了保证表中记录的物理和索引顺序一致,在记录插入的时候,会对数据页重新排序。
聚集索引类似于新华字典中用拼音去查找汉字,拼音检索表于书记顺序都是按照a~z排列的,就像相同的逻辑顺序于物理顺序一样,当你需要查找a,ai两个读音的字,或是想一次寻找多个傻(sha)的同音字时,也许向后翻几页,或紧接着下一行就得到结果了。
非聚合索引(nonclustered index):
非聚集索引指定了表中记录的逻辑顺序,但是记录的物理和索引不一定一致,两种索引都采用B+树结构,非聚集索引的叶子层并不和实际数据页相重叠,而采用叶子层包含一个指向表中的记录在数据页中的指针方式。非聚集索引层次多,不会造成数据重排。
非聚集索引类似在新华字典上通过偏旁部首来查询汉字,检索表也许是按照横、竖、撇来排列的,但是由于正文中是a~z的拼音顺序,所以就类似于逻辑地址于物理地址的不对应。同时适用的情况就在于分组,大数目的不同值,频繁更新的列中,这些情况即不适合聚集索引。
根本区别:
聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致。
正确回答通过率:72.0%
[ 详情 ] 推荐指数: ★★★ 试题难度: 中级
原子性(Atomicity):
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性(Consistency):
事务开始前和结束后,数据库的完整性约束没有被破坏。比如A向B转账,不可能A扣了钱,B却没收到。
隔离性(Isolation):
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
持久性(Durability):
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
事务:实战分析:事务的隔离级别和传播属性
正确回答通过率:51.0%
[ 详情 ] 推荐指数: ★★★★ 试题难度: 中级
1.PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
2.PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
3.PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
4.PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
5.PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6.PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7.PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
正确回答通过率:53.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 高难
什么是嵌套事务?
嵌套是子事务套在父事务中执行,子事务是父事务的一部分,在进入子事务之前,父事务建立一个回滚点,叫save point,然后执行子事务,这个子事务的执行也算是父事务的一部分,然后子事务执行结束,父事务继续执行。重点就在于那个save point。看几个问题就明了了:
如果子事务回滚,会发生什么?
父事务会回滚到进入子事务前建立的save point,然后尝试其他的事务或者其他的业务逻辑,父事务之前的操作不会受到影响,更不会自动回滚。
如果父事务回滚,会发生什么?
父事务回滚,子事务也会跟着回滚!为什么呢,因为父事务结束之前,子事务是不会提交的,我们说子事务是父事务的一部分,正是这个道理。那么:
事务的提交,是什么情况?
是父事务先提交,然后子事务提交,还是子事务先提交,父事务再提交?答案是第二种情况,还是那句话,子事务是父事务的一部分,由父事务统一提交。
正确回答通过率:62.0%
[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级
(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 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
正确回答通过率:87.0%
[ 详情 ] 推荐指数: ★★ 试题难度: 初级
幻读就是指当一个事务正在访问数据,并且对数据进行了修改,但是还没有来得及提交到数据库中,这时,另一个事务也访问这个数据,然后使用了这个数据