代码编织梦想

MySQL中myisam与innodb的区别

MyISAM:

  • 不支持事务,但是每次查询都是原子的;
  • 支持表级锁,即每次操作对整个表加锁;
  • 存储表的总行数;
  • 一个MYISAM表有三个文件:索引文件、表结构文件、数据文件;
  • 采用非聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性。

InnoDb:

  • 支持ACID的事务,支持事务的四种隔离级别;
  • 支持行级锁及外键约束:因此可以支持写并发;
  • 不存储总行数;
  • 一个InnoDb引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多个文件里),也有可能为多个(设置为独立表空,表大小受操作系统文件大小限制,一般为2G),受操作系统文件大小的限制;
  • 主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅索引查找数据,需要先通过辅索引找到主键值,再访问辅索引;最好使用自增主键,防止插入数据时,为维持B+树结构,文件的大调整。

两者的适用场景:

因为MyISAM相对简单所以在效率上要优于InnoDB。如果系统读多,写少,对原子性要求低,那么MyISAM最好的选择,且MyISAM恢复速度快,可直接用备份覆盖恢复。
如果系统读少,写多的时候,尤其是并发写入高的时候。InnoDB就是首选了。

myisam与innodb引擎下select count(*)哪个更快,为什么?

统计一张表的总数量,是我们开发中常有的业务需求,通常情况下,我们都是使用 select count(*) from t SQL 语句来完成。随着业务数据的增加,你会发现这条语句执行的速度越来越慢,为什么它会变慢呢?

为什么会变慢?想要得到答案就需要知道 MySQL 是如何统计总数量的,先说一个前提吧,count(*) 的具体实现是由存储引擎实现的,也就是说不同的存储引擎实现的方式不一样。

InnoDB和MyISAM 是我们常用的 MySQL 存储引擎,所以主要对比一下 count(*) 在 InnoDB 和 MyISAM 中的实现:

  • 在 MyISAM 存储引擎中,把表的总行数存储在磁盘上,当执行 select count(*) from t 时,直接返回总数据。
  • 在 InnoDB 存储引擎中,跟 MyISAM 不一样,没有将总行数存储在磁盘上,当执行 select count(*) from t 时,会先把数据读出来,一行一行的累加,最后返回总数量。

知道了 InnoDB 和 MyISAM 引擎 count(*) 实现之后,为什么 select count(*) from t,在 InnoDB 引擎中比 MyISAM 慢?应该有答案了吧,但是这个结论需要有一个前提,就是统计 SQL 不带过滤条件。如果统计数量SQL语句为:select count(*) from t where x = 23,那么在 MyISAM 中就不一定比 InnoDB 快了。

InnoDB 中 count(*) 语句是在执行的时候,全表扫描统计总数量,所以当数据越来越大时,语句就越来越耗时了,为什么 InnoDB 引擎不像 MyISAM 引擎一样,将总行数存储到磁盘上?这跟 InnoDB 的事务特性有关,由于多版本并发控制(MVCC)的原因,InnoDB 表“应该返回多少行”也是不确定的。

不妨用一个例子来说明一下,假设现在 t 表中有 10000 条数据,现在有三个用户同时访问的会话:

  • 会话 A 先启动事务并查询一次表的总行数。
  • 会话 B 启动事务,插入一行后记录后,查询表的总行数。
  • 会话 C 先启动一个单独的语句,插入一行记录后,查询表的总行数。

InnoDB 引擎在 count(*)语句上也做了优化,我们知道,在 InnoDB 存储引擎中是以索引组织表的方式存储数据,主键索引树上的叶子节点存放着所在行的所有的数据,而普通索引树的叶子节点是主键值,所以普通索引树会比主键索引树小很多,但是数量是一样的,也就是说遍历主键索引树和普通索引树得到的结果都是一样的。MySQL 就利用了这一特性,在 InnoDB 中执行 select count(*) from t 语句时,MySQL 优化器会找到最小的那棵索引树来遍历,这样可能就可以减少加载次数,在一定程度上提升了 count(*)的执行效率。

MySQL INT和CHAR隐式类型转换需要注意什么?

主要记住下面两点:

① 当查询字段是INT类型,如果查询条件为CHAR,将查询条件转换为INT,如果是字符串并且前导都是数字,将截取前导数字用来比较,如果没有前导数字,则转换为0。

② 当查询字段是CHAR/VARCHAR类型,如果查询条件为INT,将查询字段转换为INT再进行比较,可能会造成全表扫描。

有如下一张测试表product,id为int类型,name为varchar类型。

+----+----------+
| id | name   |
+----+----------+
|  1 | apple   |
|  2 | banana |
|  3 | 99cat   |
+----+----------+

情况1:

// 查询条件转化为数字1再比较
mysql> select * from product where id = '1abc23';
+----+---------+
| id | name  |
+----+---------+
|  1 | apple  |
+----+---------+

情况2:

// 查询字段全部转化成数字,id:1和id:2字段值转化为0,id:3转化成99,再比较
mysql> select * from product where name=0;
+----+----------+
| id | name   |
+----+----------+
|  1 | apple   |
|  2 | banana |
+----+----------+

MySQL 如何高效率随机获取N条数据?

假设表叫做mm_account。

ID连续的情况下(注意不能带where,否则结果不好):

SELECT *
FROM `mm_account` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `mm_account`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id ASC LIMIT 4;

ID不连续的情况下:

