转换为分区表

时间:2011-08-19 22:57:23

标签: mysql database-partitioning

我有以下表结构,其中包含实时数据:

 CREATE TABLE IF NOT EXISTS `userstatistics` (
   `user_id` int(10) unsigned NOT NULL,
   `number_logons` int(7) unsigned NOT NULL DEFAULT '0',
   `number_profileminiviews` int(7) unsigned NOT NULL DEFAULT '0',
   `number_profilefullviews` int(7) unsigned NOT NULL DEFAULT '0',
   `number_mailsreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `number_interestreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `number_favouratesreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `number_friendshiprequestreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `number_imchatrequestreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `yearweek` int(6) unsigned NOT NULL DEFAULT '0',
   PRIMARY KEY (`user_id`,`yearweek`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我想将其转换为具有以下结构的分区表:

 CREATE TABLE IF NOT EXISTS `userstatistics` (
   `user_id` int(10) unsigned NOT NULL,
   `number_logons` int(7) unsigned NOT NULL DEFAULT '0',
   `number_profileminiviews` int(7) unsigned NOT NULL DEFAULT '0',
   `number_profilefullviews` int(7) unsigned NOT NULL DEFAULT '0',
   `number_mailsreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `number_interestreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `number_favouratesreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `number_friendshiprequestreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `number_imchatrequestreceived` int(7) unsigned NOT NULL DEFAULT '0',
   `yearweek` int(6) unsigned NOT NULL DEFAULT '0',
   PRIMARY KEY (`user_id`,`yearweek`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 /*!50100 PARTITION BY RANGE (yearweek)
 (PARTITION userstats_201108 VALUES LESS THAN (201108) ENGINE = InnoDB,
  PARTITION userstats_201109 VALUES LESS THAN (201109) ENGINE = InnoDB,
  PARTITION userstats_201110 VALUES LESS THAN (201110) ENGINE = InnoDB,
  PARTITION userstats_201111 VALUES LESS THAN (201111) ENGINE = InnoDB,
  PARTITION userstats_201112 VALUES LESS THAN (201112) ENGINE = InnoDB,
  PARTITION userstats_201113 VALUES LESS THAN (201113) ENGINE = InnoDB,
  PARTITION userstats_201114 VALUES LESS THAN (201114) ENGINE = InnoDB,
  PARTITION userstats_201115 VALUES LESS THAN (201115) ENGINE = InnoDB,
  PARTITION userstats_201116 VALUES LESS THAN (201116) ENGINE = InnoDB,
  PARTITION userstats_201117 VALUES LESS THAN (201117) ENGINE = InnoDB,
  PARTITION userstats_201118 VALUES LESS THAN (201118) ENGINE = InnoDB,
  PARTITION userstats_201119 VALUES LESS THAN (201119) ENGINE = InnoDB,
  PARTITION userstats_201120 VALUES LESS THAN (201120) ENGINE = InnoDB,
  PARTITION userstats_201121 VALUES LESS THAN (201121) ENGINE = InnoDB,
  PARTITION userstats_max VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;

我该如何进行转换?

只需将第二个SQL语句的第一行更改为

即可
 ALTER TABLE 'userstatistics' (

会这样做吗?

从MySQL 5.0升级到5.1。

3 个答案:

答案 0 :(得分:6)

首先,您需要运行MySQL 5.1或更高版本。 MySQL 5.0不支持分区。

其次,请注意单引号(分隔字符串和日期)和反向标记(在MySQL中分隔表和列标识符)之间的区别。在适当的地方使用正确的类型。我提到这一点,因为你的例子使用了错误的引号:

ALTER TABLE 'userstatistics' (

应该是:

ALTER TABLE `userstatistics` (

最后,是的,您可以使用ALTER TABLE将表重组为分区。这是一个精确的副本&从我在MySQL 5.1.57上测试的语句粘贴:

ALTER TABLE userstatistics PARTITION BY RANGE (yearweek)  (
PARTITION userstats_201108 VALUES LESS THAN (201108) ENGINE = InnoDB,   
PARTITION userstats_201109 VALUES LESS THAN (201109) ENGINE = InnoDB,   
PARTITION userstats_201110 VALUES LESS THAN (201110) ENGINE = InnoDB,   
PARTITION userstats_201111 VALUES LESS THAN (201111) ENGINE = InnoDB,   
PARTITION userstats_201112 VALUES LESS THAN (201112) ENGINE = InnoDB,   
PARTITION userstats_201113 VALUES LESS THAN (201113) ENGINE = InnoDB,   
PARTITION userstats_201114 VALUES LESS THAN (201114) ENGINE = InnoDB,   
PARTITION userstats_201115 VALUES LESS THAN (201115) ENGINE = InnoDB,   
PARTITION userstats_201116 VALUES LESS THAN (201116) ENGINE = InnoDB,   
PARTITION userstats_201117 VALUES LESS THAN (201117) ENGINE = InnoDB,   
PARTITION userstats_201118 VALUES LESS THAN (201118) ENGINE = InnoDB,   
PARTITION userstats_201119 VALUES LESS THAN (201119) ENGINE = InnoDB,   
PARTITION userstats_201120 VALUES LESS THAN (201120) ENGINE = InnoDB,   
PARTITION userstats_201121 VALUES LESS THAN (201121) ENGINE = InnoDB, 
PARTITION userstats_max VALUES LESS THAN MAXVALUE ENGINE = InnoDB);

请注意,这会导致表重组,因此如果此表中已有大量数据,则需要一段时间才能运行。具体多长时间取决于您拥有的数据量,硬件速度以及其他因素。请注意,在重组表时,它会被锁定,并且无法通过其他查询进行读写。

答案 1 :(得分:0)

答案 2 :(得分:0)

看看这个 关于alter table的http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

然后特别是alter table .. ADD / DROP / COALESCE / REORGANIZE分区sql几乎提供了管理分区的所有功能。

请注意,hash只能用于整数。

•ALTER TABLE ...除了与NDB表一起使用外,ADD PARTITION不会创建临时表。 RANGE或LIST分区的ADD或DROP操作是立即操作或几乎是操作。 HASH或KEY分区的ADD或COALESCE操作在更改的分区之间复制数据;除非使用LINEAR HASH或LINEAR KEY,否则这与创建新表非常相似(尽管操作是按分区进行的)。 REORGANIZE操作仅复制更改的分区,不触及未更改的分区。