Python面试题——Part Ⅲ 数据库和缓存(46题)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010525694/article/details/82380791

1.列举常见的关系型数据库和非关系型都有那些?

关系型数据库:
Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL
非关系型数据库:
NoSql、Cloudant、MongoDb、redis、HBase

2.MySQL常见数据库引擎及比较?

InnoDB: 支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)。
 
MyISAM: 插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比 较低,也可以使用。
 
MEMORY: 所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择MEMOEY。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表。

3.简述数据三大范式?

第一范式就是指表中的所有字段都是原子的、不可再分的。将第零范式中重复的字段抽取出来,作为表的数据,从而形成一个稳定的、冗余数据少得表结构。
第二范式是满足非主属性完全依赖于主属性。因此,满足第二范式的表当然也是满足第一范式的,第二范式的目的就是消除表中的部分依赖。
第三范式是指在满足第二范式的情况下,属性不依赖于其它非主属性 , 消除传递依赖
所谓传递依赖,就是指x–>y,y–>z,那么可以得到x–>z.传递依赖常发生在主键、外键、外键相关的属性上。

4.什么是事务?MySQL如何支持事务?

原子性:要么完全提交(10233276的checking余额减少200,savings 的余额增加200),要么完全回滚(两个表的余额都不发生变化)
一致性:这个例子的一致性体现在 200元不会因为数据库系统运行到第3行之后,第4行之前时崩溃而不翼而飞,因为事务还没有提交。
隔离性:允许在一个事务中的操作语句会与其他事务的语句隔离开,比如事务A运行到第3行之后,第4行之前,此时事务B去查询checking余额时,它仍然能够看到在事务A中被减去的200元(账户钱不变),因为事务A和B是彼此隔离的。在事务A提交之前,事务B观察不到数据的改变。
持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中。
 
MySQL要使用InnoDB引擎才能支持事务操作:
START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMMIT = {0 | 1}

START TRANSACTION 或 BEGIN 语句:开始一项新的事务。
COMMIT 和 ROLLBACK:用来提交或者回滚事务。
CHAIN 和 RELEASE 子句:分别用来定义在事务提交或者回滚之后的操作,CHAIN 会立即启动一个新事务,并且和刚才的事务具有相同的隔离级别,RELEASE 则会断开和客户端的连接。
SET AUTOCOMMIT 可以修改当前连接的提交方式, 如果设置了 SET AUTOCOMMIT=0,则设置之后的所有事务都需要通过明确的命令进行提交或者回滚

5.简述数据库设计中一对多和多对多的应用场景?

一对一: 比如文章的meta信息(分类、标签、摘要、发布日期等)和文章正文内容;
多对多: 文章和标签

6.如何基于数据库实现商城商品计数器?

方式一: 单独维护一个商品数量表
方式二: 在商品表中用多行来记录商品数量
https://blog.csdn.net/liuxinmingcode/article/details/43964307

7.常见SQL(必备)
详见武沛齐博客:https://www.cnblogs.com/wupeiqi/articles/5729934.html

8.简述触发器、函数、视图、存储过程?

1、视图
视图只是一种逻辑对象,是一种虚拟表,它并不是物理对象,因为视图不占物理存储空间,在视图中被查询的表称为视图的基表,大多数的select语句都可以用在创建视图中(说白了,视图就是一种虚拟表,就像是一张电子照片)
优点:集中用户使用的数据,掩码数据的复杂性,简化权限管理以及为向其他应用程序输出而重新组织数据等
2、触发器
(1)触发器是一个特殊的存储过程,它是MySQL在insert、update、delete的时候自动执行的代码块。
(2)触发器必须定义在特定的表上。
(3)自动执行,不能直接调用,
3、函数
它跟php或js中的函数几乎一样:需要先定义,然后调用(使用)。
只是规定,这个函数,必须要返回数据——要有返回值
4、存储过程
存储过程(procedure),概念类似于函数,就是把一段代码封装起来,当要执行这一段代码的时候,可以通过调用该存储过程来实现。在封装的语句体里面,可以同if/else ,case,while等控制结构,可以进行sql编程,查看现有的存储过程。

9.MySQL索引种类

从逻辑角度
普通索引INDEX:加速查找
唯一索引:
-主键索引PRIMARY KEY:加速查找+约束(不为空、不能重复)
-唯一索引UNIQUE:加速查找+约束(不能重复)
联合索引:
-PRIMARY KEY(id,name):联合主键索引
-UNIQUE(id,name):联合唯一索引
-INDEX(id,name):联合普通索引
 
从数据结构角度
1、B+树索引(O(log(n))):关于B+树索引,可以参考 MySQL索引背后的数据结构及算法原理
2、hash索引:
a 仅仅能满足”=”,”IN”和”<=>”查询,不能使用范围查询
b 其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引
c 只有Memory存储引擎显示支持hash索引
3、FULLTEXT索引(现在MyISAM和InnoDB引擎都支持了)
4、R-Tree索引(用于对GIS数据类型创建SPATIAL索引)

10.索引在什么情况下遵循最左前缀的规则?

