Spec-Zone .ru
спецификации, руководства, описания, API
|
Диапазон и разделы списка очень подобны относительно того, как добавление и отбрасывание разделов
обрабатываются. По этой причине мы обсуждаем управление обоими видами разделения в этом разделе. Для получения
информации о работе с таблицами, которые делятся хешем или ключом, см. Раздел
17.3.2, "Управление HASH
и KEY
Разделы"
. Отбрасывание a RANGE
или LIST
раздел является
более прямым чем добавление того, таким образом, мы обсуждаем это сначала.
Отбрасывание раздела от таблицы, которая делится также RANGE
или LIST
может быть выполнен, используя ALTER TABLE
оператор с a DROP PARTITION
пункт. Вот
очень основной пример, который предполагает, что Вы уже составили таблицу, которая делится диапазоном и затем
заполняется с 10 записями, используя следующий CREATE
TABLE
и INSERT
операторы:
mysql>CREATE TABLE tr (id INT, name VARCHAR(50), purchased DATE)
->PARTITION BY RANGE( YEAR(purchased) ) (
->PARTITION p0 VALUES LESS THAN (1990),
->PARTITION p1 VALUES LESS THAN (1995),
->PARTITION p2 VALUES LESS THAN (2000),
->PARTITION p3 VALUES LESS THAN (2005)
->);
Query OK, 0 rows affected (0.01 sec)mysql>INSERT INTO tr VALUES
->(1, 'desk organiser', '2003-10-15'),
->(2, 'CD player', '1993-11-05'),
->(3, 'TV set', '1996-03-10'),
->(4, 'bookcase', '1982-01-10'),
->(5, 'exercise bike', '2004-05-09'),
->(6, 'sofa', '1987-06-05'),
->(7, 'popcorn maker', '2001-11-22'),
->(8, 'aquarium', '1992-08-04'),
->(9, 'study desk', '1984-09-16'),
->(10, 'lava lamp', '1998-12-25');
Query OK, 10 rows affected (0.01 sec)
Можно видеть, какие элементы должны были быть вставлены в раздел p2
как показано
здесь:
mysql>SELECT * FROM tr
->WHERE purchased BETWEEN '1995-01-01' AND '1999-12-31';
+------+-----------+------------+| id | name | purchased |+------+-----------+------------+| 3 | TV set | 1996-03-10 || 10 | lava lamp | 1998-12-25 |+------+-----------+------------+2 rows in set (0.00 sec)
Отбрасывать названный раздел p2
, выполните следующую команду:
mysql> ALTER TABLE tr DROP PARTITION
p2;
Query OK, 0 rows affected (0.03 sec)
Очень важно помнить, что, когда Вы отбрасываете раздел, Вы также удаляете все данные,
которые хранились в том разделе. Можно видеть что дело обстоит так, запуская повторно предыдущее SELECT
запрос:
mysql>SELECT * FROM tr WHERE purchased
->BETWEEN '1995-01-01' AND '1999-12-31';
Empty set (0.00 sec)
Из-за этого Вы должны иметь DROP
полномочие для таблицы прежде, чем можно будет выполниться ALTER TABLE ... DROP
PARTITION
на той таблице.
Если Вы хотите отбросить все данные от всех разделов, сохраняя табличное определение и его схему выделения
разделов, используйте TRUNCATE TABLE
оператор. (См. Раздел
13.1.27,"TRUNCATE TABLE
Синтаксис".)
Если Вы намереваетесь изменить разделение таблицы, не теряя данные,
использовать ALTER TABLE ... REORGANIZE PARTITION
вместо этого. См. ниже или в Разделе 13.1.6,"ALTER TABLE
Синтаксис", для информации о REORGANIZE
PARTITION
.
Если Вы теперь выполняете a SHOW CREATE
TABLE
оператор, можно видеть, как состав разделения таблицы был изменен:
mysql> SHOW CREATE TABLE tr\G
*************************** 1. row *************************** Table: trCreate Table: CREATE TABLE `tr` ( `id` int(11) default NULL, `name` varchar(50) default NULL, `purchased` date default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1PARTITION BY RANGE ( YEAR(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990) ENGINE = MyISAM, PARTITION p1 VALUES LESS THAN (1995) ENGINE = MyISAM, PARTITION p3 VALUES LESS THAN (2005) ENGINE = MyISAM)1 row in set (0.01 sec)
Когда Вы вставляете новые строки в измененную таблицу с purchased
значения столбцов
между '1995-01-01'
и '2004-12-31'
включительно, те
строки будут сохранены в разделе p3
. Можно проверить это следующим образом:
mysql>INSERT INTO tr VALUES (11, 'pencil holder', '1995-07-12');
Query OK, 1 row affected (0.00 sec)mysql>SELECT * FROM tr WHERE purchased
->BETWEEN '1995-01-01' AND '2004-12-31';
+------+----------------+------------+| id | name | purchased |+------+----------------+------------+| 11 | pencil holder | 1995-07-12 || 1 | desk organiser | 2003-10-15 || 5 | exercise bike | 2004-05-09 || 7 | popcorn maker | 2001-11-22 |+------+----------------+------------+4 rows in set (0.00 sec)mysql>ALTER TABLE tr DROP PARTITION p3;
Query OK, 0 rows affected (0.03 sec)mysql>SELECT * FROM tr WHERE purchased
->BETWEEN '1995-01-01' AND '2004-12-31';
Empty set (0.00 sec)
Отметьте что число строк, отброшенных от таблицы в результате ALTER TABLE ... DROP
PARTITION
не сообщается сервером, как это было бы эквивалентом DELETE
запрос.
Отбрасывание LIST
разделы используют точно то же самое ALTER
TABLE ... DROP PARTITION
синтаксис как использующийся для того, чтобы отбросить RANGE
разделы. Однако, есть одно важное различие в эффекте, который это имеет на Ваше использование таблицы позже:
больше невозможно вставить в таблицу строки, имеющие любое из значений, которые были включены в список значения,
определяющий удаленный раздел. (См. Раздел 17.2.2,"LIST
Разделение", для примера.)
Чтобы добавить новый диапазон или раздел списка к ранее разделенной таблице, используйте ALTER
TABLE ... ADD PARTITION
оператор. Для таблиц, которые делятся RANGE
, это
может использоваться, чтобы добавить новый диапазон до конца списка существующих разделов. Предположите, что у
Вас есть разделенная таблица, содержащая данные членства для Вашей организации, которая определяется следующим
образом:
CREATE TABLE members ( id INT, fname VARCHAR(25), lname VARCHAR(25), dob DATE)PARTITION BY RANGE( YEAR(dob) ) ( PARTITION p0 VALUES LESS THAN (1970), PARTITION p1 VALUES LESS THAN (1980), PARTITION p2 VALUES LESS THAN (1990));
Предположите далее, что минимальный возраст для элементов 16. Поскольку календарь приближается к концу 2005, Вы
понимаете, что будете скоро принимать членов, кто родился в 1990 (и позже в последующие годы). Можно изменить
members
таблица, чтобы разместить новые элементы, перенесенные в годах 1990 - 1999
как показано здесь:
ALTER TABLE members ADD PARTITION (PARTITION p3 VALUES LESS THAN (2000));
С таблицами, которые делятся диапазоном, можно использовать ADD PARTITION
чтобы
добавить новые разделы к верхнему уровню разделов перечисляют только. Попытка добавить новый раздел этим
способом между или перед существующими результатами разделов по ошибке как показано здесь:
mysql>ALTER TABLE members
>ADD PARTITION (
>PARTITION n VALUES LESS THAN (1960));
ERROR 1463 (HY000): VALUES LESS THAN value must be strictly » increasing for each partition
Можно работать вокруг этой проблемы, реорганизовывая первый раздел в два новых, которые разделяют диапазон между ними, как это:
ALTER TABLE members REORGANIZE PARTITION p0 INTO ( PARTITION n0 VALUES LESS THAN (1960), PARTITION n1 VALUES LESS THAN (1970));
Используя SHOW CREATE TABLE
можно видеть что ALTER TABLE
оператор имел требуемый эффект:
mysql> SHOW CREATE TABLE members\G
*************************** 1. row *************************** Table: membersCreate Table: CREATE TABLE `members` ( `id` int(11) DEFAULT NULL, `fname` varchar(25) DEFAULT NULL, `lname` varchar(25) DEFAULT NULL, `dob` date DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1/*!50100 PARTITION BY RANGE ( YEAR(dob))(PARTITION n0 VALUES LESS THAN (1960) ENGINE = InnoDB, PARTITION n1 VALUES LESS THAN (1970) ENGINE = InnoDB, PARTITION p1 VALUES LESS THAN (1980) ENGINE = InnoDB, PARTITION p2 VALUES LESS THAN (1990) ENGINE = InnoDB, PARTITION p3 VALUES LESS THAN (2000) ENGINE = InnoDB) */1 row in set (0.00 sec)
См. также Раздел 13.1.6.1,"ALTER
TABLE
Операции раздела".
Можно также использовать ALTER TABLE ... ADD PARTITION
добавить новые разделы к
таблице, которая делится LIST
. Предположите таблицу tt
определяется, используя следующий CREATE
TABLE
оператор:
CREATE TABLE tt ( id INT, data INT)PARTITION BY LIST(data) ( PARTITION p0 VALUES IN (5, 10, 15), PARTITION p1 VALUES IN (6, 12, 18));
Можно добавить новый раздел, в котором можно сохранить строки, имеющие data
значения столбцов 7
, 14
, и 21
как показано:
ALTER TABLE tt ADD PARTITION (PARTITION p2 VALUES IN (7, 14, 21));
Отметьте, что невозможно добавить новое LIST
раздел, охватывающий любые значения, которые уже включаются в список значения существующего раздела. Если Вы
попытаетесь сделать так, то ошибка закончится:
mysql>ALTER TABLE tt ADD PARTITION
>(PARTITION np VALUES IN (4, 8, 12));
ERROR 1465 (HY000): Multiple definition of same constant » in list partitioning
Поскольку любые строки с data
значение столбца 12
были
уже присвоены разделить p1
, невозможно создать новый раздел на таблице tt
это включает 12
в его списке значения. Чтобы
выполнить это, Вы могли отбросить p1
, и добавьте np
и
затем новое p1
с измененным определением. Однако, как обсуждено ранее, это привело
бы к потере всех данных, хранивших в p1
— и это часто имеет место, что это не то,
что Вы действительно хотите сделать. Другое решение, могло бы казаться, было бы, чтобы сделать копию таблицы с
новым разделением и скопировать данные в это использование CREATE TABLE ... SELECT ...
, тогда отбросьте старую таблицу и переименуйте
новый, но это могло быть очень отнимающим много времени, имея дело с большие объемы данных. Это также не могло
бы быть выполнимо в ситуациях, где высокая доступность является требованием.
Можно добавить многократные разделы в сингле 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 обеспечивает способы пересмотреть разделы, не теряя данные. Давайте
смотреть сначала на несколько простых включений в качестве примера RANGE
разделение. Вспомните members
таблица, которая теперь определяется как показано
здесь:
mysql> SHOW CREATE TABLE members\G
*************************** 1. row *************************** Table: membersCreate 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=latin1PARTITION 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.
A 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 TABLEtbl_name
REORGANIZE PARTITIONpartition_list
INTO (partition_definitions
);
Здесь, tbl_name
имя разделенной таблицы, и partition_list
список разделенных запятой значений имен одного или
более существующих разделов, которые будут изменены. partition_definitions
список разделенных запятой значений новых определений раздела, которые следуют за теми же самыми правилами что
касается partition_definitions
список, используемый в CREATE TABLE
(см. Раздел 13.1.14,"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
пункты, используемые, чтобы определить новую
схему выделения разделов, подчиняются тем же самым правилам как используемые с a CREATE TABLE
оператор.
Что наиболее важно следует помнить, что у новой схемы выделения разделов не может быть никаких
диапазонов наложения (применяется к таблицам, разделенным RANGE
) или
наборы значений (реорганизовывая таблицы, разделенные LIST
).
Комбинация разделов в partition_definitions
список должен учесть тот же самый
диапазон или набор значений повсюду как объединенные разделы, названные в partition_list
.
Например, в members
таблица, используемая в качестве примера в этом
разделе, разделах p1
и p2
вместе покройте
годы 1980 - 1999. Поэтому, любая перестройка этих двух разделов должна покрыть тот же самый диапазон
лет повсюду.
Для таблиц, разделенных RANGE
, можно реорганизовать
только смежные разделы; невозможно перескочить через разделы диапазона.
Например, Вы не могли реорганизовать members
таблица, используемая в
качестве примера в этом разделе, используя начинающийся оператор ALTER TABLE
members REORGANIZE PARTITION p0,p2 INTO ...
потому что p0
покрывает годы до 1970 и p2
годы с 1990 до 1999 включительно, и таким
образом эти два не являются смежными разделами.
Невозможно использовать REORGANIZE PARTITION
изменить
тип разделения таблицы; то есть, невозможно (например) измениться RANGE
разделы к HASH
разделы или наоборот. Также невозможно использовать эту команду, чтобы
изменить выражение разделения или столбец. Чтобы выполнить любую из этих задач, не отбрасывая и
воссоздавая таблицу, можно использовать ALTER TABLE ... PARTITION BY ...
. Например:
ALTER TABLE members PARTITION BY HASH( YEAR(dob) )PARTITIONS 8;