MySQL开发篇(4)表类型(存储引擎)的选择
一、查看支持的存储引擎以及设置修改存储引擎
1.查看默认存储引擎:show variables like '%storage_engine%';
2.查看当前数据库支持的存储引擎:show ENGINES \G
3.查看某个表使用的存储引擎: show create table 表名;
4.创建新表时指定存储引擎(如果不设置ENGINE则使用默认的存储引擎)
- mysql> CREATE TABLE ai(i bigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY(i))
- -> ENGINE=MyISAM DEFAULT CHARSET=gbk;
- Query OK, 0 rows affected (0.04 sec)
5.将一个已经存在的表修改成其他的存储引擎:ALTER TABLE ai ENGINE=innodb;
二、各种存储引擎的特性
1.MyISAM
MyISAM是默认的MySQL插件式存储引擎。如果应用是以读操作和插入操作为主,只有很少的更新操作和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常适合的。MyISAM是在Web、数据仓储和其他应用环境下最长使用的存储引擎之一。
MyISAM是MySQL默认的存储引擎。
MyISAM不支持事务、也不支持外键,其优势是访问的速度快,对事务完整性没有要求或者以SELECT、INSET为主的应用基本上都可以使用MyISAM来创建表。
每个MyISAM在磁盘上存储成3个文件,扩展名分别是:.frm(存储表定义)、.MYD(MYData,存储数据)、.MYI(MYIndex,存储索引)
数据文件和索引文件可以防止在不同的目录,平均分布IO,获得更快的速度。
MyISAM表还支持3中不同的存储格式:
- 静态(固定长度)表: 静态表是默认的存储格式。静态表中的字段都是非变长地段,这样每个记录都是固定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间比动态表多。静态表的数据在存储时会按照列的宽度定义补足空格,但是在应用访问的时候并不会得到这些空格,这些空格在返回应用之前已经去掉。
- 动态表:动态表中包含变长字段,记录不是固定长度的,这样存储的优点是占用的空间相对较少,但是频繁地更新和删除记录会产生碎片,需要定期执行OPTIMIZE TABLE语句或myisamchk -r命令来改善性能,并且在出现故障时恢复相对比较困难。
- 压缩表:由myisampack工具创建,占据非常小的磁盘空间。因为每个记录是被单独压缩的,所以只有非常小的访问开支。
2.InnoDB
InnoDB用于事务处理应用程序,支持外键、如果应用对事务的完整性有比较高的要求,在并发条件下要去数据的一致性,数据操作除了插入和查询以外,还包括很多的更新和删除操作,那么InnoDB是比较合适的选择。InnoDB除了有效地降低由于删除和更新导致的锁定,还可以确保事务的完整提交(Commit)和回滚(Rollback),以及崩溃恢复能力的事务安全,对于类似计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB都是合适的选择。
InnoDB不同于其他存储引擎的表的特点:自动增长列、外键约束、存储方式
(1)自动增长列
InnoDB表的自动增长列可以手动插入,当插入的值是0或者null时,实际插入的将是自动增长后的值。如果跳跃着插入,则从插入的第一个值开始增长。
对于InnoDB表,自动增长列必须是索引。如果是组合索引,也必须是组合索引的第一列。
但是对于MyISAM表,自动增长列可以是组合索引的其他列,这样插入记录后,自动增长列是按照组合索引的前面几列进行排序后递增的。
- mysql> create table autoincre_demo
- -> (i smallint not null auto_increment,
- -> name varchar(10),primary key(i)
- -> )engine=innodb;
- Query OK, 0 rows affected (0.04 sec)
- mysql> insert into autoincre_demo values(1,''),(0,''),(null,'');
- Query OK, 3 rows affected (0.01 sec)
- Records: 3 Duplicates: 0 Warnings: 0
- mysql> select * from autoincre_demo;
- +---+------+
- | i | name |
- +---+------+
- | 1 | 1 |
- | 2 | 2 |
- | 3 | 3 |
- +---+------+
- 3 rows in set (0.00 sec)
- mysql> insert into autoincre_demo values(1,''),(0,''),(null,'');
- ERROR 1062 (23000): Duplicate entry '' for key 'PRIMARY'
- mysql> insert into autoincre_demo values(5,''),(0,''),(null,'');
- Query OK, 3 rows affected (0.01 sec)
- Records: 3 Duplicates: 0 Warnings: 0
- mysql> select * from autoincre_demo;
- +---+------+
- | i | name |
- +---+------+
- | 1 | 1 |
- | 2 | 2 |
- | 3 | 3 |
- | 5 | 1 |
- | 6 | 2 |
- | 7 | 3 |
- +---+------+
- 6 rows in set (0.00 sec)
- mysql> select LAST_INSERT_ID();
- +------------------+
- | LAST_INSERT_ID() |
- +------------------+
- | 6 |
- +------------------+
- 1 row in set (0.00 sec)
- mysql> insert into autoincre_demo values('');
- ERROR 1136 (21S01): Column count doesn't match value count at row 1
- mysql> insert into autoincre_demo values(9,'5');
- Query OK, 1 row affected (0.00 sec)
- mysql> select LAST_INSERT_ID();
- +------------------+
- | LAST_INSERT_ID() |
- +------------------+
- | 6 |
- +------------------+
- 1 row in set (0.00 sec)
- mysql> insert into autoincre_demo values(10,'1'),(0,'2'),(null,'3');
- Query OK, 3 rows affected (0.00 sec)
- Records: 3 Duplicates: 0 Warnings: 0
- mysql> select LAST_INSERT_ID();
- +------------------+
- | LAST_INSERT_ID() |
- +------------------+
- | 11 |
- +------------------+
- 1 row in set (0.00 sec)
- mysql> show tables;
- +----------------+
- | Tables_in_tmz |
- +----------------+
- | ai |
- | autoincre_demo |
- | dept |
- | emp |
- | emp1 |
- | salary |
- | settest |
- | t1 |
- | t2 |
- | t3 |
- | t6 |
- +----------------+
- 11 rows in set (0.00 sec)
- mysql> drop autoincre_demo;
- ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'autoincre_demo' at line 1
- mysql> drop table autoincre_demo;
- Query OK, 0 rows affected (0.04 sec)
- mysql> show tables;
- +---------------+
- | Tables_in_tmz |
- +---------------+
- | ai |
- | dept |
- | emp |
- | emp1 |
- | salary |
- | settest |
- | t1 |
- | t2 |
- | t3 |
- | t6 |
- +---------------+
- 10 rows in set (0.00 sec)
- mysql> create table autoincre_demo
- -> (d1 smallint not null auto_increment,
- -> d2 smallint not null,
- -> name varchar(10),
- -> index(d2,d1)
- -> )engine=myisam;
- Query OK, 0 rows affected (0.00 sec)
- mysql> insert into autoincre_demo(d2,name) values(2,'2'),(3,'3'),(4,'4'),(2,'2'),(3,'3'),(4,'4');
- Query OK, 6 rows affected (0.00 sec)
- Records: 6 Duplicates: 0 Warnings: 0
- mysql> select * from autoincre_demo;
- +----+----+------+
- | d1 | d2 | name |
- +----+----+------+
- | 1 | 2 | 2 |
- | 1 | 3 | 3 |
- | 1 | 4 | 4 |
- | 2 | 2 | 2 |
- | 2 | 3 | 3 |
- | 2 | 4 | 4 |
- +----+----+------+
- 6 rows in set (0.00 sec)
自动增长列使用举例
(2)外键约束(TODO)
MySQL支持外键约束的只有InnoDB。在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动地创建相应的索引。
(3)存储方式
- 使用共享表空间存储:表结构保存在.frm文件中,数据和索引保存在innodb_data_home_dir和innodb_data_file_path定义的表空间中,可以多个文件。
- 使用多表空间存储:表结构仍然保存在.frm文件中,但是每个表的数据和索引单独保存在.ibd中。如果是个分区表,则每个分区对应单独的.ibd文件。
3.MEMROY
MEMORY将所有数据保存在RAM中,在需要快速定位记录和其他类似数据的环境下,可 提供极快的访问。MEMORY的缺陷是对表的大小有限制,太大的表无法缓存在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。MEMORY表通常用于更新不太频繁的小表,可以快速得到访问结果。
MEMORY存储引擎使用存在于内存中的内容来创建表。每个MEMORY表只实际对应一个磁盘文件,格式是.frm。MEMORY类型的表访问非常地块,因为它的数据是放在内存中的,并且默认使用HASH索引,也可以指定使用BTREE索引,但是一旦服务关闭,表中的数据就会丢失掉。
MEMORY主要用于内容变化不频繁的表,或者作为统计操作的中间结果表,便于高效地对中间结果进行分析并得到最终的统计结果。对MEMORY的表进行更新操作要谨慎,因为数据并没有实际写入到磁盘中,所以一定要对下次重新启动服务后如何获得这些修改后的数据有所考虑。
4.MERGE
MERGE用于将一系列等同的MyISAM表以逻辑方式组合在一起,并作为一个对象引用它们。MERGE表的优点在于可以突破对单个MyISAM表大小的限制,并且通过将不同的表分布在多个磁盘上,可以有效地改善MERGE表的访问效率。这对于诸如数据仓储等VLDB环境十分适合。
MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构完全相同,MERGE表本身并没有数据,对MERGE类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行的。
在定义MERGE表时,需要声明union和INSERT_METHOD,假如INSERT_METHOD=LAST,那么执行向MERGE表中插入数据时,就会向UNION中最后一个表中插入数据,这也是MERGE表和分区表的区别,MERGE表并不能智能地将记录写到对应的表中,而分区表是可以的。
- 1.新建两个MyISAM表和一个MERGE表
- mysql> create table payment_2006(
- -> country_id smallint,
- -> payment_date datetime,
- -> amount decimal(15,2),
- -> key idx_fk_country_id(country_id)
- -> )engine=myisam;
- Query OK, 0 rows affected (0.01 sec)
- mysql> create table payment_2007(
- -> country_id smallint,
- -> payment_date datetime,
- -> amount decimal(15,2),
- -> key idx_fk_country_id(country_id)
- -> )engine=myisam;
- Query OK, 0 rows affected (0.01 sec)
- mysql> create table payment_all(
- -> country_id smallint,
- -> payment_date datetime,
- -> amount decimal(15,2),
- -> INDEX(country_id)
- -> )engine=merge union=(payment_2006, payment_2007) INSERT_METHOD=LAST;
- Query OK, 0 rows affected (0.01 sec)
- 2.分别向两个MyISAM表中插入数据并查看三个表中的内容
- mysql> insert into payment_2006 values(1,'2006-05-01',100000),(2,'2006-08-15',150000);
- Query OK, 2 rows affected (0.00 sec)
- Records: 2 Duplicates: 0 Warnings: 0
- mysql> insert into payment_2007 values(1,'2007-02-20',35000),(2,'2007-07-15',220000);
- Query OK, 2 rows affected (0.00 sec)
- Records: 2 Duplicates: 0 Warnings: 0
- mysql> select * from payment_2006;
- +------------+---------------------+-----------+
- | country_id | payment_date | amount |
- +------------+---------------------+-----------+
- | 1 | 2006-05-01 00:00:00 | 100000.00 |
- | 2 | 2006-08-15 00:00:00 | 150000.00 |
- +------------+---------------------+-----------+
- 2 rows in set (0.00 sec)
- mysql> select * from payment_2007;
- +------------+---------------------+-----------+
- | country_id | payment_date | amount |
- +------------+---------------------+-----------+
- | 1 | 2007-02-20 00:00:00 | 35000.00 |
- | 2 | 2007-07-15 00:00:00 | 220000.00 |
- +------------+---------------------+-----------+
- 2 rows in set (0.00 sec)
- mysql> select * from payment_all;
- +------------+---------------------+-----------+
- | country_id | payment_date | amount |
- +------------+---------------------+-----------+
- | 1 | 2006-05-01 00:00:00 | 100000.00 |
- | 2 | 2006-08-15 00:00:00 | 150000.00 |
- | 1 | 2007-02-20 00:00:00 | 35000.00 |
- | 2 | 2007-07-15 00:00:00 | 220000.00 |
- +------------+---------------------+-----------+
- 4 rows in set (0.00 sec)
- 3.向MERGE表中插入数据,则可以看到的是向最后的MyISAM表中插入的
- mysql> insert into payment_all values(3,'2006-03-31',112200);
- Query OK, 1 row affected (0.00 sec)
- mysql> select * from payment_all;
- +------------+---------------------+-----------+
- | country_id | payment_date | amount |
- +------------+---------------------+-----------+
- | 1 | 2006-05-01 00:00:00 | 100000.00 |
- | 2 | 2006-08-15 00:00:00 | 150000.00 |
- | 1 | 2007-02-20 00:00:00 | 35000.00 |
- | 2 | 2007-07-15 00:00:00 | 220000.00 |
- | 3 | 2006-03-31 00:00:00 | 112200.00 |
- +------------+---------------------+-----------+
- 5 rows in set (0.00 sec)
MERGE表使用示例
MySQL开发篇(4)表类型(存储引擎)的选择的更多相关文章
- Mysql表类型(存储引擎)的比较
面试官问:你知道mysql有哪些存储引擎,区别是啥? 我:一脸闷逼,于是乎下来补一补,以作备查 1.和大多数数据库不同,MySQL 中有一个存储引擎的概念,针对不同的存储需求可以选择最优的存储引擎. ...
- MySQL查看和修改表的存储引擎(转载+加点东西)
1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎 两种方法: a.show table status from YOUR_DB_NAME where name='YOU ...
- MySQL查看和修改表的存储引擎
1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎 两种方法: a.show table status from db_name where name='table_na ...
- MySQL开发——【多表关系、引擎、外键、三范式】
多表关系 一对一关系 一对多或多对一关系 多对多关系 MySQL引擎 所谓的MySQL引擎就是数据的存储方式,常用的数据库引擎有以下几种: Myisam与InnoDB引擎之间的区别(面试) ①批量插入 ...
- MySQL开发篇,存储引擎的选择真的很重要吗?
前言 谁说MySQL查询千万级别的数据很拉跨?我今天就要好好的和你拉拉家常,畅谈到深夜,一起过除夕!这篇文章也是年前的最后一篇,希望能带给大家些许收获,不知不觉查找文档和参考实体书籍就写了这么多,自己 ...
- MySql(一)表类型(存储引擎)
MySql(一)表类型(存储引擎) 一.MYSQL存储引擎概述 二.存储引擎的特性对比 2.1 MyISAM 2.2 InnoDB 2.2.1 自动增长列 2.2.2 外键约束 2.2.3 存储方式 ...
- mysql 开发基础系列8 表的存储引擎
一. 表的存储引擎 1. 概述 插件式存储引擎是mysql数据库最重要的特性之一, 用户可以根据应用的需要选择如何存储和索引数据,是否使用事务等.在mysql 5.0里支持的引擎包括: MyISAM, ...
- mysql修改表的存储引擎(myisam<=>innodb)
查看当前数据库的所支持的数据库引擎以及默认数据库引擎 mysql> show engines; +--------------------+---------+----------------- ...
- MySQL更改数据库表的存储引擎
MySQL更改数据库表的存储引擎 1.查看表的原存储引擎 show create table user; 'user', 'CREATE TABLE `user` (\n `id` int(11) N ...
随机推荐
- Android Studio [RecyclerView/列表视图]
LinearRecyclerViewActivity.java package com.xdw.a122.recyclerview; import android.graphics.Rect; imp ...
- ppt课件动手动脑实际验证
1关于double精度 源代码:public class Doublejingdu { public static void main(String[] args) { System.out.prin ...
- [AspNetCore 3.0] 在RazorPages/MVC 中使用 Blazor (Razor组件)
开发环境 Vs2019 16.3.1 dotnetcore 3.0 一.开始 新建webapp项目 dotnet new webapp -o projectname 或Vs 中新建项目选择 Web应用 ...
- CentOS8-网卡配置
一. 介绍 Centos8系统更新,新的版本让人看起来感觉很舒服,这时有人会配置CentOS8系统的网卡使系统上网,就会遇到配置好的网卡不会生效,自己想想和配置CentOS7的时候一个样啊,CentO ...
- springboot系列之04-提高开发效率必备工具lombok
未经允许,不得转载 原作者:字母哥博客 本文完整系列出自:springboot深入浅出系列 一.前置说明 本节大纲 使用lombok插件的好处 如何安装lombok插件 使用lombok提高开发效率 ...
- Vagrant定制个性化CentOS7虚拟机模板
关于虚拟机模板 想用vagrant搭建hadoop集群,要完成以下准备工作: 三个虚拟机实例操作系统都是CentOS7的server版: 每个实例都要安装同样的应用.关闭防火墙.关闭swap等: 今天 ...
- .Net Core 商城微服务项目系列(十二):使用k8s部署商城服务
一.简介 本篇我们将会把商城的服务部署到k8s中,同时变化的还有以下两个地方: 1.不再使用Consul做服务的注册和发现,转而使用k8s-dns来实现. 2.不再使用Ocelot作为业务网关,使用T ...
- VisualStudio自定义调试工具(GIS)
闲言 偶尔分享技术,对,这次就是偶尔,几年一次(技术自卑).上周末竟然有人催更,也是受宠...若惊.以后会主动定期更的,可能. 前言 Visual Studio 调试器自带很多调试工具,调 ...
- SpringBoot注入Service失败
Description: The bean 'userService' could not be injected as a 'com.phy.hemanresoruce.service.UserSe ...
- Java读源码之Thread
前言 JDK版本:1.8 阅读了Object的源码,wait和notify方法与线程联系紧密,而且多线程已经是必备知识,那保持习惯,就从多线程的源头Thread类开始读起吧.由于该类比较长,只读重要部 ...