对于组合索引mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。索引index1:(a,b,c),只会走a、a,b、a,b,c 三种类型的查询,其实这里说的有一点问题,a,c也走,但是只走a字段索引,不会走c字段。
 
select * from table where a = ‘1’ and b > ‘2’ and c=’3’ 这种类型的也只会有a与b走索引,c不会走。
像select * from table where a = ‘1’ and b > ‘2’ and c=’3’ 这种类型的sql语句,在a、b走完索引后,c肯定是无序了,所以c就没法走索引

11.主键和外键的区别?

主键是能确定一条记录的唯一标识,比如,一条记录包括身份正号,姓名,年龄。身份证号是唯一能确定你这个人的,其他都可能有重复,所以,身份证号是主键。
外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。

12.MySQL常见的函数?

2008-10-16 10:33:44
一、数学函数
ABS(x) 返回x的绝对值
BIN(x)          返回x的二进制(OCT返回八进制,HEX返回十六进制)
CEILING(x) 返回大于x的最小整数值
EXP(x)          返回值e(自然对数的底)的x次方
FLOOR(x)         返回小于x的最大整数值
GREATEST(x1,x2,…,xn)  返回集合中最大的值
LEAST(x1,x2,…,xn) 返回集合中最小的值
LN(x) 返回x的自然对数
LOG(x,y)         返回x的以y为底的对数
MOD(x,y) 返回x/y的模(余数)
PI()           返回pi的值(圆周率)
RAND()          返回0到1内的随机值,可以通过提供一个参数(种子)使RAND()随机数生成器生成一个指定的值。
ROUND(x,y)        返回参数x的四舍五入的有y位小数的值
SIGN(x)          返回代表数字x的符号的值
SQRT(x)          返回一个数的平方根
TRUNCATE(x,y) 返回数字x截短为y位小数的结果
二、聚合函数(常用于GROUP BY从句的SELECT查询中)
AVG(col)         返回指定列的平均值
COUNT(col)        返回指定列中非NULL值的个数
MIN(col)         返回指定列的最小值
MAX(col)         返回指定列的最大值
SUM(col)         返回指定列的所有值之和
GROUP_CONCAT(col)     返回由属于一组的列值连接组合而成的结果
三、字符串函数
ASCII(char)        返回字符的ASCII码值
BIT_LENGTH(str)      返回字符串的比特长度
CONCAT(s1,s2…,sn)    将s1,s2…,sn连接成字符串
CONCAT_WS(sep,s1,s2…,sn)  将s1,s2…,sn连接成字符串,并用sep字符间隔
INSERT(str,x,y,instr)    将字符串str从第x位置开始,y个字符长的子串替换为字符串instr,返回结果
FIND_IN_SET(str,list)   分析逗号分隔的list列表,如果发现str,返回str在list中的位置
LCASE(str)或LOWER(str)   返回将字符串str中所有字符改变为小写后的结果
LEFT(str,x)        返回字符串str中最左边的x个字符
LENGTH(s)         返回字符串str中的字符数
LTRIM(str)         从字符串str中切掉开头的空格
POSITION(substr,str)    返回子串substr在字符串str中第一次出现的位置
QUOTE(str)         用反斜杠转义str中的单引号
REPEAT(str,srchstr,rplcstr)返回字符串str重复x次的结果
REVERSE(str)        返回颠倒字符串str的结果
RIGHT(str,x)        返回字符串str中最右边的x个字符
RTRIM(str)         返回字符串str尾部的空格
STRCMP(s1,s2)       比较字符串s1和s2
TRIM(str)         去除字符串首部和尾部的所有空格
UCASE(str)或UPPER(str)   返回将字符串str中所有字符转变为大写后的结果
四、日期和时间函数
CURDATE()或CURRENT_DATE() 返回当前的日期
CURTIME()或CURRENT_TIME() 返回当前的时间
DATE_ADD(date,INTERVAL int keyword) 返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:SELECT DATE_ADD(CURRENT_DATE,INTERVAL 6 MONTH);
DATE_FORMAT(date,fmt) 依照指定的fmt格式格式化日期date值
DATE_SUB(date,INTERVAL int keyword) 返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:SELECT DATE_SUB(CURRENT_DATE,INTERVAL 6 MONTH);
DAYOFWEEK(date) 返回date所代表的一星期中的第几天(1~7)
DAYOFMONTH(date) 返回date是一个月的第几天(1~31)
DAYOFYEAR(date) 返回date是一年的第几天(1~366)
DAYNAME(date) 返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE);
FROM_UNIXTIME(ts,fmt) 根据指定的fmt格式,格式化UNIX时间戳ts
HOUR(time) 返回time的小时值(0~23)
MINUTE(time) 返回time的分钟值(0~59)
MONTH(date) 返回date的月份值(1~12)
MONTHNAME(date) 返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE);
NOW() 返回当前的日期和时间
QUARTER(date) 返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE);
WEEK(date) 返回日期date为一年中第几周(0~53)
YEAR(date) 返回日期date的年份(1000~9999)

13.列举 创建索引但是无法命中索引的8种情况。

