数据库和缓存

1.列举常见的关系型数据库和非关系型都有那些? 关系型数据库:Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL等。 非关系型数据库: MongoDB、Redis、NoSql、Cloudant等。 2.MySQL常见数据库引擎及比较?
3.简述数据三大范式? 第一范式:确保每列的原子性.       如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式.       例如:顾客表(姓名、编号、地址、……)其中"地址"列还可以细分为国家、省、市、区等。   第二范式:在第一范式的基础上更进一层,目标是确保表中的每列都和主键相关.       如果一个关系满足第一范式,并且除了主键以外的其它列,都依赖于该主键,则满足第二范式.       例如:订单表(订单编号、产品编号、定购日期、价格、……),"订单编号"为主键,"产品编号"和 主键列没有直接的关系,即"产品编号"列不依赖于主键列,应删除该列。   第三范式:在第二范式的基础上更进一层,目标是确保每列都和主键列直接相关,而不是间接相关.       如果一个关系满足第二范式,并且除了主键以外的其它列都不依赖于主键列,则满足第三范式.       为了理解第三范式,需要根据Armstrong公里之一定义传递依赖。假设A、B和C是关系R的三个属 性,如果A-〉B且B-〉C,则从这些函数依赖中,可以得出A-〉C,如上所述,依赖A-〉C是传递依 赖。       例如:订单表(订单编号,定购日期,顾客编号,顾客姓名,……),初看该表没有问题,满足第二 范式,每列都和主键列"订单编号"相关,再细看你会发现"顾客姓名"和"顾客编号"相关,"顾客编 号"和"订单编号"又相关,最后经过传递依赖,"顾客姓名"也和"订单编号"相关。为了满足第三范 式,应去掉"顾客姓名"列,放入客户表中。 
4.什么是事务?MySQL如何支持事务? 事务就是一段sql 语句的批处理,但是这个批处理是一个原子 ,不可分割,要么都执行,要么回滚 (rollback)都不执行。
事务具体四大特性,也就是经常说的ACID :
1.原子性(所有操作要么全部成功,要么全部失败回滚)
2.一致性(事务执行之前和执行之后都必须处于一致性状态。)
3.隔离性(数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要 相互隔离)
4.持久性(一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即使遭遇故障依 然能够通过日志恢复最后一次更新) 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支
持事务
MYSQL 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT来实现 BEGIN 开始一个事务 ROLLBACK 事务回滚 COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式: SET AUTOCOMMIT=0 禁止自动提交 SET AUTOCOMMIT=1 开启自动提交
5.简述数据库设计中一对多和多对多的应用场景? 一对一关系示例: 一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号。 一对多关系示例:(下拉单选) 一个学生只属于一个班,但是一个班级有多名学生。 多对多关系示例:(下拉多选) 一个学生可以选择多门课,一门课也有多名学生。 6.如何基于数据库实现商城商品计数器? CREATE TABLE daily_hit_counter(      day date not null,      slot tinyint unsigned not null,      cnt int unsigned not null,      primary( day , slot )           ) ENGINE=InnoDB; 7.常见SQL(必备) 详见武沛齐博客:https://www.cnblogs.com/wupeiqi/articles/5729934.html
8.简述触发器、函数、视图、存储过程? 1)存储过程?     一组为了完成特定功能的SQL 语句集,经编译后存储在数据库。用户通过指定存储过程的名字并 给出参数(如果该存储过程带有参数)来执行它。存储过程在创建时即在服务器上进行编译,所以 执行起来比单个SQL语句快,因为调用存储过程比直接向服务端发送大量SQL语句在执行速度快。   对于存储过程,可以接收参数,其参数有三类:   in          仅用于传入参数用   out        仅用于返回值用   inout     既可以传入又可以当作返回值   2)函数?     封装一段sql代码,完成一种特定的功能,必须返回结果。其余特性基本跟存储过程相同   3)函数与存储过程的区别?     3.1) 函数有且只有一个返回值,而存储过程不能有返回值。     3.2) 存储过程可以实现很复杂的业务逻辑,函数有很多限制。不能在函数中使用 insert,update,delete,create等语句
    3.3)存储过程可以调用函数。但函数不能调用存储过程。     3.4)存储过程一般是作为一个独立的部分来调用。而函数可以作为查询语句的一个部分来调用。   4)视图?     视图是基于 SQL 语句的结果集的可视化虚拟表。     视图中的字段来自一个或多个数据库中的真实表的字段。视图并不在数据库中以存储数据值集形 式存在,而存在于实际引用的数据库表中,视图的构成可以是单表查询,多表联合查询,分组查询 以及计算(表达式)查询等。行和列数据在引用视图时动态生成   5)触发器?     触发器(TRIGGER)与函数类似,需要声明、执行。但是触发器的执行不是由程序调用,而是 由事件来触发从而实现执行。对某个表进行【增/删/改】操作的前后如果希望触发某个特定的行为 时,可以使用触发器,触发器用于定制用户对表的行进行【增/删/改】前后的行为
