一、数据库的三范式是什么?
-
第一范式:列不可再分
-
第二范式:行可以唯一区分(主键约束)
-
表的非主属性不能依赖于其它表的非主数据(外键约束)
三范式是一级一级依赖的,第二范式建立在第一范式之上,第三范式建立在第二范式之上
二、数据库引擎有哪些?
查看数据库引擎方法:show engines;
MySql数据库引擎包括MYISAM、Innodb、Memory、MERGE
-
MYISAM:权标锁,拥有较高的执行速度,不支持事务、不支持外键、并发性能差、占用空间相对较小,对事务文字性没有要求;
-
Innodb:行级锁,提供了具有提交、回滚和崩溃回复能力的事务安全,支持自动增长列,支持外键约束,并发能力强,占用空间是MYISAM的2.5倍,处理效率相对较差;
-
Memory:全表锁,存储在内存中,速度快,但会占用和数据量成正比的内存空间且在mysql重启时会丢失,默认使用HASH索引,检索效率非常高,但不适用于精确查找,主要用于那些内容变化不频繁的代码表;
-
MERGE:是一组MYSIAM表的组合。
三、InnoDB与MyISAM的区别是什么?
-
InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,最好把多条SQL语言放在一个事务进行执行;
-
InnoDB支持外键,MyISAM不支持;
-
InnoDB是聚集索引,数据文件是和索引捆绑一起的,必须有主键,通过主键进行所有效率很高,但辅助索引需要两次查询,先查主键,再通过主键查询数据,因此,主键不应过大;而MyISAM是非聚集索引,数据文件是分离的,索引保存数据文件的指针,主键索引和辅助索引是独立的;
-
InnoDB不保存具体行数,执行 select count(*) 时需要进行全表扫描,速度相对较慢,而MyISAM用一个变量保存了整个表的行数,所以执行上面语句时,只需要读取该变量即可,速度很快;
-
InnoDB不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM会更高。
四、数据库的事务
-
什么是事务?
- 事务简单来说就是,多条sql语句要么全部成功,要么全部失败
-
事务的特性是什么?
-
原子性
-
一致性
-
隔离性
-
持久性
-
原子性:组成一个事务的多个数据库操作是一个密不可分的原子单元,只有所有操作都成功事务才会提交,任何一个步骤失败了已经执行的任何操作都会被撤销。
一致性:事务操作成功后,数据库的数据是一致的,如:A转账100给B,无论成功与否,AB的账户总额都是不变的
隔离性:高并发情况下,不同事务拥有的数据空间,他们的操作不会彼此产生干扰
持久性:一旦事务成功提交,事务中的所有操作都必须持久化到数据库中
五、什么是索引?
索引是对数据库表中一个或多个列的值进行排序的结构,建立索引能有助于快速找到对应信息
六、Mysql有多少种索引?
Mysql有4钟不同的索引
-
主键索引(PRIMARY):
数据列允许重复,不允许为NULL,一个表只能有一个主键
-
唯一索引(UNIQUE)
数据列不允许重复,允许为NULL值,一个表允许有多个唯一索引
ALTER TABLE TABLE_NAME ADD UNIQUE (COLUMN) // 创建唯一索引ALTER TABLE TABLE_NAME ADD UNIQUE (COLUMN1, COLUMN) // 创建唯一组合索引 -
普通索引(INDEX)
ALTER TABLE TABLE_NAME ADD INDEX INDEX_NAME (COLUMN) // 创建普通索引ALTER TABLE TABLE_NAME ADD INDEX INDEX_NAME (COLUMN1,COLUMN2) // 创建组合普通索引 -
全文索引(FULLTEXT)
ALTER TABLE TABLE_NAME ADD FULLTEXT (COLUMN) // 创建全文索引
注意:索引不是越多越好,创建索引需要消耗资源
1、增加数据库存储空间
2、在插入和删除时要花费较多的时间维护索引
-
索引加快了数据库的查询速度
-
索引降低了插入、删除、修改等维护任务的速度
-
唯一索引可以确保每一行数据的唯一性
-
通过使用索引,可以在查询的过程中优化隐藏器,提高系统的性能
-
索引需要占物理和数据空间
七、SQL优化
-
查询语句中不要使用 select *
-
尽量减少子查询,改用关联查询(left join、inner join 、right join)
-
减少使用 IN 或者 NOT IN,改用exists、not exists
-
or 的查询尽量用 union或者 union all替代
-
应尽量避免在 where 子句中使用 != 或 <> 操作符,否则索引会失效,继而全表扫描
-
应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致索引失效继而全表扫描
八、drop、delete、truncate的区别
delete 和 truncate 只删除数据不删除表结构,而 drop 则是删除数据和删除表结构
delete 语句是dml,这个操作会放到rollback segement中,事务提交才会生效;
drop truncate 语句是ddl,操作立即生效,并且操作不会放到rollback segement中,不支持回滚。
九、什么是视图?
视图是一种虚拟的表,具有和物理表相同的功能,可以对视图进行增、改、查操作,视图通常是由一个表或多个表的行或列的子集,对视图的修改不会影响基本表。
十、什么是内联接、左外联接、右外联接
-
内联接:匹配2张表中相关联的记录
-
左外联接:除了匹配2张表相关联的记录外,还会匹配左表中剩余的记录,右表中未匹配到的字段用NULL表示
-
右外联接:除了匹配2张表相关联的记录外,还会匹配右表中剩余的记录,左表中未匹配到的字段用NULL表示
十一、并发事务带来哪些问题
-
脏读:当一个事务在访问数据并且对数据进行了修改,而这种修改还没提交到数据库中,这是另外一个事务也访问该数据,但是获取到的数据是未修改之前的,这样的数据就叫“脏数据“;
-
丢失修改:一个事务读取数据时,另外一个事务访问了该数据进行修改,第一个事务也进行了修改,这样的情况会导致第一个事务修改的数据丢失,因此叫做丢失修改
-
不可重复读:一个事务内多次读取同一数据,在这个事务还没结束的情况下另外一个事务也访问了该数据,那么,在第一个事务中的两次读取数据之间,由于第二个事务的修改导致第一个事务读取的数据有可能不一样;
-
幻读:在一个事务中读取了多行数据,但是另外一个事务插入了些数据时,第一个事务又查询了一次,获取到了一些原本不存在的记录。
十二、事务隔离级别有哪些?MySQL的默认隔离级别是?
SQL标准定义了4个隔离级别
-
READ-UNCOMMITTED(读未提交):最低的隔离级别,允许尚未提交的数据变更,可能会导致脏读,幻读或不可重复读
-
READ-COMMOTTED(读已提交):允许读取并发事务已经提交的数据,可以阻止脏读,但幻读或不可重复读人仍可能发生
-
REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本身事务所修改,可以防止脏读和不可重复读,但幻读仍有可能发生
-
SERIALIZABLE(可串行化):最高的隔离级别,完全服重ACID的隔离级别,所有的事务依次逐个执行,事务之间完全不会产生干扰,该级别可以防止脏读、不可重复读以及幻读
MySQL InnoDB存储引擎默认支持的隔离级别是REPEATABLE-READ(可重复读)
可以通过 SELECT @@tx_isolation命令查看
需要注意的是,InnoDB存储引擎在REPERATABLE事务隔离级别下使用的是Next-Key-Lock锁算法,因此可以防止幻读的发生,
十三、数据量大的表怎么优化?
-
限定数据的范围
数据做历史查询的时候限定一个查询区间,一般控制在一个月的范围内
-
读/写分离
主库负责写,从库负责读
-
垂直分区
根据数据库里面的数据表关系进行拆分
-
水平分区
保持表结构不变,通过某种策略存储数据分配,每一片数据分散到不同的表或者库中,达到了分布式的目的
常见的数据库分片方案
客户端代理:分片逻辑在应用端,封装在jar中,通过修改或者封装JDBC层来实现,例如:ShardingJDBC(当当网)、TDDL(阿里)
中间件代理:在应用和数据中间加了一个代理层,分片逻辑统一维护在中间件服务中,例如:Mycat、Atlas(360)、DDB(网易)
十四、MySQL有关权限的表是哪几个?
-
user权限表:记录允许连接到服务器的用户信息,为全局权限
-
db权限表:记录各个账号数据库上的操作权限
-
table_priv权限表:记录数据表级的操作权限
-
column_priv权限表:记录数据列级权限
-
host权限表:配合db权限表给指定主机上的数据库级操作权限作更细致的控制,该表不受CRANT和REVOKE语句影响
十五、MySQL有哪些数据类型
-
数据类型包括:TINYINT、SMALLINT、MUDIUMINT、INT、BIGINT,分别表示1字节、2字节、3字节、4字节、8字节。
任何整数类型都可以加上UNSIGNED属性,表示数据都是无符号的,即非负整数。
-
实数类型包括:FLOAT、DOUBLE、DECIMAL
DECIMAL能存储比BIGINT更大的数字,可以精确到小数位
DECIMAL做计算的效率比FLOAT、DOUBLE更高
-
字符串类型包括:VARCHAR、CHAR、TEXT、BLOB
VARCHAR用于存储可变长字符串,它比定长类型更节省空间
VARCHAR使用额外1或2个字节存储字符串长度。烈长度小于255字节时,使用1字节表示,否则使用2字节表示
VARCHAR存储内容超过限定长度时,内容会被截断
CHAR是定长类型,根据定义的长度分配空间
CHAR适合存储很短长度的字符串,或者所有值都接近同一个长度
CHAR存储内容超出设置的长度时,内容也会被截断
-
枚举类型:ENUM,把不重复的数据存储为一个预定义的集合
有时可以使用ENUM代替常用的字符串类型
EMUN存储非常紧凑,会把列表值压缩到一个或两个字节
ENUM在内部存储时,其实存的是整数
尽量避免使用数据作为ENUM枚举的常量,避免混淆
排序是按照内部存储的整数
-
日期和时间类型包括:DATETIME、TIMESTAMP
尽量使用TIMESTAMP,空间效率高于DATETIME
用整数保存时间戳通常不方便处理
如果需要存储至微秒,可以使用BIGINT进行存储
十六、创建索引有几种方式?
-
在执行 CREATE TABL E时创建索引
CREATE TABLE TABLE_NAME ( id INT AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(16), last_name VARCHAR(16), id_card VARCHAR(18), information text, KEY name (first_name, last_name), FULLTEXT KEY (information), UNIQUE KEY (id_card)) -
使用 ALTER TABLE 命令创建索引
ALTER TABLE TABLE_NAME ADD INDEX (COLUMN1, COLUMN2);注意 ALTER TABLE 用来创建普通索引、唯一索引、主键索引
-
使用 CREATE INDEX 创建索引
CREATE INDEX INDEX_NAME ON TABLE_NAME (COLUMN);注意:CREATE INDEX 只能用来创建普通索引、唯一索引