1、如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
2、对于多列索引,不是使用的第一部分(第一个),则不会使用索引
3、like查询是以%开头
4、如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
5、如果mysql估计使用全表扫描要比使用索引快,则不使用索引
其他:
这里写图片描述

14.如何开启慢日志查询?

方法一:全局变量设置
将 slow_query_log 全局变量设置为“ON”状态
mysql> set global slow_query_log=’ON’;
设置慢查询日志存放的位置
mysql> set global slow_query_log_file=’/usr/local/mysql/data/slow.log’;
 
方法二:配置文件设置
修改配置文件my.cnf,在[mysqld]下的下方加入
[mysqld]
slow_query_log = ON
slow_query_log_file = /usr/local/mysql/data/slow.log
long_query_time = 1

15.数据库导入导出命令(结构+数据)?

导出数据和表结构:
mysqldump -u 用户名 -p 数据库名 > 数据库名.sql
 
只导出表结构
mysqldump -u 用户名 -p -d 数据库名 > 数据库名.sql
 
导入数据库,需要首先建空数据库
mysql>create database abc;
mysql -u 用户名 -p 数据库名 < 数据库名.sql
https://blog.csdn.net/u010525694/article/details/82219751

16.数据库优化方案?

  • 硬件优化
  • 定位慢SQL,并优化
  • 合理使用索引
  • 分表 水平分割(按行)、垂直分割(按列)
  • 读写分离 使用负载均衡实现,写操作都往主库上写,读操作往从服务器上读
  • 缓存 短时间内相同数据重复查询多次且数据更新不频繁
    https://blog.csdn.net/u013628152/article/details/82184809

17.char和varchar的区别?

char(10):简单粗暴,浪费空间,存取速度快 root存成root000000
varchar:精准,节省空间,存取速度慢
sql优化:创建表时,定长的类型往前放,变长的往后放

18.简述MySQL的执行计划?

MySQL数据库中,在SELECT查询语句前边加上“EXPLAIN”或者“DESC”关键字,即可查看该查询语句的执行计划,分析执行计划是优化慢查询的重要手段。

19.在对name做了唯一索引前提下,简述以下区别:


     select * from tb where name = ‘Oldboy-Wupeiqi’ 

     select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1

当只有一行数据时使用 LIMIT 1,在这种情况下,加上 LIMIT 1 可以增加性能。这样一样,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。

19.1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?

因为页数越大,mysql要扫描的行数越多
解决: 提供线索
如果 LIMIT m,n 不可避免的话,要优化效率,只有尽可能的让m小一下,我们扩展前面的”clue”做法,还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是9527,最小的是9500,比如要跳到第8页,
SQL语句可以这 样写:
SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20,20;
跳转到第13页:
SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 40,20;
原理还是一样,记录住当前页id的最大值和最小值,计算跳转页面和当前页相对偏移,由于页面相近,这个偏移量不会很大,这样的话m值相对较小,大大 减少扫描的行数。其实传统的limit m,n,相对的偏移一直是第一页,这样的话越翻到后面,效率越差,而上面给出的方法就没有这样的问题。
https://blog.csdn.net/helloxiaozhe/article/details/78106709

20.什么是索引合并?

对多个索引分别进行条件扫描,然后将它们各自的结果进行合并(intersect/union)。

21.什么是覆盖索引?

辅助索引中就可以得到查询记录,而不需要查询聚集索引中的记录。通常需要建立联合索引。
使用覆盖索引的一个好处是:辅助索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作

22.简述数据库读写分离?

MySQL Proxy最强大的一项功能是实现“读写分离(Read/Write Splitting)”。基本的原理是让主数据库处理事务性查询,而从数据库处理SELECT查询。数据库复制被用来把事务性查询导致的变更同步到集群中的从数据库。 当然,主服务器也可以提供查询服务。使用读写分离最大的作用无非是缓解服务器压力。

23.简述数据库分库分表?(水平、垂直)

垂直切分可以使模块的划分更清晰,分成功能不同的表;水平切分可以解决大数据下大表性能的瓶颈问题。

24.redis和memcached比较?
>

25.redis中数据库默认是多少个db 及作用?
>

26.python操作redis的模块?

27.如果redis中的某个列表中的数据量非常大,如果实现循环显示每一个值?

28.redis如何实现主从复制?以及数据同步机制?

29.redis中的sentinel的作用?

30.如何实现redis集群?

31.redis中默认有多少个哈希槽?

32.简述redis的有哪几种持久化策略及比较?

33.列举redis支持的过期策略。

34.MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中都是热点数据?

35.写代码,基于redis的列表实现 先进先出、后进先出队列、优先级队列。

36.如何基于redis实现消息队列?

37.如何基于redis实现发布和订阅?以及发布订阅和消息队列的区别?

38.什么是codis及作用?

39.什么是twemproxy及作用?

40.写代码实现redis事务操作。

41.redis中的watch的命令的作用?

42.基于redis如何实现商城商品数量计数器?

43.简述redis分布式锁和redlock的实现机制。

44.什么是一致性哈希?Python中是否有相应模块?

45.如何高效的找到redis中所有以oldboy开头的key?

猜你喜欢

转载自blog.csdn.net/u010525694/article/details/82380791