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

    为毛要分表和分区,,,,
    所有数据库的通病,文件越大,性能越低...那问题就来了.数据越多文件越大...无解?哎,所以说知道 为毛要分区了吧!
    那分表又是毛线?
    分表就是把一张表拆分成若干表,,,根据情况常见2种方式,一种是横向(水平分表),不断复制完全一样的表,一种是纵向(垂直分表) 按列拆分成若干个表. 
    那分区又是毛线?
    说白了就是mysql帮咱们分表,储存到不同的位置(自定义)
    别扯了,说重点吧!
    好.
    分表
    水平分表 
    完全相同的数据结构来复制表,
    比如 
    user1 user2 user3 都有相同的数据结构 . id, username 假定每个表只存10万条数据. 那么 10万01就会存到user2中,  17万8000 也应该在第二个表中, 公式是 该条数据 % 10万(上限) 就可以得到表了 
    执行查询也是先计算该数据存在哪个表中. 缺点自然能看的出来. 搜索三个表的数据时比较 麻烦.这时可以对某些字段单独建一个关联表. 
    垂直分表
    还是以user为例 id username password  10亿条数据可能过大. 那怎么办呢. 
    建 user,userpass 两个表.字段分别是 id,username   id,password  一一关联. 即可.  缺点.如果使用 where username and password时就无法使用了.    所以 这种分表方式必须根据条件来判断是否可取. 
    分区
    分区有4种方式分别是  hash   key    list  range

    先说hash

    [SQL] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    drop table if exists test1;
    CREATE TABLE test1 (
        id INT NOT NULL primary key  auto_increment, -- 自动递增
        username varchar(5) not null -- 用户名
    )
    ENGINE=innodb
    PARTITION BY HASH(id) -- 以id(必须是主键才可以)分区,共分4个区.
    PARTITIONS 4 ( -- 分别是
            partition p0  -- p0   数据位置和索引位置分别如下
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p1
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p2
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p3
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test'
    ) ;
    insert test1 (username) values
    ('test1'),-- 储存在p0分区
    ('test2'),-- 储存在p1分区
    ('test3'),-- p2
    ('test4'),-- p3
    ('test5');-- po分区

    如果出现 Error : Got error -1 from storage engine 说明没权限 

    /data/wwwroot/test/test   注意这里多出一个test
    total 768
    drwxrwx---  6 _mysql        wheel    204  4 13 11:27 .
    drwxrwxrwx  3 xxxxxxxx   wheel    102  4 13 11:27 ..
    -rw-rw----  1 _mysql        wheel  98304  4 13 11:27 test1#P#p0.ibd
    -rw-rw----  1 _mysql        wheel  98304  4 13 11:27 test1#P#p1.ibd
    -rw-rw----  1 _mysql        wheel  98304  4 13 11:27 test1#P#p2.ibd
    -rw-rw----  1 _mysql        wheel  98304  4 13 11:27 test1#P#p3.ibd

    如果换成myisam 则是这样
    /data/wwwroot/test  注意这里是设置的test路径  里面的test内容 就是上面的内容  其它就是myisam的分区文件 内容了
    test                        test1#P#p1.MYD        test1#P#p2.MYI
    test1#P#p0.MYD        test1#P#p1.MYI        test1#P#p3.MYD
    test1#P#p0.MYI        test1#P#p2.MYD        test1#P#p3.MYI

    接下来就是range
    [SQL] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    drop table if exists test1;
    CREATE TABLE test1 (
        id INT NOT NULL primary key  auto_increment, -- 自动递增
        username varchar(5) not null -- 用户名
    )
    ENGINE=innodb
    PARTITION BY RANGE(id) -- 以id(必须是主键才可以)分区,共分4个区.
    PARTITIONS 4 ( -- 分别是
            partition p0 VALUES LESS THAN (3)  -- 小于3的
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p1 values less than (5)  -- 小于5的
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p2 values less than (10) -- 小于10的
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test' ,
            partition p3 values less than MAXVALUE -- >10 其它的
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test'
    ) ;
    insert test1 (username) values
    ('test1'),-- 1 储存在p0分区
    ('test2'),-- 2 p0
    ('test3'),-- 3 p1
    ('test4'),-- 4 p1
    ('test5'),-- 5 p2
    ('test6');-- 6 p2


    再然后就是list了
    [SQL] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    drop table if exists test1;
    CREATE TABLE test1 (
        id INT NOT NULL primary key  auto_increment, -- 自动递增
        username varchar(5) not null -- 用户名
    )
    ENGINE=innodb
    PARTITION BY list(id) -- 以id(必须是主键才可以)分区,共分4个区.
    PARTITIONS 2 ( -- 分别是
            partition p0 VALUES in(1,2,3,4,5)  -- id mod 10
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p1 values in(6,7,8,9,0)  -- id mod 10
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test'
    ) ;
    insert test1 (username) values
    ('test1'),-- 1 储存在p0分区
    ('test2'),-- 2 p0
    ('test3'),-- 3 p0
    ('test4'),-- 4 p0
    ('test5'),-- 5 p0
    ('test6');-- 6 p1


    最后就是key了. 

    理解key跟hash差不多就可以了,只不过Hash分区允许使用用户自定义的表达式,而Key分区不允许使用用户自定义的表达式,需要使用MySQL服务器提供的HASH函数;同时Hash分区只支持整数分区,而Key分区支持使用BLOB或Text类型外其他类型的列作为分区键 

    [SQL] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    drop table if exists test1;
    CREATE TABLE test1 (
        id INT NOT NULL primary key  auto_increment, -- 自动递增
        username varchar(5) not null -- 用户名
    )
    ENGINE=innodb
    PARTITION BY key(id) -- 以key.
    ( -- 分别是
            partition p0
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p1 
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p2 
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test' ,
            partition p3
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test'
    )  
     
    ;





    另外还支持子分区.
    比如  range基础上再来一个hash子分区

    [SQL] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    drop table if exists test1;
    CREATE TABLE test1 (
        id INT NOT NULL primary key  auto_increment, -- 自动递增
        username varchar(5) not null -- 用户名
    )
    ENGINE=innodb
    PARTITION BY RANGE(id) -- 以id(必须是主键才可以)分区,共分4个区.
    SUBPARTITION by hash(id)
    ( -- 分别是
            partition p0 VALUES LESS THAN (3)  -- 小于3的
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p1 values less than (5)  -- 小于5的
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test',
            partition p2 values less than (10) -- 小于10的
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test' ,
            partition p3 values less than MAXVALUE -- >10 其它的
                    data directory='/data/wwwroot/test'
                    index directory='/data/wwwroot/test'
    )  
     
    ;







    mysql 5.5后增加了个 COLUMNS 分区
    mysql-5.5开始支持COLUMNS分区,可视为RANGE和LIST分区的进化,COLUMNS分区可以直接使用非整形数据进行分区。COLUMNS分区支持以下数据类型:
      所有整形,如INT SMALLINT TINYINT BIGINT。FLOAT和DECIMAL则不支持。
      日期类型,如DATE和DATETIME。其余日期类型不支持。
      字符串类型,如CHAR、VARCHAR、BINARY和VARBINARY。BLOB和TEXT类型不支持。
      COLUMNS可以使用多个列进行分区。



  • 相关阅读:
    礼物
    Hibernate 笔记 HQL查询 条件查询,聚集函数,子查询,导航查询
    Hibernate get 和 load区别
    JS
    JS
    JS
    JS
    JS
    JS
    JS
  • 原文地址:https://www.cnblogs.com/ghjbk/p/6703485.html
Copyright © 2011-2022 走看看