• 7. 表类型(存储引擎)的选择


    MySQL中存储引擎针的概念,针对不同的存储需求选择最优的存储引擎。提高数据的存取读取效率。

    7.1 MySQL存储引擎概述

    MySQL支持的存储引擎包括MyISAM、InnoDB、MEMORY、MERGE、BDB等(前两种常用,后两种了解即可)。其中InnoDB和BDB提事务安全表,其他存储引擎都是非事务安全表

    MySQLv5.1之后默认的存储引擎为InnoDB,之前是MyISAM。

    1· 查看mysql支持哪些引擎:show engines G;

    engine:引擎名称;support:显示是否支持,default显示当前默认存储引擎;comment:简单描述;transactions:是否支持事务

    在这里插入图片描述

    2· 修改默认存储引擎: set default_storage_engine=innodb;

    修改后只是本次会话有效,其他会话无效,可通过global选项设置全局会话有效,无论本次会话还是全局会话都有效,但是重启后都会失效。

    3· 创建新表的时候,通过增加engine关键字则设置新表的存储引擎,也可以使用alter table tb_name engine=innodb修改表的存储引擎。

    mysql> create table t (
        -> id int(10) not null auto_increment,
        -> primary key(id)
        -> )ENGINE=MyISAM DEFAULT CHARSET=UTF8;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show create table t;
    +-------+------------------------------+
    | Table | Create Table                                                                                                         |
    +-------+------------------------------+
    | t     | CREATE TABLE `t` (
      `id` int(10) NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
    +-------+------------------------------+
    
    
    mysql> alter table t engine=InnoDB;
    mysql> show create table t;
    +-------+------------------------------+
    | Table | Create Table                                                                                                         |
    +-------+------------------------------+
    | t     | CREATE TABLE `t` (
      `id` int(10) NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +-------+------------------------------+
    

    7.2 各种存储引擎的特性

    在这里插入图片描述

    7.2.1 MyISAM

    ​ MySQL5.1之前的默认存储引擎。不支持事务、表级锁、不支持外键,优点是访问速度快对事务完整性没有要求或者以SELECT、INSERT为主的应用可以使用这个引擎来创建表

    1· 每个MyISAM在磁盘上存储成3个文件,其文件名和表名相同,但扩展名分别是:

    • .frm(存储表定义)
    • .MYD(MYData,存储数据)
    • .MYI (MYIndex,存储索引)

    数据文件和索引文件可以放置在不同的目录,平均分布IO,获得更快的速度

    2有误

    2· MyISAM的表支持3种不同的存储格式,分别是

    • 静态(固定长度)表

      默认的存储格式,表中字段都是固定长度,如果列不满足定义的列宽则空格填充。

      优点:访问速度快

      缺点:占用空间

    • 动态表

      存储的字段变长

      优点:占用空间少。

      缺点:容易产生碎片。

    • 压缩表

    mysql并没有什么静态、动态、压缩表,但是有静态动态压缩行,静态和动态是针对具体行中定义的数据类型,当保存具体的数据时所呈现的结果是什么样的。详情参考

    https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html

    varchar类型的对末尾空格不做处理,char类型的字段会去掉末尾空格

    # varchar类型的对末尾空格不做处理,char类型的字段会去掉末尾空格
    mysql> insert into t values(1,'abc'),(3,'abc  '),(4,'   abc');
    mysql> select name,length(name) from t;
    +--------+--------------+
    | name   | length(name) |
    +--------+--------------+
    | abc    |            3 |
    | abc    |            5 |
    |    abc |            6 |
    +--------+--------------+
    3 rows in set (0.00 sec)
    
    mysql> show create table t;
    +-------+------+
    | Table | Create Table                                                                   
    +-------+---+
    | t     | CREATE TABLE `t` (
      `id` int(10) NOT NULL AUTO_INCREMENT,
      `name` varchar(10) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 |
    +-------+-------+
    1 row in set (0.00 sec)
    
    mysql> alter table t modify name char(10);      
    
    mysql> select name,length(name) from t;
    +--------+--------------+
    | name   | length(name) |
    +--------+--------------+
    | abc    |            3 |
    | abc    |            3 |
    |    abc |            6 |
    +--------+--------------+
    #插入记录后面的空格都被去掉了,前面的空格保留。
    

    7.2.2 InnoDB

    ​ MySQL5.1之后默认的存储引擎,InnoDB 存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全,支持外键。但是对比 MyISAM的存储引擎,InnoDB 写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。

    应用场景:如果应用对事务的完整性有比较高大要求,要求在并发条件下要求数据的一致性,,数据操作除了插入和查询以外,还包括很多的更新、删除操作,那么 InnoDB 存储引擎应该是比较合适的选择。

    1. 自动增长列

    • InnoDB 表的自动增长列可以手工插入,但是插入的值如果是空或者 0,则实际插入的将是自动增长后的值。
    • 对于 InnoDB 表,自动增长列必须是索引。如果是组合索引,也必须是组合索引的第一列,但是对于 MyISAM 表,自动增长列可以是组合索引的其他列,这样插入记录后,自动增长列是按照组合索引的前面几列进行排序后递增的。
    • 可以通过alter table tb_name auto_increment = n;设置自动增长列的初始值。只适用于本次回话(重启失效)。可以使用LAST_INSERT_ID()查询当前线程最后插入记录使用的值。

    示例:

    mysql> create table autoincre_demo (
        -> i smallint not null auto_increment,
        -> name varchar(10),primary key(i));
    
    mysql> insert into autoincre_demo values(1,'1'),(0,'2'),(null,'3');
    mysql> select * from autoincre_demo;
    +---+------+
    | i | name |
    +---+------+
    | 1 | 1    |
    | 2 | 2    |
    | 3 | 3    |
    +---+------+
    
    

    2. 外键约束

    MySQL 支持外键的存储引擎只有 InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引。

    外键的使用需要满足下列的条件:

    1. 两张表必须都是InnoDB表,并且它们没有临时表。

    2. 建立外键关系的对应列必须具有相似的InnoDB内部数据类型。

    3. 建立外键关系的对应列必须建立了索引。

    (1)在创建索引的时候,可以指定在删除、更新父表时,对子表进行的相应操作,包 RESTRICTCASCADESET NULLNO ACTION

    1. CASCADE: 父表中删除或更新对应的行,同时自动的删除或更新自表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。

    2. SET NULL: 父表中删除或更新对应的行,同时将子表中的外键列设为空。注意,这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持。

    3. NO ACTION: InnoDB拒绝删除或者更新父表。

    4. RESTRICT: 拒绝删除或者更新父表。指定RESTRICT(或者NO ACTION)和忽略ON DELETE或者ON UPDATE选项的效果是一样的。

    外键约束使用最多的两种情况无外乎:

    1)父表更新时子表也更新,父表删除时如果子表有匹配的项,删除失败

    ON UPDATE CASCADE ON DELETE RESTRICT
    

    2)父表更新时子表也更新,父表删除时子表匹配的项也删除

    ON UPDATE CASCADE ON DELETE CASCADE
    

    (2)当某个表被其他表创建了外键参照,那么该表的对应索引或者主键禁止被删除。
    在导入多个表的数据时,如果需要忽略表之前的导入顺序,可以暂时关闭外键的检查;
    同样,在执行 LOAD DATA 和 ALTER TABLE 操作的时候,可以通过暂时关闭外键约束来加快处理的速度,关闭的命令是SET FOREIGN_KEY_CHECKS = 0;,执行完成之后,通过执行SET FOREIGN_KEY_CHECKS = 1;语句改回原状态。

    例如对下面创建的两个表,子表的外键指定是 ON DELETE RESTRICT ON UPDATE CACADE

    mysql> CREATE TABLE country ( 
        ->   country_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, 
        ->   country VARCHAR(50) NOT NULL, 
        ->   last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
        ->   PRIMARY KEY  (country_id) 
        -> )ENGINE=InnoDB DEFAULT CHARSET=utf8;
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> CREATE TABLE city ( 
        ->   city_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, 
        ->   city VARCHAR(50) NOT NULL, 
        ->   country_id SMALLINT UNSIGNED NOT NULL, 
        ->   last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
        ->   PRIMARY KEY  (city_id), 
        ->   KEY idx_fk_country_id (country_id), 
        ->   CONSTRAINT `fk_city_country` FOREIGN KEY (country_id) REFERENCES country (country_id) ON 
        -> DELETE RESTRICT ON UPDATE CASCADE 
        -> )ENGINE=InnoDB DEFAULT CHARSET=utf8;
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> insert into country(country_id,country) values(1,'ShanDong');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from country;
    +------------+----------+---------------------+
    | country_id | country  | last_update         |
    +------------+----------+---------------------+
    |          1 | ShanDong | 2020-07-21 10:21:48 |
    +------------+----------+---------------------+
    
    mysql> insert into city(city_id,city,country_id) values(111,'QingDao',1);
    
    mysql> select * from city;
    +---------+---------+------------+---------------------+
    | city_id | city    | country_id | last_update         |
    +---------+---------+------------+---------------------+
    |     111 | QingDao |          1 | 2020-07-21 10:22:53 |
    +---------+---------+------------+---------------------+
    # 删除主表中一条被子表关联的一条记录,报错
    mysql> delete from country where country_id=1;
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`city`, CONSTRAINT `fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `country` (`country_id`) ON UPDATE CASCADE)
    # 更新主表中的记录,子表有对应记录也会跟新
    mysql> update country set country_id=1000 where country_id=1;
    
    mysql> select * from city;
    +---------+---------+------------+---------------------+
    | city_id | city    | country_id | last_update         |
    +---------+---------+------------+---------------------+
    |     111 | QingDao |       1000 | 2020-07-21 10:22:53 |
    +---------+---------+------------+---------------------+
    
    mysql> select * from country;
    +------------+----------+---------------------+
    | country_id | country  | last_update         |
    +------------+----------+---------------------+
    |       1000 | ShanDong | 2020-07-21 10:23:48 |
    +------------+----------+---------------------+
    
    #上面已经演示了,当删除一条被其他表的外键关联字段时会报错,我们可以通过将外键约束禁止掉,就可以删除了
    #默认外键约束开启
    mysql> show variables like '%FOREIGN_KEY_CHECKS%';       
    +--------------------+-------+
    | Variable_name      | Value |
    +--------------------+-------+
    | foreign_key_checks | ON    |
    +--------------------+-------+
    
    mysql> set foreign_key_checks=off;
    mysql> show variables like '%FOREIGN_KEY_CHECKS%';
    +--------------------+-------+
    | Variable_name      | Value |
    +--------------------+-------+
    | foreign_key_checks | OFF   |
    +--------------------+-------+
    # 成功删除
    mysql> delete from country where country_id=1000;
    
    mysql> select * from country;
    Empty set (0.00 sec)
    

    3. 存储方式

    innoDB存储数据和索引有共享表空间存储和独占表空间存储两种方式,通过参数innodb_file_per_table控制,0表示共享空间,也是默认的,1表示独占空间。两种方式的表结构(描述)都保存在.frm文件中。

    共享表空间:

    每一个数据库的所有表的数据、索引都保存在一个文件中,默认在data目录下,名为ibdata1,大小为10M的文件,可以通过参数innodn_data_file_path=/data/ibdata1:2000M来指定存储路径。

    优点:

    (1)可以将表空间分为多个文件放在不同的磁盘上,分布IO,提高性能。采用共享空间存储,存储空间的大小不受文件系统下文件大小的限制了,而取决于自身的限制,官方文档显示,表空间的最大限制是64TB。

    (2)表数据和表结构放在一起,方便管理

    缺点:由于所有的数据和索引都是在一个文件中混合存储,这样的话对一个表做了大量的删除操作后,表空间中会产生大量的空隙

    独占表空间存储:

    每一张表都有自己独立的表空间,表的结构依然在.frm文件中,还有一个后缀为.ibd的文件,保存了这张表的数据和索引。

    优点:

    每张表都有自己独立的表空间,可实现单表在不同数据库中移动空间可回收。drop table会自动回收;删除数据后,通过alter table emp engine=innodb也可回收不用的表空间,效率和性能会好一些。
    缺点:由于每个表的数据都是以一个单独的文件来存放,所以会受到文件系统的大小限制

    7.2.3 MEMORY

    ​ MEMORY 存储引擎使用存在内存中的内容来创建表。每个 MEMORY 表只实际对应一个磁盘文件,格式是.frm。MEMORY 类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用 HASH 索引,但是一旦服务关闭,表中的数据就会丢失掉。

    MEMORY:将所有数据保存在 RAM 中,在需要快速定位记录和其他类似数据的环境下,可提供极快的访问。MEMORY 的缺陷是对表的大小有限制,太大的表无法 CACHE 在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。MEMORY 表通常用于更新不太频繁的小表,用以快速得到访问结果。

    7.2.4 MERGE

    MERGE 存储引擎是一组 MyISAM 表的组合,这些 MyISAM 表必须结构完全相同,MERGE表本身并没有数据,对 MERGE 类型的表可以进行查询、更新、删除的操作,这些操作实际上是对内部的实际的 MyISAM 表进行的。

    MERGE:用于将一系列等同的 MyISAM 表以逻辑方式组合在一起,并作为一个对象引用它们。MERGE 表的优点在于可以突破对单个 MyISAM 表大小的限制,并且通过将不同的表分布在多个磁盘上,可以有效地改善MERGE表的访问效率。这对于诸如数据仓储等VLDB环境十分适合。

    7.3 status和variables

    show status: 查看系统运行的实时状态,便于dba查看mysql当前运行的状态,做出相应优化,动态的,不可人为进行修改,只能系统自动update。

    show variables : 查看系统参数,系统默认设置或者dba调整优化后的参数,静态的。可以通过set或者修改my.cnf配置文件修改。

    首先可以通过下属两个命令来查看mysql的相应的系统参数

    # 支持模糊查询
    show status like '%abc%';
    show variables like '%abc%';
    

    参考:mysql之status和variables区别及用法详解

    系统变量又分global和session,比如当用show variables like 'character_set%';不选中数据库和选中数据库时查询的记过是不一样的。

  • 相关阅读:
    5.6移植Madplay到开发板
    5.4.Makefile
    5.3交叉工具链使用
    5.2嵌入式linux程序编译与调试
    5.1Minicom 通信配置-linux环境
    7.点亮led的操作
    6、异常向量表的学习---设置SVC模式
    4.协处理器访问指令
    3.Arm机器码
    android RelativeLayout控件或view实现叠加效果
  • 原文地址:https://www.cnblogs.com/wubug/p/13667241.html
Copyright © 2020-2023  润新知