zoukankan      html  css  js  c++  java
  • MySQL表分区

    一. 概念

    通俗地讲表分区是将一大表,根据条件分割成若干个小表。mysql5.1开始支持数据表分区了。
    如:某用户表的记录超过了600万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区。当然也可根据其他的条件分区。

    二. 优点

    为了改善大型表以及具有各种访问模式的表的可伸缩性,可管理性和提高数据库效率。
    分区的一些优点包括:
    • 与单个磁盘或文件系统分区相比,可以存储更多的数据。
    • 对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据。相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。
    • 一些查询可以得到极大的优化,这主要是借助于满足一个给定WHERE语句的数据可以只保存在一个或多个分区内,这样在查找时就不用查找其他剩余的分区。因为分区可以在创建了分区表后进行修改,所以在第一次配置分区方案时还不曾这么做时,可以重新组织数据,来提高那些常用查询的效率。
    • 涉及到例如SUM()和COUNT()这样聚合函数的查询,可以很容易地进行并行处理。这种查询的一个简单例子如 “SELECT salesperson_id, COUNT (orders) as order_total FROM sales GROUP BY salesperson_id;”。通过“并行”,这意味着该查询可以在每个分区上同时进行,最终结果只需通过总计所有分区得到的结果。
    • 通过跨多个磁盘来分散数据查询,来获得更大的查询吞吐量。

     三. 分区类型

    partition分区子句可以使用各种函数,但表达式返回的值要是一个确定的整数,且不能是一个常数。

    3.1 RANGE分区

    基于属于一个给定连续区间的列值,把多行分配给分区。

    CREATE TABLE employees (  
        id INT NOT NULL,  
        fname VARCHAR(30),  
        lname VARCHAR(30),  
        hired DATE NOT NULL DEFAULT '1970-01-01',  
        separated DATE NOT NULL DEFAULT '9999-12-31',  
        job_code INT NOT NULL,  
        store_id INT NOT NULL  
    )  
      
    PARTITION BY RANGE (store_id) (  
        PARTITION p0 VALUES LESS THAN (6),  
        PARTITION p1 VALUES LESS THAN (11),  
        PARTITION p2 VALUES LESS THAN (16),  
        PARTITION p3 VALUES LESS THAN MAXVALUE  
    ); 
    
    
    PARTITION BY RANGE (YEAR(separated)) (  
        PARTITION p_1991 VALUES LESS THAN (1991),  
        PARTITION p_1996 VALUES LESS THAN (1996),  
        PARTITION p_2001 VALUES LESS THAN (2001),  
        PARTITION p_more VALUES LESS THAN MAXVALUE  
    );
    

    RANGE分区在如下场合特别有用:
    • 当需要删除一个分区上的“旧的”数据时,只删除分区即可。 如果你使用上面最近的那个例子给出的分区方案,你只需简单地使用 “ALTER TABLE employees DROP PARTITION p0;”来删除所有在1991年前就已经停止工作的雇员相对应的所有行。对于有大量行的表,这比运行一个如“DELETE FROM employees WHERE YEAR (separated) <= 1990;”这样的一个DELETE查询要有效得多。
    • 想要使用一个包含有日期或时间值,或包含有从一些其他级数开始增长的值的列。
    • 经常运行直接依赖于用于分割表的列的查询。例如,当执行一个如“SELECT COUNT(*) FROM employees WHERE YEAR(separated) = 2000 GROUP BY store_id;”这样的查询时,MySQL可以很迅速地确定只有分区p2需要扫描,这是因为余下的分区不可能包含有符合该WHERE子句的任何记录。

    3.2 LIST分区

    类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。 
    LIST分区通过使用“PARTITION BY LIST(expr)”来实现,其中“expr” 是某列值或一个基于某个列值、并返回一个整数值的表达式,然后通过“VALUES IN (value_list)”的方式来定义每个分区,其中“value_list”是一个通过逗号分隔的整数列表。

    CREATE TABLE employees (  
        id INT NOT NULL,  
        fname VARCHAR(30),  
        lname VARCHAR(30),  
        hired DATE NOT NULL DEFAULT '1970-01-01',  
        separated DATE NOT NULL DEFAULT '9999-12-31',  
        job_code INT,  
        store_id INT  
    )  
      
    PARTITION BY LIST(store_id)  
        PARTITION pNorth VALUES IN (3,5,6,9,17),  
        PARTITION pEast VALUES IN (1,2,10,11,19,20),  
        PARTITION pWest VALUES IN (4,12,13,14,18),  
        PARTITION pCentral VALUES IN (7,8,15,16)  
    ); 
    

      这使得在表中增加或删除指定地区的雇员记录变得容易起来。例如,假定西区的所有音像店都卖给了其他公司。那么与在西区音像店工作雇员相关的所有记录 (行)可以使用查询“ALTER TABLE employees DROP PARTITION pWest;”来进行删除,它与具有同样作用的DELETE (删除)查询“DELETE query DELETE FROM employees WHERE store_id IN (4,12,13,14,18);”比起来,要有效得多。

    注意:如果试图插入列值(或分区表达式的返回值)不在分区值列表中的一行时,那么“INSERT”查询将失败并报错。要重点注意的是,LIST分区没有类似如“VALUES LESS THAN MAXVALUE”这样的包含其他值在内的定义。将要匹配的任何值都必须在值列表中找到。

    3.3 HASH分区

    基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
    要使用HASH分区来分割一个表,要在CREATE TABLE 语句上添加一个“PARTITION BY HASH (expr)”子句,其中“expr”是一个返回一个整数的表达式。它可以仅仅是字段类型为MySQL 整型的一列的名字。此外,你很可能需要在后面再添加一个“PARTITIONS num”子句,其中num 是一个非负的整数,它表示表将要被分割成分区的数量。

    CREATE TABLE employees (  
    	id INT NOT NULL,  
    	fname VARCHAR(30),  
    	lname VARCHAR(30),  
    	hired DATE NOT NULL DEFAULT '1970-01-01',  
    	separated DATE NOT NULL DEFAULT '9999-12-31',  
    	job_code INT,  
    	store_id INT  
    )  
    PARTITION BY HASH(store_id)  
    PARTITIONS 4; 
    

    如果没有包括一个PARTITIONS子句,那么分区的数量将默认为1。 

    3.4 LINER HASH分区

    MySQL还支持线性哈希功能,它与常规哈希的区别在于,线性哈希功能使用的一个线性的2的幂(powers-of-two)运算法则,而常规哈希使用的是求哈希函数值的模数。
    线性哈希分区和常规哈希分区在语法上的唯一区别在于,在“PARTITION BY” 子句中添加“LINEAR”关键字。

    CREATE TABLE employees (  
        id INT NOT NULL,  
        fname VARCHAR(30),  
        lname VARCHAR(30),  
        hired DATE NOT NULL DEFAULT '1970-01-01',  
        separated DATE NOT NULL DEFAULT '9999-12-31',  
        job_code INT,  
        store_id INT  
    )  
    PARTITION BY LINEAR HASH(YEAR(hired))  
    PARTITIONS 4; 


    3.5 KEY分区

    类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

    CREATE TABLE tk (  
    	col1 INT NOT NULL,  
    	col2 CHAR(5),  
    	col3 DATE  
    )  
    PARTITION BY LINEAR KEY (col1)  
    PARTITIONS 3;  
    

    在KEY分区中使用关键字LINEAR和在HASH分区中使用具有同样的作用,分区的编号是通过2的幂(powers-of-two)算法得到,而不是通过模数算法。

  • 相关阅读:
    关于敏捷开发的一些思考。
    【转】浅谈程序猿的职业规划,看你如何决定自己的未来吧。
    Individual Project
    homework_06 围棋程序改进
    homework 08_2 C++11新特性作业之二
    homework_08
    软件工程个人作业——Agile Software Development读后感
    附加题——软件工程之结对编程
    软件工程——PairProject
    软件工程第一次个人项目——词频统计by11061153柴泽华
  • 原文地址:https://www.cnblogs.com/waterystone/p/5086045.html
Copyright © 2011-2022 走看看