面试官常问的 数据库 问题(二)
面试官常问的 数据库 问题 11-21
- 11.Oracle 跟 SQL Server 的区别?
- 12.关系型数据库和非关系型数据库区别,优势比较?
- 13.MYSQL 的两种存储引擎区别(事务、锁级别等等),各自的适用场景
- 14.MongoDB 与 Redis 区别
- 15.Memcached 和 redis 的区别
- 16.在项目中缓存用在哪里
- 17.Redis 如何持久化
- 18.Redis 的内存淘汰策略有那些
- 19.redis 有哪些数据类型
- 20.Redis 一般用在那些场景
- 21.SQL 题目
11.Oracle 跟 SQL Server 的区别?
oracle:可在不同平台运行(ISO标准认证);支持PL-SQL脚本语言;性能很高;
sqlserver:只可在 windows 平台运行(不安全、不稳定);支持T-SQL脚本语言;多用户性能低;
一般不用SQL Server !!!
区别:
1、最大的区别在于平台。oracle 可以运行在不同的平台上;sqlserver 只能运行在 windows 平台上。windows 平台的稳定性和安全性,影响了 sqlserver 的稳定性和安全性。
2、oracle 使用的脚本语言为 PL-SQL,而 sqlserver 使用的脚本为 T-SQL 。
文体结构不同
3、体系结构不同。
oracle的文件体系结构为:
数据文件 .dbf(真实数据)
日志文件 .rdo
控制文件 .ctl
参数文件 .ora
sql server的文件体系结构为:
.mdf (数据字典)
.ndf (数据文件)
.ldf (日志文件)
4、存储结构不同。
oracle存储结构:
在oracle里有两个块参数pctfree(填充因子)和pctused(复用因子),可控制块确定块本身何时有,何时没有足够的空间接受新信息(对块的存储情况的分析机制)。这样可降低数据行连接与行迁移的可能性。块的大小可设置(oltp块和dss块)。
在oracle中,将连续的块组成区,可动态分配区(区的分配可以是等额的也可以是自增长的)可减少空间分配次数。
在oraclel里表可以分为多个段,段由多个区组成,每个段可指定分配在哪个表空间里(段的类型分为:数据段、索引段、回滚段、临时段、cash段。oracle里还可对表进行分区,可按照用户定义的业务规则、条件或规范,物理的分开磁盘上的数据。
这样大大降低了磁盘争用的可能性。
oracle有七个基本表空间:
·system表空间(存放数据字典和数据管理自身所需的信息)
·rbs回滚表空间
·temp临时表空间
·tools交互式表空间
·users用户默认表空间
·indx索引表空间
·dbsys福数据表空间
不同的数据分别放在不同的表空间(数据字典与真实数据分开存放),在oracle里基表(存储系统参数信息)是加密存储,任何人都无法访问。只能通过用户可视视图查看。
sql server 存储结构:
以页为最小分配单位,每个页为8k(不可控制,缺乏对页的存储情况的分析机制),可将8个连续的页的组成一个‘扩展’,以进一步减少分配时所耗用的资源。(分配缺乏灵活性),在sql server里数据以表的方式存放,而表是存放在数据库里。
sql server有五个基本数据库: www.2cto.com
·master(数据字典)
·mode(存放样版)
·tempdb(临时数据库)
·msdb(存放调度信息和日志信息)
·pubs(示例数据库)
真实数据与数据字典存放在一起。对系统参数信息无安全机制。
12.关系型数据库和非关系型数据库区别,优势比较?
关系型数据库:可用 SQL 语句在一个以上表之间做非常复杂的数据查询;安全性高;数据存储在硬盘;
非关系型数据库:性能高;可扩展(水平扩展);数据存储在缓存,比关系型数据库查询快;
非关系型数据库的优势:
性能:NOSQL 是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过 SQL 层的解析,所以性能非常高。
可扩展性:同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
关系型数据库的优势:
复杂查询:可以用 SQL 语句在一个表以及多个表之间做非常复杂的数据查询。
事务支持:使得对于安全性能很高的数据访问要求得以实现。
13.MYSQL 的两种存储引擎区别(事务、锁级别等等),各自的适用场景
MySql主要有两种存储引擎:InnoDB和MyISAM。
InnoDB:支持事务、外键;支持行级锁;聚集索引;不保存行数;不支持全文类型索引(查表总行数时,不需要全表扫描);
MyISAM:不支持事务、外键;支持表级锁(性能低);非聚集索引;保存行数;支持全文类型索引(查表总行数时,全表扫描);
使用场景:一般默认InnoDB,当表比较小,读取操作较多,插入和更新少,不要考虑事务,可以考虑MyIsam。
区别
- InnoDB支持事务,后者不支持
- InnoDB支持外键,MyIsam不支持
- InnoDB支持行级锁,MyIsam是表级锁,表级锁性能低
- InnoDB是聚集索引,即索引中键值的逻辑顺序决定了表中相应行的物理顺序,而MyIsam是非聚集索引,即索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
- InnoDB不保存行数,后者保存。
使用场景,一般默认都是InnoDB,如果表比较小,读取操作较多,插入和更新操作少,不需要考虑事务,可以考虑MyIsam
14.MongoDB 与 Redis 区别
①.性能方面:redis 要大于 mongodb ;
②.操作便利性:Mongodb 支持丰富的数据表达、索引,最类似关系型数据库,支持的查询语言非常丰富 ;Redis 数据结构方面丰富
③.内存空间大小和数据量大小:Mongodb 适合大量数据的存储 ;
④.数据一致性:Redis 事务支持比较弱 ;Mongodb 不支持事务 ;
⑤.应用场景:Redis 用在数据量较小的操作和运算上;Mongodb 主要解决海量数据的访问效率问题。
redis、memcache、mongoDB 对比
从以下几个维度,对redis、memcache、mongoDB 做了对比,欢迎拍砖
1、性能
都比较高,性能对我们来说应该都不是瓶颈
总体来讲,TPS方面redis和memcache差不多,要大于mongodb
2、操作的便利性
memcache数据结构单一
redis丰富一些,数据操作方面,redis更好一些,较少的网络IO次数
mongodb支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富
3、内存空间的大小和数据量的大小
redis在2.0版本后增加了自己的VM特性,突破物理内存的限制;可以对key value设置过期时间(类似memcache)
memcache可以修改最大可用内存,采用LRU算法
mongoDB适合大数据量的存储,依赖操作系统VM做内存管理,吃内存也比较厉害,服务不要和别的服务在一起
4、可用性(单点问题)
对于单点问题,
redis,依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题,
所以单点问题比较复杂;不支持自动sharding,需要依赖程序设定一致hash 机制。
一种替代方案是,不用redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡
Memcache本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题。
mongoDB支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制。
5、可靠性(持久化)
对于数据持久化和数据恢复,
redis支持(快照、AOF):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响
memcache不支持,通常用在做缓存,提升性能;
MongoDB从1.8版本开始采用binlog方式支持持久化的可靠性
6、数据一致性(事务支持)
Memcache 在并发场景下,用cas保证一致性
redis事务支持比较弱,只能保证事务中的每个操作连续执行
mongoDB不支持事务
7、数据分析
mongoDB内置了数据分析的功能(mapreduce),其他不支持
8、应用场景
redis:数据量较小的更性能操作和运算上
memcache:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding)
MongoDB:主要解决海量数据的访问效率问题
15.Memcached 和 redis 的区别
①.存储方式:Memcached 数据都在内存中,断电后会挂掉,数据不可超过内存大小;Redis 部分存在硬盘上,保证数据的持久性 ;
②.数据支持类型:Memcached 对数据类型支持相对简单 ;Redis 有复杂的数据类型 ;
③.Value 大小:Redis 最大可以达到 1G;Memcached 只有 1MB。
16.在项目中缓存用在哪里
缓存数据(查询多删改少的数据)比如:数据字典(改动少,基本不改动)
为什么使用缓存?:
缓存主要用途有两个,高性能和高并发。
高并发的场景不常见,所以项目用它的目的是高性能。
如果一个数据被大量的读取,那么可以将它放入缓存中,被读取时直接从缓存中通过key查出value,这样可以大幅提升性能。
使用缓存存在哪些问题?
①缓存雪崩。
②缓存穿透。
③缓存与数据量双写不一致。
④缓存并发竞争。
17.Redis 如何持久化
持久化:将内存中的数据写入到硬盘中。
Redis实现数据持久化的两种实现方式:1、RDB实现Redis数据持久化(默认方式);2、AOF持久化方案;
RDB:指定的时间间隔内保存数据快照;
AOF:先把命令追加到操作日志的尾部,保存所有的历史操作;
RDB:将数据写入到一个临时文件(dump.rdb),持久化结束之后,用这个临时文件替换上次持久化的文件,达到数据恢复。
间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失,所以这种方式更适合数据要求不严谨的时候,
默认开启的 AOF:是将执行过的指令记录下来,数据恢复时按照从前到后的顺序再将指令执行一遍,实现数据恢复。
AOF 相比于RDB的优点:可以保证数据完整,可对历史操作进行处理;
但是 AOF 文件比 RDB 文件大,且恢复速度慢,默认是关闭的。
18.Redis 的内存淘汰策略有那些
①.noeviction:默认策略,不删除任意数据,但是内存不够时,会直接返回错误
②.Allkeys-lru:从数据集中(包括设置过期时间和未设置过期时间的数据集),优先移除最近未使用的 key
③.Volatile-lru:在设置了过期时间的数据集中,优先移除最近未使用的 key
④.Allkeys-random:从数据集中(包括设置过期时间和未设置过期时间的数据集),随机移除某个 key
⑤.Volatile-random:在设置了过期时间的数据集中,随机移除某个 key Volatile-ttl:在设置了过期时间的数据集中,具有更早过期时间的 key 优先移除。
Redis 的内存淘汰:用户存储的一些键可以被 redis 主动从实例中删除,从而产生读 miss 的情况,
内存淘汰是为了更好的使用内存,用一定的缓存 miss 来换取内存的使用率。
Redis 提供的内存淘汰策略有:
①.noeviction:默认策略,不删除任意数据,但是内存不够时,会直接返回错误
②.Allkeys-lru:从数据集中(包括设置过期时间和未设置过期时间的数据集),优先移除最近未使用的 key
③.Volatile-lru:在设置了过期时间的数据集中,优先移除最近未使用的 key
④.Allkeys-random:从数据集中(包括设置过期时间和未设置过期时间的数据集),随机移除某个 key
⑤.Volatile-random:在设置了过期时间的数据集中,随机移除某个 key Volatile-ttl:在设置了过期时间的数据集中,具有更早过期时间的 key 优先移除。
redis 的雪崩、穿透
缓存穿透
什么是缓存穿透?
一般的缓存系统,都是按照key(键)去缓存查询,如果不存在对应的value(值),就应该去DB(数据库)中查找 。
这个时候,如果请求的并发量很大,就会对后端的DB系统造成很大的压力。这就叫做缓存穿透!
造成的原因:- 业务自身代码或数据出现问题;
- 一些恶意攻击、爬虫造成大量空的命中,此时会对数据库造成很大压力。
解决方法:
- 设置布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,
从避免了对底层存储系统的查询压力。 - 如果一个查询返回的数据为空,不管是数据不存在还是系统故障,我们仍然把这个结果进行缓存,但是它的过期时间会很短
最长不超过5分钟。
服务雪崩
什么是雪崩?
因为缓存层承载了大量的请求,有效的保护了存储层。但是如果缓存由于某些原因,整体不能够提供服务,于是所有的请求,就会到达存储层,存储层的调用量就会暴增,造成存储层也会挂掉的情况。
缓存雪崩的英文解释是奔逃的野牛,指的是缓存层当掉之后,并发流量会像奔腾的野牛一样,大量后端存储。造成的原因:
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,大量数据会去直接访问DB,此时给DB很大的压力。
解决方法:- 设置redis集群和DB集群的高可用,如果redis出现宕机情况,可以立即由别的机器顶替上来。这样可以防止一部分的风险。
使用互斥锁
在缓存失效后,通过加锁或者队列来控制读和写数据库的线程数量。比如:对某个key只允许一个线程查询数据和写缓存,其他线程等待。单机的话,可以使用synchronized或者lock来解决,如果是分布式环境,可以是用redis的setnx命令来解决。
- 不同的key,可以设置不同的过期时间,让缓存失效的时间点不一致,尽量达到平均分布。
永远不过期
redis中设置永久不过期,这样就保证了,不会出现热点问题,也就是物理上不过期。
资源保护
使用netflix的hystrix,可以做各种资源的线程池隔离,从而保护主线程池。
19.redis 有哪些数据类型
String(字符串)、Hash(哈希)、List(列表)、Sets(集合)、ZSet(有序集合)
①.String(字符串):redis 最基本的数据类型,一个 key 对应一个 value,一个键最大能存储 512MB
②.Hash(哈希):是一个键值对集合,特别适合用于存储对象
③.List(列表):存放多个字符串值,可以重复,按照插入顺序进行排序,也可以添加一个元素到列表的头部和尾部
④.Sets(集合):存放多个值,不可以重复,没有顺序
⑤.ZSet(有序集合):存放多个值,不可以重复,有顺序。不同的是每个元素都会关联一个 double 类型的分数,redis 正是通过分 数来为集合中的成员进行从小到大的排序
20.Redis 一般用在那些场景
①.缓存热数据(热数据:查询多删改少的数据 )
②.计数器,诸如统计点击数等应用
③.队列
④.位操作(大数据处理),比如统计 QQ 用户在线
⑤.分布式锁和单线程机制
⑥.最新列表
⑦.排行榜,使用 zadd 添加有序集合
redis使用场景:会话缓存(Session Cache)、全页缓存(FPC)、排行榜/计数器
redis优点:
- 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
- 支持丰富数据类型,支持string,list,set,sorted set,hash
- 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
- 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
21.SQL 题目
在GRADE表中查找80-90份的学生学号和分数
select 学号,分数 from grade where 分数 between 80 and 90
在GRADE 表中查找课程编号为003学生的平均分
select avg(分数) from grade where 课程编号='003'
在GRADE 表中查询学习各门课程的人数
select 课程编号,count(学号) as 人数 from grade group by 课程编号
查询所有姓张的学生的学号和姓名
select 姓名,学号 from student_info where 姓名 like'张%'
查询和学号’0001’的这位同学性别相同的所有同学的姓名和出生年月
select 姓名,出生年月 from student_info where 性别 in(select 性别 from student_info where sno='0001')
查询所有选修课程编号为0002 和0003的学生的学号、姓名和性别
select 学号,姓名,性别 from student_infowhere 学号 in(select 学号 from grade where 课程编号='0002' and 学号 in(select 学号 from grade where 课程编号='0001'))
查询出学号为0001的学生的分数比0002号学生最低分高的课程编号的课程编号和分数
select 课程编号, 分数 from grade where 学号='0001'and 分数>(select min(分数) from grade where 学号='0002')
查询分数在80-90分的学生的学号、姓名、分数
select student_info.学号,student_info.姓名,grade.分数 from student_info,grade where grade.分数 between 80 and 90
查询学习了’C语言’课程的学生学号、姓名和分数
select student_info.学号,student_info.姓名,grade.成绩 from student_info,grade,curriculum where student_info.学号=grade.学号 and grade.课程号=curriculum.课程号 and curriculum.课程名='C 语言'
查询所有学生的总成绩,要求列出学号、姓名、总成绩,没有选课的学生总成绩为空。
select grade.学号,student_info.姓名,sum(grade.成绩) as 总成绩 from student_info,grade where grade.学号=student_info.学号 group by grade.学号,student_info.姓名
还没有评论,来说两句吧...