Mysql 常见问题
基础
MySQL 中有哪些不同的表格类型
- MyISAM
- Heap
- Merge
- INNODB
- MISAM
MyISAM 和InnoDB 的区别
- MyISAM:
- 不支持事务, 但是每次查询都是原子的; 支持表级锁, 即
每次操作是对整个表加锁
; 存储表的总行数; - 一个 MYISAM 表有三个文件: 索引文件、表结构文件、数据文件;
- 采用非聚集索引, 索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致, 但是辅索引不用保证唯一性。
- 不支持事务, 但是每次查询都是原子的; 支持表级锁, 即
- InnoDb:
- 支持 ACID 的事务, 支持事务的四种隔离级别; 支持行级锁及外键约束: 因此可以支持写并发; 不存储总行数:
- 一个 InnoDb 引擎存储在一个文件空间( 共享表空间, 表大小不受操作系统控制,一个表可能分布在多个文件里), 也有可能为多个( 设置为独立表空, 表大小受操作系统文件大小限制, 一般为 2G), 受操作系统文件大小的限制;
- 主键索引采用聚集索引(索引的数据域存储数据文件本身), 辅索引的数据域存储主键的值; 因此从辅索引查找数据, 需要先通过辅索引找到主键值, 再访问辅索引; 最好使用自增主键, 防止插入数据时, 为维持 B+树结构, 文件的大调整。
- MyISAM:
一张表,里面有 ID 自增主键,当 insert 了 17 条记录之后,删除了第 15,16,17 条记录,再把 Mysql 重启,再 insert 一条记录,这条记录的 ID 是 18 还是 15 ? MyISAM: 18 MyISAM 会把自增主键最大ID记录到数据文件中,重启不会丢失 InnoDB: 15 InnoDB 只是把自增主键最大ID记录到内存中,重启或者对表的 OPTIMIZE 操作都会导致最大ID丢失
Heap 表
- HEAP 表存在于内存中,用于临时高速存储。
- 不允许BLOB 或 TEXT 字段类型
- 只能使用比较运算符
=,<,>,=>,= <
- HEAP 表不支持 AUTO_INCREMENT
- 索引不可为 NULL
如何控制 HEAP 表的最大尺寸 max_heap_table_size
Federated 表 federated 表,允许访问位于其他服务器数据库上的表。
Mysql 中一个字节占用多少位 一个汉字占用几个字节,字母和数字呢
- 一个字节占用 8 位
- 如果设置的是
utf-8字符集 一个汉字占用 3 个字节 一个字母或者数字占用一个字节
区分 FLOAT 和 DOUBLE DECIMAL
- MySQL中,float和double都是浮点数类型,而decimal是定点数类型。
- float用于表示单精度浮点数值,而double用于表示双精度浮点数值。
MySQL对单精度值使用四个字节,对双精度值使用八个字节
。 - float和double在不指定精度时,默认会按照实际的精度来显示,而decimal在不指定精度时,默认整数为10,小数为0。
- MySQL 浮点型和定点型可以用类型名称后加(M,D)来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度。
- 例如,float(5,2)的可显示为999.99,MySQL保存值时会进行四舍五入,如果插入999.009,则结果为999.01。
- 与浮点数相比,decimal可以更准确地存储小数,并且可以避免一些浮点运算的误差。但是,在存储同样范围的值时,通常比decimal使用更少的空间,并且在一些处理器上比decimal更快。
CHAR_LENGTH 和 LENGTH CHAR_LENGTH 是字符数,而 LENGTH 是字节数。不管汉字、字母、数字,都占用1字符
Mysql 中 InnoDB 支持的四种事务隔离级别
- read uncommited :读到未提交数据
- read committed:脏读,不可重复读
- repeatable read:可重读(默认)
- serializable :串行事物
隔离级别 脏读 非重复读 幻读 read uncommited ✓ ✓ ✓ read committed ✓ ✓ repeatable read ✓ serializable CHAR 和 VARCHAR 的区别
- CHAR 和 VARCHAR 类型在存储和检索方面有所不同
- CHAR 列长度固定为创建表时声明的长度,长度值范围是 1 到 255
- 当 CHAR 值被存储时,它们被用空格填充到特定长度,检索 CHAR 值时需删除尾随空格。
列的字符串类型
- SET
- BLOB
- ENUM
- CHAR
- TEXT
- VARCHAR
TIMESTAMP 在 UPDATE CURRENT_TIMESTAMP 数据类型上作用
- 创建表时TIMESTAMP列用Zero更新。只要表中的其他字段发生更改, UPDATECURRENT_TIMESTAMP 修饰符就将时间戳字段更新为当前时间。
myisamchk作用 压缩 MyISAM 表,减少磁盘或内存使用。
列设置为 AUTO INCREMENT 时,如果在表中达到最大值,会发生什么 它会停止递增,任何进一步的插入都将产生错误
怎样才能找出最后一次插入时分配了哪个自动增量 LAST_INSERT_ID 将返回由 Auto_increment 分配的最后一个值,并且不需要指定表名称。
怎么看到为表格定义的所有索引
SHOW INDEX FROM <tablename>;
LIKE 声明中的%和_ %对应于 0 个或更多字符,_只匹配 LIKE 语句中的一个字符。
Unix 和 Mysql 时间戳转换
- UNIX_TIMESTAMP 是从 Mysql 时间戳转换为 Unix 时间戳的命令
- FROM_UNIXTIME 是从 Unix 时间戳转换为 Mysql 时间戳的命令
列对比运算符 =,<>,<=,<,> =,>,<<,>>,<=>,AND,OR 或LIKE 运算符。
Mysql 查询是否区分大小
Mysql 不区分大小写
LIKE 和 REGEXP 操作
- LIKE 和 REGEXP 运算符用于表示^和%。
SELECT * FROM employee WHERE emp_name REGEXP "^b";
SELECT * FROM employee WHERE emp_name LIKE "%b";
- LIKE 和 REGEXP 运算符用于表示^和%。
BLOB 和 TEXT
- BLOB 是一个二进制对象,可以容纳可变数量的数据。有四种类型的 BLOB
- TINYBLOB
- BLOB
- MEDIUMBLOB
- LONGBLOB
- TEXT 是一个不区分大小写的 BLOB。四种 TEXT 类型
- TINYTEXT
- TEXT
- MEDIUMTEXT
- LONGTEXT
- BLOB 和 TEXT 类型之间的唯一区别在于对 BLOB 值进行排序和比较时区分大小写,对TEXT 值不区分大小写。
- BLOB 是一个二进制对象,可以容纳可变数量的数据。有四种类型的 BLOB
mysql_fetch_array 和 mysql_fetch_object
- mysql_fetch_array() - 将结果行作为关联数组或来自数据库的常规数组返回。
- mysql_fetch_object - 从数据库返回结果行作为对象。
Mysql 表中允许有多少个 TRIGGERS
- BEFORE INSERT
- AFTER INSERT
- BEFORE UPDATE
- AFTER UPDATE
- BEFORE DELETE
- AFTER DELETE
MYSQL 连接
- 内连接(INNER JOIN):获取两个表中字段匹配关系的记录。
- 左连接(LEFT JOIN):获取左表所有记录,即使右表没有对应匹配的记录。
- 右连接(RIGHT JOIN):获取右表所有记录,即使左表没有对应匹配的记录。
- 交叉连接(CROSS JOIN):获取两个表中所有可能的组合。
- 联合查询(UNION):将多个查询结果合并成一个结果集。
jdbc vs odbc
- JDBC是Java数据库连接,是面向对象的,只能用于Java语言开发的程序中,可以在任何平台上使用。
- ODBC是开放式数据库连接,是程序性的,可以用于任何语言(如C,C++等)开发的程序中,但需要本地的ODBC驱动程序,仅适用于Windows平台。
- JDBC是通过网络访问数据库的URL连接方式,而ODBC是本地建立连接后再使用的方式。
- JDBC比ODBC更容易理解和使用,也更安全和稳定。
其他问题
唯一索引比普通索引快吗, 为什么
- 唯一索引不一定比普通索引快, 还可能慢.
- 查询时, 在未使用 limit 1 的情况下, 在匹配到一条数据后, 唯一索引即返回, 普通索引会继续匹配下一条数据, 发现不匹配后返回. 如此看来唯一索引少了一次匹配, 但实际上这个消耗微乎其微.
- 更新时, 普通索引将记录放到 change buffer 中语句就执行完毕了. 而对唯一索引而言, 它必须要校验唯一性, 因此, 必须将数据页读入内存确定没有冲突, 然后才能继续操作. 对于写多读少的情况, 普通索引利用 change buffer 有效减少了对磁盘的访问次数, 因此普通索引性能要高于唯一索引.
MySQL查询缓存有什么弊端, 应该什么情况下使用
- 查询缓存可能会失效非常频繁, 对于一个表, 只要有更新, 该表的全部查询缓存都会被清空. 因此对于频繁更新的表来说, 查询缓存不一定能起到正面效果.
- 对于读远多于写的表可以考虑使用查询缓存.
8.0版本的查询缓存功能被删
MySQL怎么恢复半个月前的数据 通过整库备份+binlog进行恢复. 前提是要有定期整库备份且保存了binlog日志.
数据库范式
- 第一范式: 属性不可再分.
- 第二范式: 在一范式的基础上, 要求数据库表中的每个实例或行必须可以被惟一地区分. 通常需要为表加上一个列, 以存储各个实例的惟一标识. 这个惟一属性列被称为主关键字或主键.
- 第三范式: 在二范式的基础上, 要求一个数据库表中不包含已在其它表中已包含的非主关键字信息.所以第三范式具有如下特征:1. 每一列只有一个值. 2. 每一行都能区分. 3. 每一个表都不包含其他表已经包含的非主关键字信息.
大数据量的表, 如何分页查询
- 数据量过大的情况下, limit offset 分页会由于扫描数据太多而越往后查询越慢.
- 可以配合当前页最后一条ID进行查询, SELECT * FROM T WHERE id > #{ID} LIMIT #{LIMIT} . 当然, 这种情况下ID必须是有序的, 这也是有序ID的好处之一.