首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >常见面试题(笔试题)系列

常见面试题(笔试题)系列

作者头像
用户8568307
发布2022-03-14 14:55:03
发布2022-03-14 14:55:03
6420
举报
文章被收录于专栏:PHP全栈技术PHP全栈技术

MYSQL的Innodb和Myisam引擎的区别

  1. 事务,Innodb是支持事务的,而Myisam不支持。这是MYSQL将默认存储引擎从Myisam改成Innodb的重要原因之一。
  2. 锁的粒度,Innodb最小的锁粒度是行锁,Myisam最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新全部被阻塞,因此并发受限。这也是MYSQL将默认存储引擎从Myisam变成Innodb的重要原因之一。
  3. 读写:Innodb擅长更新频繁的操作,而Myisam擅长查询频繁操作。Innodb不保存表的行数,执行select count(*) from table 时需要扫描全表。而Myisam用一个变量保存了整张表的行数,执行上述语句只需要读出该变量即可,速度很快。
  4. 外键:Innodb支持外键,而Myisam不支持。对一个包含外键的Innodb表转为Myisam会失败。
  5. 聚簇索引:Innodb拥有聚簇索引,Myisam没有聚簇索引。关于聚簇索引详情见下。

关于Innodb和Myisam的聚簇索引问题

首先索引总共分为两大类:

  1. 聚簇索引(聚集索引)
  2. 辅助索引(非聚簇索引,二级索引)
  • 聚簇索引的叶子节点是存储了完整的行数据,所以通过主键查找的行记录速度是最快的,只需要查一次索引树。
  • 辅助索引的叶子节点并没有存储完整的行数据,需要先通过辅助索引的叶子节点得到主键值,然后在拿这个主键值去聚簇索引中查找对应的行记录,这里总共查找了两次,也被称为‘回表’,如何避免呢?可以使用索引覆盖,详情见下。
问题又来了,为什么Myisam既然没有聚簇索引查询速度也会比Innodb高呢 ?

Innodb在做select的时候,要维护的东西比Myisam引擎多得多。

  1. Innodb的聚簇索引的叶子节点存储的是数据文件(行记录),辅助索引存储了主键值。而Myisam是非聚簇索引,他的数据文件都是分离的,索引的叶子节点都是存储的数据文件的地址指针。假如都用的辅助索引,Innodb的辅助索引需要查找两遍树,而Myisam的索引只需要查询一遍树
  2. Innodb还需要维护MVCC一致;虽然可能你的场景没有,但是他还是需要去检查和维护,MVCC (Multi-Version Concurrency Control)多版本并发控制
聚簇索引一定是主键吗?

聚簇索引不一定是主键,但是主键一定是聚簇索引。

不建立主键的话是否就没有聚簇索引?

一个表可能没有主键,但是一定会有聚簇索引。因为如果没有定义主键,Innodb就会取第一个非空的唯一索引代替。如果没有这样的索引,Innodb会隐式创建一个内置的rowid作为聚簇索引。

如何避免‘回表’,什么是索引覆盖?

  • 回表,其实就是上面说到的,先定位到主键值,在定位到行记录,它的性能较扫一遍的索引树更低,这就叫做'回表'
  • 如何避免呢,可以使用索引覆盖。什么是索引覆盖? 索引覆盖就是select的数据只用从索引中就能够取到,不需要去读取一行数据。
  1. 示例1
代码语言:javascript
复制
主键是id,age是索引,name是普通字段

select *from table where age = 1;

这个就会回表,因为这里查询的是一整行的数据,而通过age索引只能查到age和主键id,所以Innodb又会通过主键id去聚簇索引上找一行的数据,这里就查了两次索引树。

代码语言:javascript
复制
优化:
select id,age from table where age = 1;
  1. 示例2
代码语言:javascript
复制
select id,age,name from table where age = 1;

这里也是会回表的,因为age索引树上找不到name,所以又会通过主键id去聚簇索引找到name值。

代码语言:javascript
复制
优化:
建立复合索引:age_name

说说PHP的垃圾回收机制

php变量存在一个叫zval容器变量中。它的结构分为四部分:类型,值,is_ref和refcount。

  • is_ref,是一个bool值,用来标志这个变量是否属于一个引用集合(其实就是如果用到了引用操作符),通过这个字节,php引擎才能把普通变量和引用变量区分开来。
  • refcount,表示指向这个zval变量容器的变量的个数。

当refcount等于0,也就是没有变量指向这个变量容器zval时,该变量的内存空间将被释放。

session和cookie的区别与联系

区别
  1. 保存的位置:cookie保存在客户端,而session保存在服务端。
  2. 安全性:cookie不是很安全,别人可以分析放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
  3. 保存的数据大小:单个cookie保存的数据不能超过4K,很多浏览器都限制了一个站点最多保存20个cookie。而session是没有大小限制的
联系

session是依靠cookie的,sessionId就保存在cookie中,用户提交表单时,浏览器会默认的将cookie也带上,会将cookie里面的sessionId自动附在HTTP头信息中(这是浏览器自带的功能,用户不会察觉到),当浏览器处理完这个表单后,将结果返回给sessionId所对应的用户(试想,如果没有sessionId,当有两个用户同时注册的时候,服务器怎样才能知道到底哪个用户提交的哪个表单呢)。

那如果cookie被禁用了怎么办呢?

如果cookie被禁用,通常有两种方式实现session而不依赖cookie。

  1. URL重写,就是把sessionId直接附在URL路径的后面。
  2. 表单隐藏字段。比如:
代码语言:javascript
复制
<form name="testform" action="/xxx"> 
    <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"> 
    <input type="text"> 
</form>
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP全栈技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MYSQL的Innodb和Myisam引擎的区别
  • 关于Innodb和Myisam的聚簇索引问题
    • 问题又来了,为什么Myisam既然没有聚簇索引查询速度也会比Innodb高呢 ?
    • 聚簇索引一定是主键吗?
    • 不建立主键的话是否就没有聚簇索引?
  • 如何避免‘回表’,什么是索引覆盖?
  • 说说PHP的垃圾回收机制
  • session和cookie的区别与联系
    • 区别
    • 联系
    • 那如果cookie被禁用了怎么办呢?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档