MySQL: руководство профессионала
Шрифт:
in list partitioning
Потому что любые строки со значением столбца data 12 уже были назначены в раздел p1, Вы не можете создавать новый раздел в таблице tt, который включает 12 в список значения. Чтобы выполнять это, Вы могли бы удалить p1, добавить np, а затем новый p1 с изменяемым определением. Однако, как сказано ранее, это привело бы к потере всех данных, сохраненных в p1, и это часто имеет место. Другое решение: сделать копию таблицы с новым выделением разделов и скопировать данные в нее, используя CREATE TABLE … SELECT …, затем удалить старую таблицу и переименовать новую, но это могло бы быть очень долго, когда имеешь
Начиная с MySQL 5.1.6, Вы можете добавлять много разделов в одиночной команде ALTER TABLE … ADD PARTITION, как показано здесь:
CREATE TABLE employees (id INT NOT NULL, fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL, hired DATE NOT NULL)
PARTITION BY RANGE(YEAR(hired)) (
PARTITION p1 VALUES LESS THAN (1991),
PARTITION p2 VALUES LESS THAN (1996),
PARTITION p3 VALUES LESS THAN (2001),
PARTITION p4 VALUES LESS THAN (2005));
ALTER TABLE employees ADD PARTITION (PARTITION p5 VALUES LESS THAN (2010),
PARTITION p6 VALUES LESS THAN MAXVALUE);
Реализация выделения разделов в MySQL обеспечивает способы переопределить разделы без потерь данных. Выберите таблицу элементов members, которая теперь определена как показано здесь:
mysql> SHOW CREATE TABLE members\G
*************************** 1. row ***************************
Table: members
Create Table: CREATE TABLE `members` (`id` int(11) default NULL,
`fname` varchar(25) default NULL,
`lname` varchar(25) default NULL,
`dob` date default NULL)
ENGINE=MyISAM DEFAULT CHARSET=latin1
PARTITION BY RANGE (YEAR(dob)) (
PARTITION p0 VALUES LESS THAN (1970) ENGINE = MyISAM,
PARTITION p1 VALUES LESS THAN (1980) ENGINE = MyISAM,
PARTITION p2 VALUES LESS THAN (1990) ENGINE = MyISAM.
PARTITION p3 VALUES LESS THAN (2000) ENGINE = MyISAM)
Предположите, что Вы хотели бы переместить все строки, представляющие элементы, рожденные перед 1960 в отдельный раздел. Мы уже видели, что это не может быть выполнено, используя ALTER TABLE … ADD PARTITION. Однако, Вы можете использовать другое связанное с разделом расширение ALTER TABLE, чтобы выполнить это:
ALTER TABLE members REORGANIZE PARTITION p0 INTO (
PARTITION s0 VALUES LESS THAN (1960),
PARTITION s1 VALUES LESS THAN (1970));
В действительности эти команды разделяют раздел p0 на два новых раздела s0 и s1. Это также перемещает данные, которые были сохранены в p0, в новые разделы согласно правилам, воплощенным в двух предложениях PARTITION … VALUES …, так, чтобы s0 содержал только те записи, для которых YEAR(dob) меньше, чем 1960 и s1 хранил те строки, в которых YEAR(dob) является большим чем или равным 1960, но меньше чем 1970.
Предложение REORGANIZE PARTITION может также использоваться для объединения смежных разделов. Вы можете возвращать таблицу элементов members к предыдущему выделению разделов, как показано здесь:
ALTER TABLE members REORGANIZE PARTITION s0,s1 INTO (
PARTITION p0 VALUES LESS THAN (1970));
Никакие данные не потеряны при разбиении или объединении разделов, использующих REORGANIZE PARTITION. При выполнении вышеупомянутой инструкции MySQL перемещает все записи, которые были сохранены в разделах s0 и s1 в раздел p0.
Общий синтаксис для REORGANIZE PARTITION:
ALTER TABLE tbl_name
REORGANIZE PARTITION partition_list
INTO (partition_definitions);
Здесь tbl_name имя разбитой на разделы таблицы, partition_list разделяемый запятыми список имен одного или большего количества существующих разделов, которые будут изменены. partition_definitions разделяемый запятыми список новых определений разделов, которые следуют тем же самым правилам, что касаются списка partition_definitions, используемого в CREATE TABLE. Должно быть отмечено, что Вы не ограничены объединением нескольких разделов в один или разбиением одного раздела на много, когда используете REORGANIZE PARTITION. Например, Вы можете реорганизовать все четыре раздела таблицы элементов members в два следующим образом:
ALTER TABLE members REORGANIZE PARTITION p0,p1,p2,p3 INTO (
PARTITION m0 VALUES LESS THAN (1980),
PARTITION m1 VALUES LESS THAN (2000));
Вы можете также использовать REORGANIZE PARTITION с таблицами, которые разбиты на разделы LIST. Вернемся к проблеме добавления нового раздела к разбитой на разделы списком таблице tt и тому, что новый раздел имел значение, которое было уже представлено в списке значений одного из существующих разделов. Мы можем обрабатывать это, добавляя раздел, который содержит только не находящиеся в противоречии значения, а затем реорганизуя новый и существующий разделы так, чтобы значение, которое было сохранено в существующем, переместилось в новый:
ALTER TABLE tt ADD PARTITION (PARTITION np VALUES IN (4, 8));
ALTER TABLE tt REORGANIZE PARTITION p1,np INTO (
PARTITION p1 VALUES IN (6, 18),
PARTITION np VALUES in (4, 8, 12));
Имеются некоторые ключевые точки, которые следует иметь в виду, когда используете ALTER TABLE … REORGANIZE PARTITION, чтобы заново выделить разделы таблиц, которые разбиты на разделы RANGE или LIST:
Предложения PARTITION используемые, чтобы определить новую схему выделения разделов, подчинены тем же самым правилам, какие использовали с инструкцией CREATE TABLE.
Наиболее важно, Вы должны не забыть, что новая схема выделения разделов не может иметь любые диапазоны перекрывания (применяется к таблицам, разбитым на разделы RANGE) или наборов значений (при реорганизации таблиц, разбитых на разделы LIST).
Обратите внимание: до MySQL 5.1.4 Вы не могли бы многократно использовать имена существующих разделов в предложении INTO, даже когда те разделы удалялись удалялись или переопределялись.
Комбинация разделов в списке partition_definitions должна объявить тот же самый диапазон или полный набор значений, что и объединенные разделы, именованные в partition_list.