MySQL性能调优与架构设计【面试题一】
MySQL中有哪些存储引擎?
InnoDB存储引擎
InnoDB是MySQL的默认事务型引擎,也是最重要、使用最广泛的存储引擎。它被设计用来处理大量的短期(short-lived)事务,应该优先考虑InnoDB引擎。
MylSAM存储引擎
在MySQL 5.1及之前的版本,MyISAM是默认的存储引擎。MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务和行级锁,而且崩溃后无法安全恢复。MyISAM对整张表加锁,很容易因为表锁的问题导致典型的的性能问题。
Mrg_MylSAM
Merge存储引擎,是一组MyIsam的组合,也就是说,他将MyIsam引擎的多个表聚合起来,但是他的内部没有数据,真正的数据依然是MyIsam引擎的表中,但是可以直接进行查询、删除更新等操作。
Archive引擎
Archive存储引擎只支持INSERT和SELECT操作,会缓存所有的写并利用zlib对插入的行进行压缩,所以比MyISAM表的磁盘I/O更少。但是每次SELECT查询都需要执行全表扫描。所以Archive表适合日志和数据采集类应用,Archive引擎是一个针对高速插入和压缩做了优化的简单引擎。
Blackhole引擎
Blackhole引擎没有实现任何的存储机制,它会丢弃所有插入的数据,不做任何保存。可以在一些特殊的复制架构和日志审核时发挥作用。但这种引擎在应用方式上有很多问题,因此并不推荐。
CSV引擎
CSV引擎可以将普通的CSV文件(逗号分割值的文件)作为MySQL
的表来处理,但这种表不支持索引。因此CSV引擎可以作为一种数据交换的机制,非常有用。
Federated引擎
Federated引擎是访问其他MySQL服务器的一个代理,它会创建一个到远程MySQL服务器的客户端连接,并将查询传输到远程服务器执行,然后提取或者发送需要的数据。默认是禁用的。
Memory 引擎
Memory表至少比MyISAM 表要快一个数量级,数据文件是存储在内存中。Memory表的结构在重启以后还会保留,但数据会丢失。
Memroy表在很多场景可以发挥好的作用:
用于查找(lookup)或者映射(mapping)表,例如将邮编和州名映射的表。
用于缓存周期性聚合数据(periodically
aggregated data)的结果。
用于保存数据分析中产生的中间数据。
Memory表支持 Hash索引,因此查找操作非常快。Memroy表是表级锁,因此并发写入的性能较低,每行的长度是固定的,可能导致部分内存的浪费。
NDB集群引擎
使用MySQL服务器、NDB集群存储引擎,以及分布式的、share-nothing 的、容灾的、高可用的NDB数据库的组合,被称为MySQL集群((MySQL
Cluster)。
MyISAM和InnoDB的区别是什么?
MyISAM引擎是5.1版本之前的默认引擎,支持全文检索、压缩、空间函数等,但是不支持事务和行级锁,所以一般用于有大量查询少量插入的场景来使用,而且MyISAM不支持外键,并且索引和数据是分开存储的。
InnoDB是基于聚簇索引建立的,和MyISAM相反它支持事务、外键,并且通过MVCC来支持高并发,索引和数据存储在一起。
请概述下数据库的范式设计
目前关系数据库有六种范式,常见范式:第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。。
范式化设计优缺点:
优点:可以尽量得减少数据冗余,使得更新快,体积小;缺点:对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引优化
反范式化:
优点:可以减少表得关联,可以更好得进行索引优化;缺点:数据冗余以及数据异常,数据得修改需要更多的成本,常见的反范式设计有缓存、冗余等等。
数据库表设计时,字段你会如何选择?
更小的通常更好,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为它们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。但是要确保没有低估需要存储的值的范围。
简单就好,简单数据类型的操作通常需要更少的CPU周期。例如,整型比字符操作代价更低,比如应该使用MySQL内建的类型而不是字符串来存储日期和时间。
尽量避免NULL,如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引、索引统计和值比较都更复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊处理。当可为NULL的列被索引时,每个索引记录需要一个额外的字节。
mysql里记录货币用什么字段类型好?
MySQL既支持精确类型的存储DECIMAL类型,也支持不精确类型存储FLOAT和 DOUBLE类型。对于货币记录,应该选择DECIMAL类型,但是DECIMAL类型是以字符串形式存放的,所以性能会有影响。
作为替代方案,可以在数据量比较大的而且要求精度时,虑使用BIGINT代替DECIMAL,将需要存储的货币单位根据小数的位数乘以相应的倍数即可。
谈谈MySQL里的字符串类型
MySQL里的字符串类型有:SET、BLOB、ENUM、VARCHAR、CHAR、TEXT。VARCHAR和 CHAR是两种最主要的字符串类型。VARCHAR类型用于存储可变长字符串,大部分的业务情况下比定长类型更节省空间,CHAR类型是定长的,CHAR适合存储很短的字符串,或者所有值定长或都接近同一个长度。
使用BLOB和TEXT则要慎重,一般把 BLOB或TEXT 列分离到单独的表中,还可以对BLOB或TEXT 列使用合成的(Synthetic)索引,就是根据大文本字段的内容建立一个散列值并单独存储在数据列中,可以通过检索散列值找到数据行。如果表中的字段的取值是固定几个字符串,可以使用枚举列代替常用的字符串类型。
VARCHAR(M)最多能存储多少数据?
对于VARCHAR(M)类型的列最多可以定义65535个字节。其中的M代表该类型最多存储的字符数量,但在实际存储时并不能放这么多。
MySQL对一条记录占用的最大存储空间是有限制的,除了BLOB或者TEXT类型的列之外,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节。所以MySQL服务器建议我们把存储类型改为TEXT或者BLOB的类型。这个65535个字节除了列本身的数据之外,还包括一些其他的数据,从行记录格式我们可以得知,为了存储一个VARCHAR(M)类型的列,其实需要占用3部分存储空间:真实数据、真实数据占用字节的长度、NULL值标识,如果该列有NOT
NULL属性则可以没有这部分存储空间。
我们假设表中只有一个VARCHAR字段的情况:
如果该VARCHAR类型的列没有NOT NULL属性,那最多只能存储65532个字节的数据,因为真实数据的长度可能占用2个字节,NULL值标识需要占用1个字节。
如果VARCHAR类型的列有NOT NULL属性,那最多只能存储65533个字节的数据,因为真实数据的长度可能占用2个字节,不需要NULL值标识。
如果VARCHAR(M)类型的列使用的不是ascii字符集,那M的最大取值取决于该字符集表示一个字符最多需要的字节数。在列的值允许为NULL的情况下,gbk字符集表示一个字符最多需要2个字节,那在该字符集下,M的最大取值就是32766(也就是:65532/2),也就是说最多能存储32766个字符;utf8字符集表示一个字符最多需要3个字节,那在该字符集下,M的最大取值就是21844,就是说最多能存储21844(也就是:65532/3)个字符。
不管如何,请牢记:MySQL一个行中的所有列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节。
- 点赞
- 收藏
- 关注作者
评论(0)