前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mysql常见的面试回答

mysql常见的面试回答

作者头像
技术从心
发布2020-03-10 11:19:46
3720
发布2020-03-10 11:19:46
举报
文章被收录于专栏:技术从心技术从心

innodb这种原生的数据文件就是索引文件的组织结构,这种默认的主键索引为聚簇索引。就是因为这个原因,innodb表要求必须有主键的,但是myisam表不要求必须有主键。另外一个是,innodb存储引擎下,如果对某个非主键的字段创建个索引,那么最后那个叶子节点的值就是主键的值,因为可以用主键的值到聚簇索引里根据主键再次查找到数据。

索引的类型:

MySQL目前主要有以下几种索引类型: 1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引

1.普通索引 是最基本的索引,它没有任何限制。它有以下几种创建方式: (1)直接创建索引

代码语言:javascript
复制
CREATE INDEX index_name ON table(column(length))

(2)修改表结构的方式添加索引

代码语言:javascript
复制
ALTER TABLE table_name ADD INDEX index_name ON (column(length))

(3)创建表的时候同时创建索引

代码语言:javascript
复制
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    INDEX index_name (title(length))
)

(4)删除索引

代码语言:javascript
复制
DROP INDEX index_name ON table

2.唯一索引 与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式: (1)创建唯一索引

代码语言:javascript
复制
CREATE UNIQUE INDEX indexName ON table(column(length))

(2)修改表结构

代码语言:javascript
复制
ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))

(3)创建表的时候直接指定

代码语言:javascript
复制
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    UNIQUE indexName (title(length))
);

3.主键索引 是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引:

代码语言:javascript
复制
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) NOT NULL ,
    PRIMARY KEY (`id`)
);

4.组合索引 指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合

代码语言:javascript
复制
ALTER TABLE `table` ADD INDEX name_city_age (name,city,age);

5.全文索引 主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like。它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。 (1)创建表的适合添加全文索引

代码语言:javascript
复制
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    FULLTEXT (content)
);

(2)修改表结构添加全文索引

代码语言:javascript
复制
ALTER TABLE article ADD FULLTEXT index_content(content)

(3)直接创建索引

代码语言:javascript
复制
CREATE FULLTEXT INDEX index_content ON article(content)

四、缺点

1.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行insert、update和delete。因为更新表时,不仅要保存数据,还要保存一下索引文件。 2.建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会增长很快。 索引只是提高效率的一个因素,如果有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。

五、注意事项

使用索引时,有以下一些技巧和注意事项: 1.索引不会包含有null值的列 只要列中包含有null值都将不会被包含在索引中,复合索引中只要有一列含有null值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为null。 2.使用短索引 对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。 3.索引列排序 查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。 4.like语句操作 一般情况下不推荐使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。 5.不要在列上进行运算 这将导致索引失效而进行全表扫描,例如

代码语言:javascript
复制
SELECT * FROM table_name WHERE YEAR(column_name)<2017;

6.不使用not in和<>操作

索引的使用规则:

最左前缀匹配原则

这个就是说,如果你的sql里,正好用得到了联合索引最左边的一个或者几个列表,那么也可以用上这个索引,在索引的里查找的时候就用最左的几个列就行。

事务的隔离级别(ACID)

1.atomic:原子性,就是一堆SQL,要么一起成功,要么都别执行,不许某个sql成功了,某个sql失败了,这就不是原子性

2.consitency:一致性,这个是针对数据一致性来说的,就是一组sql执行之前,数据必须是准确的,执行之后,数据也必须是准确的。

3.lsolation:隔离性,这个就是说多个事务在跑的时候不能互相干扰,别的事务A操作这个数据的时候,事务B不能操作这个数据。

4.durability:持久性,事务成功了,就必须针对数据的修改时有效的,别过了一会数据就没有了。

事务的隔离级别:

1.读未提交

read uncommitted,就是说某个事务还没提交的时候,修改的数据,就让别的事务读到,很容易出错,这个也叫脏读。

2.读已提交

read committed,这个比上面稍微好一点,就是说事务A在跑的时候,先查询到一个数据值是1,然后过一段时间,事务B把那个数据给修改了一下还提交了,此时事务A再次查询的时候值就变成2了,还是读了人家事务提交的数据,所以叫读已提交,这也叫做不可重读,就是所谓的一个事务内对一个数据两次读取可能会读取到不一样的值。

3.可重复读

read repeatable:这个就是比上面那个再好点儿,就是说事务A在执行 过程中,对某个数据的值,无论是读多次都是值1,哪怕是这个过程中事务B修改了数据的值还提交了事务,但是事务A读到的还是自己事务开始时候的那个值。

4.串行化(解决幻读)

幻读,不可重复读和可重复读都是针对两个事务同时对某条数据在修改,但是幻读针对的是插入,比如某个事务把所有的某个字段都修改为2,结果另外一个事务插入一条数据,那个数据的字段是1,第一个事务发现突然多出了一条数据,那个数据的字段是1.如果要解决幻读,就需要使用串行化级别的隔离级别,所有事务都串行起来,不许多个事务并行操作。

mysql是通过MVCC机制来实现的,就是多版本并发控制的。

innodb存储引擎,会在每行数据的最后加两个隐藏列,一个是保存行的创建时间,一个保存行的删除时间,但是这儿存放的不是时间,而是事务id,事务id是mysql自己维护的自增的,全局唯一。

每天

进步一点点

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 技术从心 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 四、缺点
  • 五、注意事项
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档