9.MySQL索引种类 主键索引    唯一索引   普通索引   联合索引   联合唯一索引 10.索引在什么情况下遵循最左前缀的规则? 使用联合索引的时候 11.主键和外键的区别?   1.主键是能确定一条记录的唯一标识,比如,一条记录包括身份证号,姓名,年龄。身份证号是唯 一能确定你这个人的,其他都可能有重复,所以,身份证号是主键。   2.外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。一个表可 以有多个外键。 12.MySQL常见的函数? AVG(col)返回指定列的平均值 COUNT(col)返回指定列中非NULL值的个数 MIN(col)返回指定列的最小值 MAX(col)返回指定列的最大值 SUM(col)返回指定列的所有值之和 13.列举 创建索引但是无法命中索引的8种情况。 1、like 2、使用函数 3、or 4、类型不一致         如果列是字符串类型,传入条件必须是用引号引起来的才行 5、!=         特别的,如果是主键,还是会走索引 6、>      特别的,如果是主键或索引是整数类型,则还是会走索引 7、order by   特别的,如果对主键排序,则还是会走索引 8、组合索引最左前缀 14.如何开启慢日志查询? 有2种方式,一是修改mysql的配置文件,二是通过set global语句来实现。 1、修改配置文件,Windows 的配置文件为 my.ini,一般在 MySQL 的安装目录下。linux 的配置 文件为my.cnf ,一般在 /etc 目录下。
在linux下,vim /etc/my.cnf,在[mysqld]内容项下增加 slow_query_log = ON long_query_time = 2 这里设置慢查询时间long_query_time 设置的是2s,认为超过2秒即为慢查询 没有配置日志文件路径和名称,就使用默认的。 重启msyqld服务就可以生效。 2、二是通过set global语句来实现,可以在mysql -uroot -p登录后,输入: SET GLOBAL slow_query_log = 'ON'; 就可以立即开始慢日志记录,如果想指定时间和文件位置,可以追加配置: SET GLOBAL long_query_time = X; X默认是10s,也就是说超过10s的查询会被记入慢日志。 SET GLOBAL slow_query_log_file = '/path/filename'; 日志路径默认是:/var/lib/mysql/hostname-slow.log 文件名中默认包含了当前服务器的 hostname,我们可以自定义路径和文件名 可以立即生效,但是msyqld重启以后会失效,因为msyql重启的时候,是按照配置文件来加载 配置的,set global语句,只对当前所有会话生效,并未修改配置文件。
15.数据库导入导出命令(结构+数据)?   - 导出现有数据库数据:           mysqldump -u用户名 -p密码 数据库名称 >导出文件路径         # 结构+数据           mysqldump -u用户名 -p密码 -d 数据库名称 >导出文件路径     # 结构   - 导入现有数据库数据:           mysqldump -uroot -p密码 数据库名称 < 文件路径 16.数据库优化方案? - 不使用select * - 短索引 - 使用链表代替子查询 - 固定长度在前面 - 分库分表 - 组合索引 > 索引合并 - 内存代替链表 - choices - limit - 读写分离(主从) - 分页 - 缓存 17.char和varchar的区别? 区别一,定长和变长   char 表示定长,长度固定,varchar表示变长,即长度可变。当所插入的字符串超出它们的长度时, 视情况来处理,如果是严格模式,则会拒绝插入并提示错误信息,如果是宽松模式,则会截取然后
插入。如果插入的字符串长度小于定义长度时,则会以不同的方式来处理,如char(10),表示存 储的是10个字符,无论你插入的是多少,都是10个,如果少于10个,则用空格填满。而 varchar(10),小于10个的话,则插入多少个字符就存多少个。   varchar怎么知道所存储字符串的长度呢?实际上,对于varchar字段来说,需要使用一个(如果字符 串长度小于255)或两个字节(长度大于255)来存储字符串的长度。但是因为他需要有一个prefix来 表示他具体bytes数是多少(因为varchar是变长的,没有这个长度值他不知道如何读取数据)。
  区别之二,存储的容量不同   对 char 来说,最多能存放的字符个数 255,和编码无关。   而 varchar 呢,最多能存放 65532 个字符。VARCHAR 的最大有效长度由最大行大小和使用的字符 集确定。整体最大长度是 65,532字节
