热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql从头学一1.1存储引擎MEMORY和MERGE

MEMORY存储引擎使用存在内存中的内容来创建表。每个MEMORY表只实际对应一个磁盘文件,格式是.frm。MEMORY类型的表访问非常得快,因为它的数

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

下面例子创建了一个 MEMORY 的表,并从 city 表获得记录:

mysql> CREATE TABLE tab_memory ENGINE=MEMORY

    ->     SELECT city_id,city,country_id 

    ->     FROM city GROUP BY city_id;

Query OK, 600 rows affected (0.06 sec)

Records: 600  Duplicates: 0  Warnings: 0

 mysql> select count(*) from tab_memory;

+----------+

| count(*) |

+----------+

| 600      |

+----------+

1 row in set (0.00 sec)

 mysql> show table status like 'tab_memory' \G

*************************** 1. row ***************************

           Name: tab_memory

         Engine: MEMORY

        Version: 10

     Row_format: Fixed

           Rows: 600

 Avg_row_length: 155

    Data_length: 127040

Max_data_length: 16252835

   Index_length: 0

      Data_free: 0

 Auto_increment: NULL

    Create_time: NULL

    Update_time: NULL

     Check_time: NULL

      Collation: gbk_chinese_ci

       Checksum: NULL  Create_options: 

        Comment: 

1 row in set (0.00 sec)

给 MEMORY 表创建索引的时候,可以指定使用 HASH 索引还是 BTREE 索引:

mysql> create index mem_hash USING HASH on tab_memory (city_id) ;

Query OK, 600 rows affected (0.04 sec)

Records: 600  Duplicates: 0  Warnings: 0

 mysql> SHOW INDEX FROM tab_memory \G

*************************** 1. row ***************************

       Table: tab_memory

  Non_unique: 1

    Key_name: mem_hash

Seq_in_index: 1

 Column_name: city_id

   Collation: NULL  Cardinality: 300

    Sub_part: NULL

      Packed: NULL         Null: 

  Index_type: HASH      Comment: 

1 row in set (0.01 sec)

 

mysql> drop index mem_hash on tab_memory; Query OK, 600 rows affected (0.04 sec)

Records: 600  Duplicates: 0  Warnings: 0

 

mysql> create index mem_hash USING BTREE on tab_memory (city_id) ;

Query OK, 600 rows affected (0.03 sec)

Records: 600  Duplicates: 0  Warnings: 0

 

mysql> SHOW INDEX FROM tab_memory \G

*************************** 1. row ***************************

       Table: tab_memory

  Non_unique: 1

    Key_name: mem_hash

Seq_in_index: 1

 Column_name: city_id    Collation: A

 Cardinality: NULL

    Sub_part: NULL

      Packed: NULL         Null:    Index_type: BTREE

     Comment: 

1 row in set (0.00 sec)

在启动 MySQL 服务的时候使用--init-file 选项,把 INSERT INTO ... SELECT 或 LOAD DATA

INFILE 这样的语句放入这个文件中,就可以在服务启动时从持久稳固的数据源装载表。服务器需要足够内存来维持所有在同一时间使用的 MEMORY 表,当不再需要 MEMORY

表的内容之时,要释放被 MEMORY 表使用的内存,应该执行 DELETE FROM 或 TRUNCATE TABLE,或者整个地删除表(使用 DROP TABLE 操作)。

每个 MEMORY 表中可以放置的数据量的大小,受到 max_heap_table_size 系统变量的约束,这个系统变量的初始值是 16MB,可以按照需要加大。此外,在定义 MEMORY 表的时候,可以通过 MAX_ROWS 子句指定表的最大行数。

MEMORY 类型的存储引擎主要用在那些内容变化不频繁的代码表,或者作为统计操作的中间结果表,便于高效地对中间结果进行分析并得到最终的统计结果。对 MEMORY 存储引擎的表进行更新操作要谨慎,因为数据并没有实际写入到磁盘中,所以一定要对下次重新启动服务后如何获得这些修改后的数据有所考虑。

7.2.4 MERGE

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

INSERT_METHOD 子句定义插入的表,可以有 3 个不同的值,使用 FIRST 或 LAST 值使得插入操作被相应地作用在第一或最后一个表上,不定义这个子句或者定义为 NO,表示不能对这个 MERGE 表执行插入操作。

可以对 MERGE 表进行 DROP 操作,这个操作只是删除 MERGE 的定义,对内部的表没有

任何的影响。

MERGE 表在磁盘上保留两个文件,文件名以表的名字开始,一个.frm 文件存储表定义,另一个.MRG 文件包含组合表的信息,包括 MERGE 表由哪些表组成、插入新的数据时的依据。

可以通过修改.MRG 文件来修改 MERGE 表,但是修改后要通过 FLUSH TABLES 刷新。下面是一个创建和使用 MERGE 表的例子。

(1)创建 3 个测试表 payment_2006、payment_2007 和 payment_all,其中 payment_all 是前两个表的 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.03 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.02 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.04 sec)

 


  1. 分别向 payment_2006 和 payment_2007 表中插入测试数据:

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 

  1. 分别查看这 3 个表中的记录:

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)

可以发现,payment_all 表中的数据是 payment_2006 和 payment_2007 表的记录合并后的结果集。

下面向 MERGE 表插入一条记录,由于 MERGE 表的定义是 INSERT_METHOD=LAST,就会向最后一个表中插入记录,所以虽然这里插入的记录是 2006 年的,但仍然会写到 payment_2007 表中。

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)

 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 |

| 3          | 2006-03-31 00:00:00 | 112200.00 |

+------------+---------------------+-----------+

3 rows in set (0.00 sec)

这也是 MERGE 表和分区表的区别,MERGE 表并不能智能地将记录写到对应的表中,而分区表是可以的(分区功能在 5.1 版中正式推出)。通常我们使用 MERGE 表来透明地对多个表进行查询和更新操作,而对这种按照时间记录的操作日志表则可以透明地进行插入操作。

7.3 如何选择合适的存储引擎

在选择存储引擎时,应根据应用特点选择合适的存储引擎,对于复杂的应用系统可以根据实际情况选择多种存储引擎进行组合。

下面是常用存储引擎的适用环境。

      • MyISAM:默认的 MySQL 插件式存储引擎。如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常适合的。MyISAM 是在 Web、数据仓储和其他应用环境下最常使用的存储引擎之一。
      • InnoDB:用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询以外,还包括很多的更新、删除操作,那么 InnoDB 存储引擎应该是比较合适的选择。InnoDB 存储引擎除了有效地降低由于删除和更新导致的锁定,还可以确保事务的完整提交(Commit)和回滚(Rollback),对于类似计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB 都是合适的选择。
      • MEMORY:将所有数据保存在 RAM 中,在需要快速定位记录和其他类似数据的环境下,可提供极快的访问。MEMORY 的缺陷是对表的大小有限制,太大的表无法 CACHE 在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。

MEMORY 表通常用于更新不太频繁的小表,用以快速得到访问结果。

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

注意:以上只是我们按照实施经验提出的关于存储引擎选择的一些建议,但是不同应用的特点是千差万别的,选择使用哪种存储引擎才是最佳方案也不是绝对的,这需要根据用户各自的应用进行测试,从而得到最适合自己的结果。

 


推荐阅读
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 小程序wxs中的时间格式化以及格式化时间和date时间互转
    本文介绍了在小程序wxs中进行时间格式化操作的问题,并提供了解决方法。同时还介绍了格式化时间和date时间的互相转换的方法。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
author-avatar
米米清澈_109
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有