(一)MySQL基础考点1.事务的原理、特点及并发控制什么是事务(Transaction)?事务是数据库并发控制的基本单位。一个事务可以看作是一组SQL语句的集合。事务必须成功执行或执行失败(回滚)。事务的常见场景是:银行转账操作的ACID特征。原子性(Atomicity:一个事务中的所有操作都完成或失败。一致性:数据完整性在事务开始和结束后不被破坏。隔离性:允许多个事务同时修改和读写数据库。持久性(Durability)):交易结束后,修改永久生效,不会丢失。事务并发控制可能会出现什么问题?幻读:第二次检查交易的结果是第一次没有找到。不可重复读:一个事务读取两次,得到不同的结果。脏读:一个事务读取了另一个事务未提交的修改。Lostmodification:并发写入Input导致部分修改丢失解决并发异常,定义4个事务隔离级别都是一样的(mysqlinnoDB默认实现了可重复读级别)序列化:事务完全序列化,隔离级别最高,效率最低唯一索引使用队列异步写入,使用redis实现分布式锁。乐观锁和悲观锁。悲观锁:先获取锁再操作。一次锁,两次检查,三次更新selectforupdate乐观锁:先修改,发现数据有变化再回滚(checkandset)使用需要根据响应速度,冲突频率,判断使用哪个重试成本2.普通字段的含义和区别文本类型CHARVARCHARTINYTEXTTEXT数值类型TINYINTSMALLINTSIGINTFLOATDOUBLE日期时间DATEDATETIMETIMESTAMP(4字节,但接受的时间在1970-2038之间)3.普通数据库引擎的区别(InnoDBVSMyISAM)MyISAMDoes不支持事务,InnoDB支持事务MyISAM不支持外键,InnoDB支持外键MyISAM只支持表锁,InnoDB支持行锁和表锁MyISAM支持全文索引,InnoDB不支持(二)Mysql索引原理及优化常见试题1.索引的原理、类型和结构什么是索引?对数据表中的一个或多个列进行排序的数据结构索引可以大大提高索引速度。创建和更新索引本身也会消耗空间和时间。什么是B树?(搜索结构演变史)多路平衡搜索树B+TreeMysql其实是用B+Tree作为索引的数据结构UniqueCREATEUNIQUEINDEX多列索引(联合索引)主键索引一个表只能有一个PRIMARYInnoDB不支持KEY全文索引(一般由专门的全文索引数据库实现)什么时候创建索引?(建表时需要根据查询要求创建索引)经常作为查询条件(WHERE条件)的字段经常作为表连接的字段经常出现在orderby,groupby之后应该支付什么创建索引时要注意什么?(最佳实践)非空字段NOTNULL,Mysql很难针对空值优化查询。辨别力高,分散度大。索引字段值尽量不要有大量相同的值。索引的长度不要太大(比较耗时-索引作为B+Tree的key值存在,字符串key太长耗时)索引什么时候失效?内存公式:模型匹配,类型隐式转换,最左匹配以%开头的LIKE语句,模糊搜索中的隐式转换(注意python等动态语言查询)不满足最左前缀原则(对于联合索引)什么聚合索引和非-聚簇索引是指B+Tree叶子节点的存储针还是数据记录MyISAM索引和数据分离,使用非聚集索引(存储数据指针)。InnoDB数据文件就是索引文件,主键索引就是聚集索引。3、如何排查和排除慢查询慢查询通常是缺少索引,索引不合理或者业务代码实现导致开启slow_query_log_file,查询慢查询日志使用explain命令排查索引问题,调整数据修改索引;业务代码层限制不合理的访问(比如一次获取的数据过多——实现分页;数据类型不匹配导致全文扫描)(三)SQL语句编写常见问题1、常用的join主要集中在innerjoin(INNERJOIN):只有当两个表之间存在匹配时,匹配的行外连接(LEFT/RIGHTJOIN):返回一个表行,即使对方不匹配全连接(FULLJOIN):只要有匹配某张表,返回(4)非关系型数据库Redis1。缓存(内存缓存)的使用场景为什么要使用缓存?缓解关系型数据(常见Mysql)的并发访问压力:减少热点数据的响应时间:内存IO速度快于磁盘提高吞吐量:Redis等内存数据库可以单机支持大量并发。Redis和Memcached的主要区别是什么?数据存储类型:redis支持string/List/hash/set/sortset;memcached只支持text/binary类型的网络IO模型:redis单进程模式;memcached多线程、非阻塞IO模式持久化支持:redis支持两种RDB、DOF;memcached不支持2、Redis的常见数据类型和使用场景?数据类型String(字符串):用于实现简单的KV键值对存储,如计数器List(链表):实现双向链表,如用户关注、粉丝列表Hash(哈希表):用于存储相互关联的信息Key-valuepairs集合(collection):存储不重复的元素,比如用户的followers排序集(orderedset):实时信息排名支持两种方式实现持久化快照:放树快照在磁盘二进制文件中,dump.rdbAOF:每个写命令都附加到appendonly.aof,哪些redis事务可以通过Redis配置修改?一种将多个请求打包,一次依次执行多个命令的机制。通过MULTI、EXEC、WATCH等命令实现事务功能。如何实现分布式锁?使用setnx实现加锁,同时可以通过expire加超时锁当value值可以使用随机uuid或者特定名字来释放锁时,使用uuid判断是否是锁,如果是则执行delete释放锁。3.缓存使用的坑使用缓存模式?CacheAside:同时更新缓存和数据库。Read/WriteThrough:先更新缓存,缓存负责同步更新数据库。WriteBehindCaching:先更新缓存,缓存定时异步更新数据库。如何解决缓存穿透问题?原因:由于大量缓存找不到,去数据库取,数据库没有数据可以查。解决方法:找不到返回None的数据也缓存起来;插入数据时,删除相应的缓存,或者设置更短的超时时间。如何解决缓存崩溃问题?原因:一些非常热的数据key过期,大量请求到达后端数据库。解决方案:分布式锁——获取锁的线程从数据库中拉取数据更新缓存,其他线程等待后台异步更新——如何解决后台任务针对过期键自动刷新缓存雪崩问题?原因:缓存不可用或大量缓存键同时失效,大量请求直接到达数据库。解决方案:多级缓存--不同级别的key不同超时时间Randomtimeout--随机设置key的超时时间,防止同时超时-提高系统可用性,监控和告警改进(五)Mysql和Redis练习题1.Mysql思考题为什么Mysql数据库的主键使用自增整数比较好?uuid可以吗?在最佳实践中,auto_increment字段的长度小于uuid,这在性能和可读性方面优于uuid。如果是分布式系统,我们如何生成数据库的自增id呢?在auto_increment的基础上,设置step增长step;例如:Master1生成1、4、7、10,Master2生成2、5、8、11,Master3生成3、6、9、12。可以有效生成集群内唯一ID,也可以大大减少ID生成数据库操作的负载。2、Redis应用——分布式锁写一个简单的分布式锁,需要支持超时参数=6379,password="",db=1)self._lock=0self.timeout=timeoutself.lock_key="%s_dynamic_test"%key@staticmethoddefget_lock(cls):whilecls._lock!=1:timestamp=time.time()+self.timeout+1cls._lock=cls.rdcon.setnx(cls.lock_key,timestamp) #注意下面括号的范围ifcls._lock==1or(time.time()>cls.rdcon.get(cls.lock_key)andtime.time()>cls.rdcon.getset(cls.lock_key,timestamp)):print"getlock"breakelse:time.sleep(0.3)@staticmethod复制代码defrelease(cls):iftime.time()