18.简述MySQL的执行计划? EXPLAIN命令是查看优化器如何决定执行查询的主要方法。可以帮助我们深入了解MySQL的基于 开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪 种策略预计会被优化器采用。 19.在对name做了唯一索引前提下,简述以下区别:         select * from tb where name = ‘Oldboy-Wupeiqi’         select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1
用where条件过滤出符合条件的数据的同时,进行计数,比如limit 1,那么在where过滤出第1条数据后,他 就会直接把结果select出来返回给你,整个过程就结束了。 20.1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?   答案一:       先查主键,在分页。       select * from tb where id in (           select id from tb where limit 10 offset 30       )   答案二:       按照也无需求是否可以设置只让用户看200页          答案三:       记录当前页  数据ID最大值和最小值       在翻页时,根据条件先进行筛选;筛选完毕之后,再根据limit offset 查询。              select * from (select * from tb where id > 22222222) as B limit 10 offset 0              如果用户自己修改页码,也可能导致慢;此时对url种的页码进行加密
21.什么是索引合并? 1、索引合并是把几个索引的范围扫描合并成一个索引。 2、索引合并的时候,会对索引进行并集,交集或者先交集再并集操作,以便合并成一个索引。 3、这些需要合并的索引只能是一个表的。不能对多表进行索引合并。
         简单的说,索引合并,让一条sql可以使用多个索引。对这些索引取交集,并集,或者先取交 集再取并集。从而减少从数据表中取数据的次数,提高查询效率。