SELECT * FROM `mm_account` 
WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `mm_account`)))  and city="city_91" and showSex=1
ORDER BY id LIMIT 4;

如果有一个字段叫id,最快的方法如下(随机获取5条):

SELECT * FROM mm_account 
WHERE id >= ((SELECT MAX(id) FROM mm_account)-(SELECT MIN(id) FROM mm_account)) * RAND() + (SELECT MIN(id) FROM mm_account)
limit 5;

如果带where语句,上面就不适合了,带where语句请看下面:

SELECT *
FROM `mm_account` AS t1 JOIN (SELECT ROUND(RAND() * (
(SELECT MAX(id) FROM `mm_account` where id<1000 )-(SELECT MIN(id) FROM `mm_account` where id<1000 ))+(SELECT MIN(id) FROM `mm_account` where id<1000 )) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id LIMIT 5;

说说你知道的MySQL的索引类型,并分别简述一下各自的场景?

普通索引:没有任何限制条件的索引,该索引可以在任何数据类型中创建。

唯一索引:使用UNIQUE参数可以设置唯一索引。创建该索引时,索引列的值必须唯一,但允许有空值。通过唯一索引,用户可以快速地定位某条记录,主键索引是一种特殊的唯一索引。

全文索引:仅可用于 MyISAM 表,针对较大的数据,生成全文索引耗时耗空间。

空间索引:只能建立在空间数据类型上。这样可以提高系统获取空间数据类型的效率。仅可用于 MyISAM 表,索引的字段不能为空值。使用SPATIAL参数可以设置索引为空间索引。

单列索引:只对应一个字段的索引。

多列索引:在表的多个字段上创建一个索引。该索引指向创建时对应的多个字段,用户可以通过这几个字段进行查询,想使用该索引,用户必须使用这些字段中的一个字段。

面试需要掌握那些技能?

1. Java基础知识:包括面向对象编程、集合框架、多线程编程、JVM、测试和调试技术等。

2. 熟悉Spring框架:包括Spring MVC、Spring Boot、Spring Cloud等。

3. 掌握常见的数据库操作技术:如SQL语句、关系型数据库和非关系型数据库等。

4. 熟练使用版本控制工具:如Git等。

5. 对Web开发有一定的了解,熟悉前端相关技术:如HTML、CSS、JavaScript等。

6. 能够写高效的算法,并对数据结构有一定的了解。

7. 有良好的代码习惯,能够编写易于维护和扩展的代码,并理解单元测试和集成测试等概念。

8. 在面试过程中,还需要表达清晰、思路清晰明了、能够准确地回答面试官提出的问题,此外,自信、积极和礼貌也是很重要的。


大厂面试官常问的技术核心知识点

1. Java基础知识:Java语言的基本知识,包括数据类型、继承、多态、接口等。


2. 面向对象编程:对面向对象编程原则和设计模式的理解,如单例、工厂、观察者、策略等。


3. 数据库知识:对关系型数据库和非关系型数据库操作的熟悉程度,掌握SQL语言,了解事务管理机制,并清楚地描述ORM框架的使用场景及实际操作。


4. Web开发:Web开发相关技术,例如Servlet、JSP、Spring MVC、JSON、RESTful API等。熟悉HTTP/HTTPS协议以及网络通信机制。


5. 常用框架:Spring、Hibernate、MyBatis等框架,尤其是Spring框架,深入理解Spring IOC,AOP等核心原理,知道如何配置基础设施组件,如事务管理、缓存等基础组件。


6. 分布式系统架构:分布式系统相关技术,如Dubbo、Zookeeper等,对微服务架构模式有一定的了解,熟悉分布式锁、分布式缓存、分布式数据存储等高可用性方案。


7. 性能排查:了解性能优化的方法,包括代码和SQL调优等,并且熟悉性能监测和分析工具,例如掌握JVM内存结构及堆栈排查技术。


8. 算法和数据结构:有基本的算法和数据结构知识,例如排序、查找、哈希表等。


我最近整理了一些小伙伴们发给我的面试题以及我的一些最新的面试等学习资料,有需要的小伙伴可以找我领取下。或者点击《最新Java后端全套VIP面试学习资源》直接获取以下Java后端架构VIP进阶学习面试资料。

资料里面包含了:Java基础、MySQL、jvm、分布式、性能优化、spring 、spring boot、spring cloud、 MyBatis、Netty源码分析、算法、乙级高并发、Redis、dubbo、Tomcat、集合框架、锁、MQ、百万简历模板等等学习视频资料。

资料如图展示:(知识其中一部分)

同时也欢迎大家关注公众号【Java烂猪皮】,回复【666】,获取最新Java后端架构VIP学习资料以及视频学习教程,然后一起学习,一文在手,面试我有。

 看完三件事❤️

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注作者公众号 『 java烂猪皮 』,不定期分享原创知识。
  • 关注后回复【666】扫码即可获取学习资料包。
  • 同时可以期待后续文章ing🚀。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pisa8559/article/details/130868725

Redis(八):zset/zadd/zrange/zrembyscore 命令源码解析-爱代码爱编程

前面几篇文章,我们完全领略了redis的string,hash,list,set数据类型的实现方法,相信对redis已经不再神秘。   本篇我们将介绍redis的最后一种数据类型: zset 的相关实现。   本篇过后,我们对redis的各种基础功能,应该不会再有疑惑。有可能的话,我们后续将会对redis的高级功能的实现做解析。(如复制、哨兵模式、集群