22.什么是覆盖索引? 如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不 需要回表操作 23.简述数据库读写分离? 读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、 DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步 到集群中的从数据库。 24.简述数据库分库分表?(水平、垂直) 对于大部分数据库的设计和业务的操作基本都与用户的ID相关,因此使用用户ID是最常用的分库的 路由策略。用户的ID可以作为贯穿整个系统用的重要字段。因此,使用用户的ID我们不仅可以方便 我们的查询,还可以将数据平均的分配到不同的数据库中。(当然,还可以根据类别等进行分表操 作,分表的路由策略还有很多方式) 数据库分表能够解决单表数据量很大的时候数据查询的效率问题,但是无法给数据库的并发操作带 来效率上的提高,因为分表的实质还是在一个数据库上进行的操作,很容易受数据库IO性能的限 制。 因此,如何将数据库IO性能的问题平均分配出来,很显然将数据进行分库操作可以很好地解决单台 数据库的性能问题。
分库策略与分表策略的实现很相似,最简单的都是可以通过取模的方式进行路由。
25.redis和memcached比较? 使用redis有哪些好处?  (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,list,set,sorted set,hash (3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行 (4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
redis相比memcached有哪些优势?    (1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 (2) redis的速度比memcached快很多 (3) redis可以持久化其数据
Memcache与Redis的区别都有哪些? 1)、存储方式 Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘 上,这样能保证数据的持久性。 2)、数据支持类型 Memcache对数据类型支持相对简单。 Redis有复杂的数据类型。 3)、使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。 Redis直接自己构建了VM 机 制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
redis与 memcached相比,redis支持key-value数据类型,同时支持list、set、hash等数据结构的存储。 redis支持数据的备份,即master-slave模式的数据备份。 redis支持数据的持久化。 redis在很多方面支持数据库的特性,可以这样说他就是一个数据库系统,而memcached只是简单地K/V缓存。
它们在性能方面差别不是很大,读取方面尤其是针对批量读取性能方面memcached占据优势。当然redis也有他的优 点,如持久性、支持更多的数据结构。 所以在选择方面如果有持久方面的需求或对数据类型和处理有要求的应该选择redis。 如果简单的keyalue 存储应该选择memcached。 26.redis中数据库默认是多少个db 及作用? Redis默认支持16个数据库(可以通过配置文件支持更多,无上限),可以通过配置databases来修改 这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数 据库   Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集 群就没有数据库的概念。
27.python操作redis的模块? 1.基本操作 import redis r = redis.Redis(host = '127.0.0.1', port = 6379) r.set('name', 'beibei') print(r.get('name')) 2.连接池 import redis pool = redis.ConnectionPool(host = '127.0.0.1', port = 6379) r = redis.Redis(connection_pool = pool) r.set('name', 'beibei') print(r.get('name')) 3、管道 import redis pool = redis.ConnectionPool(host = '127.0.0.1', port = 6379) r = redis.Redis(connection_pool = pool) pipe = r.pipeline(transaction = True) r.set('name', 'beibei') print(r.get('name')) 28.如果redis中的某个列表中的数据量非常大,如果实现循环显示每一个值?     通过scan_iter分片取,减少内存压力     scan_iter(match=None, count=None)增量式迭代获取redis里匹配的的值     # match,匹配指定key     # count,每次分片最少获取个数      r = redis.Redis(connection_pool=pool)      for key in r.scan_iter(match='PREFIX_*', count=100000):             print(key)
29.redis如何实现主从复制?以及数据同步机制? https://blog.csdn.net/zhangguanghui002/article/details/78524533 一、Master&Slave是什么?
         也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机 的master/slaver机制,Master以写为主,Slave以读为主。
二、它能干嘛?
       1、读写分离;        2、容灾恢复。
三、怎么玩?
       1、配从(库)不配主(库);        2、从库配置:slaveof [主库IP] [主库端口];            补充:每次slave与master断开后,都需要重新连接,除非你配置进redis.conf文件;             键入info replication 可以查看redis主从信息。 30.redis中的sentinel的作用? 帮助我们自动在主从之间进行切换     检测主从中 主是否挂掉,且超过一半的sentinel检测到挂了之后才进行切换。     如果主修复好了,再次启动时候,会变成从。
    启动主redis:     redis-server /etc/redis-6379.conf  启动主redis     redis-server /etc/redis-6380.conf  启动从redis              在linux中:         找到 /etc/redis-sentinel-8001.conf  配置文件,在内部:             - 哨兵的端口 port = 8001             - 主redis的IP,哨兵个数的一半/1                  找到 /etc/redis-sentinel-8002.conf  配置文件,在内部:             - 哨兵的端口 port = 8002             - 主redis的IP, 1              启动两个哨兵  
31.如何实现redis集群?
32.redis中默认有多少个哈希槽? 16384 33.简述redis的有哪几种持久化策略及比较? RDB:每隔一段时间对redis进行一次持久化。          - 缺点:数据不完整          - 优点:速度快     AOF:把所有命令保存起来,如果想到重新生成到redis,那么就要把命令重新执行一次。          - 缺点:速度慢,文件比较大          - 优点:数据完整
34.列举redis支持的过期策略。
redis 官方提供的 conf
https://raw.github.com/antirez/redis/2.2/redis.conf 中6种过期策略的具体方式。 redis 中的默认的过期策略是volatile-lru 。设置方式     config set maxmemory-policy volatile-lru
maxmemory-policy 六种方式 1.volatile-lru:只对设置了过期时间的key进行LRU(默认值) 2.allkeys-lru : 删除lru算法的key    3.volatile-random:随机删除即将过期key    4.allkeys-random:随机删除    5.volatile-ttl : 删除即将过期的    6.noeviction : 永不过期,返回错误   35.MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中都是热点数据? 相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。
redis 提供 6种数据淘汰策略: voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰 volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰 allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰 allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰 no-enviction(驱逐):禁止驱逐数据 36.写代码,基于redis的列表实现 先进先出、后进先出队列、优先级队列。
37.如何基于redis实现消息队列?
38.如何基于redis实现发布和订阅?以及发布订阅和消息队列的区别? 发布者: import redis
conn = redis.Redis(host='127.0.0.1',port=6379) conn.publish('104.9MH', "hahaha") 订阅者: import redis
conn = redis.Redis(host='127.0.0.1',port=6379) pub = conn.pubsub() pub.subscribe('104.9MH')
while True: msg= pub.parse_response() print(msg)
39.什么是codis及作用?
Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 (不支持的命令列表), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层 会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明 的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务. 40.什么是twemproxy及作用?   是 Twtter 开源的一个 Redis 和 Memcache 代理服务器,主要用于管理 Redis 和 Memcached 集群,减 少与Cache 服务器直接连接的数量。 41.写代码实现redis事务操作。   import redis   pool = redis.ConnectionPool(host='10.211.55.4', port=6379)   conn = redis.Redis(connection_pool=pool)   # pipe = r.pipeline(transaction=False)   pipe = conn.pipeline(transaction=True)   # 开始事务   pipe.multi()   pipe.set('name', 'bendere')   pipe.set('role', 'sb')   # 提交   pipe.execute()
42.redis中的watch的命令的作用? 在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能。假设我们通过WATCH命令在事 务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事 务都将被放弃,同时返回Null multi-bulk应答以通知调用者事务执行失败。      面试题:你如何控制剩余的数量不会出问题?       - 通过redis的watch实现           import redis           conn = redis.Redis(host='127.0.0.1',port=6379)           # conn.set('count',1000)           val = conn.get('count')           print(val)           with conn.pipeline(transaction=True) as pipe:               # 先监视,自己的值没有被修改过               conn.watch('count')               # 事务开始               pipe.multi()               old_count = conn.get('count')               count = int(old_count)               print('现在剩余的商品有:%s',count)               input("问媳妇让不让买?")               pipe.set('count', count - 1)               # 执行,把所有命令一次性推送过去               pipe.execute()
      - 数据库的锁
43.基于redis如何实现商城商品数量计数器? Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也 使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们 要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一 样执行即可: 当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这 样执行: ZRANGE user_scores 0 10 WITHSCORES Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的
44.简述redis分布式锁和redlock的实现机制。
45.什么是一致性哈希?Python中是否有相应模块? Python模块--hash_ring,即Python中的一致性hash https://blog.csdn.net/fjslovejhl/article/details/40831925 46.如何高效的找到redis中所有以oldboy开头的key?   redis 有一个keys命令。   语法:KEYS pattern   说明:返回与指定模式相匹配的所用的keys。   该命令所支持的匹配模式如下:   (1)?:用于匹配单个字符。例如,h?llo可以匹配hello、hallo和hxllo等;   (2)*:用于匹配零个或者多个字符。例如,h*llo可以匹配hllo和heeeello等;   (3)[]:可以用来指定模式的选择区间。例如h[ae]llo可以匹配hello和hallo,但是不能匹配hillo。   同时,可以使用“/”符号来转义特殊的字符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值