Spec-Zone .ru
спецификации, руководства, описания, API
|
Таблица, которая делится диапазоном, делится таким способом, которым каждый раздел содержит строки, для которых
значение выражения разделения находится в пределах данного диапазона. Диапазоны должны быть непрерывными, но не
наложение, и определяются, используя VALUES LESS THAN
оператор. Для следующих
немногих примеров предположите, что Вы составляете таблицу такой как следующий, чтобы содержать записи персонала
для цепочки 20 видеомагазинов, перечисленных 1 - 20:
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);
Эта таблица может быть разделена диапазоном многими способами, в зависимости от Ваших потребностей. Один путь
состоял бы в том, чтобы использовать store_id
столбец. Например, Вы могли бы решить
разделить таблицу 4 пути, добавляя a PARTITION BY 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 (21));
В этой схеме выделения разделов все строки, соответствующие сотрудникам, работающим в хранилищах 1 - 5,
сохранены в разделе p0
, к нанятым в хранилищах 6 - 10 сохранены в разделе p1
, и так далее. Отметьте, что каждый раздел определяется в порядке от самого
низкого до самого высокого. Это - требование PARTITION BY RANGE
синтаксис; можно
думать об этом как о похожении на серию if ... elseif ...
операторы в C или Java в
этом отношении.
Легко решить что новая строка, содержащая данные (72, 'Michael', 'Widenius', '1998-06-25',
NULL, 13)
вставляется в раздел p2
, но что происходит, когда Ваша цепочка
добавляет 21-ое хранилище? В соответствии с этой схемой, нет никакого правила, которое касается
строки чей store_id
больше чем 20, таким образом, ошибка заканчивается, потому что
сервер не знает, куда поместить это. Можно препятствовать этому происходить при использовании "вместилища" VALUES LESS
THAN
пункт в CREATE TABLE
оператор, который предусматривает все значения, больше чем самое высокое значение, явно названное:
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);
Другой способ избежать ошибки, когда никакое совпадающее значение не находится, состоит в том,
чтобы использовать IGNORE
ключевое слово как часть INSERT
оператор. Для примера см. Раздел
17.2.2,"LIST
Разделение". Также см. Раздел
13.2.5,"INSERT
Синтаксис", для общей информации о IGNORE
.
MAXVALUE
представляет целочисленное значение, которое всегда больше чем самое
большое целочисленное значение (на математическом языке, оно служит наименьшим количеством
верхней границы). Теперь, любые строки, чей store_id
значение столбца
больше чем или равно 16 (самое высокое определенное значение) сохранены в разделе p3
. В некоторый момент в будущем — когда число хранилищ увеличилось до 25, 30,
или более — можно использовать ALTER
TABLE
оператор, чтобы добавить новые разделы для хранилищ 21-25, 26-30, и так далее (см. Раздел
17.3, "управление Разделом", для деталей того, как сделать это).
Почти таким же способом Вы могли разделить таблицу, основанную на кодах задания сотрудника — то есть, основанный
на диапазонах job_code
значения столбцов. Например — предполагающий, что
двухразрядные коды задания используются для регулярных рабочих (в магазине), трехразрядные коды используются для
офиса и поддерживают персонал, и четырехразрядные коды используются для позиций управления — Вы могли создать
разделенную таблицу, используя следующий оператор:
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 (job_code) ( PARTITION p0 VALUES LESS THAN (100), PARTITION p1 VALUES LESS THAN (1000), PARTITION p2 VALUES LESS THAN (10000));
В этом экземпляре все строки, касающиеся рабочих в магазине, были бы сохранены в разделе p0
,
те, которые касаются сотрудников офиса и технического персонала в p1
, и те, которые
касаются менеджеров в разделе p2
.
Также возможно использовать выражение в VALUES LESS THAN
пункты. Однако, MySQL
должен быть в состоянии оценить возвращаемое значение выражения как часть a LESS
THAN
(<
) сравнение.
Вместо того, чтобы разделять табличные данные согласно числу хранилища, можно использовать выражение, основанное
на одном из двух DATE
столбцы вместо этого. Например, давайте предположим, что Вы хотите
разделить основанный на году что каждый сотрудник, оставленный компанию; то есть, значение YEAR(separated)
. Пример a CREATE TABLE
оператор, который реализует такую схему выделения разделов,
показывают здесь:
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 RANGE ( YEAR(separated) ) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1996), PARTITION p2 VALUES LESS THAN (2001), PARTITION p3 VALUES LESS THAN MAXVALUE);
В этой схеме, для всех сотрудников, которые уехали до 1991, строки сохранены в разделе p0
; для тех, кто уехал в годах 1991 - 1995, в p1
; для
тех, кто уехал в годах 1996 - 2000, в p2
; и для любых рабочих, которые уехали после
2000 года, в p3
.
Также возможно разделить таблицу RANGE
, основанный на значении a TIMESTAMP
столбец, используя UNIX_TIMESTAMP()
функция, как показано в этом примере:
CREATE TABLE quarterly_report_status ( report_id INT NOT NULL, report_status VARCHAR(20) NOT NULL, report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) ( PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ), PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ), PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ), PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ), PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ), PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ), PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ), PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ), PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ), PARTITION p9 VALUES LESS THAN (MAXVALUE));
Любое другое включение выражений TIMESTAMP
значения не разрешаются. (См. Ошибку #42849.)
Разделение диапазона особенно полезно, когда один или больше следующих условий истина:
Вы хотите или должны удалить "старые"
данные. Если Вы используете схему выделения разделов, показанную сразу выше, можно просто использовать
ALTER TABLE employees DROP PARTITION p0;
удалить все строки, касающиеся
сотрудников, которые прекратили работать на фирму до 1991. (См. Раздел
13.1.6,"ALTER TABLE
Синтаксис", и Раздел
17.3, "управление Разделом", для получения дополнительной информации.) Для таблицы с
очень многими строками это может быть намного более эффективным чем выполнение a DELETE
запросите такой как DELETE FROM
employees WHERE YEAR(separated) <= 1990;
.
Вы хотите использовать столбец, содержащий дату или временные стоимости, или содержащий значения, являющиеся результатом некоторого другого ряда.
Вы часто выполняете запросы, которые зависят непосредственно от столбца,
используемого для того, чтобы разделить таблицу. Например, выполняя запрос такой как EXPLAIN PARTITIONS SELECT COUNT(*) FROM employees WHERE separated BETWEEN
'2000-01-01' AND '2000-12-31' GROUP BY store_id;
, MySQL может быстро определить тот
единственный раздел p2
потребности, которые будут отсканированы, потому что
остающиеся разделы не могут содержать записи, удовлетворяющие WHERE
пункт.
См. Раздел
17.4, "Сокращение Раздела", для получения дополнительной информации о том, как это
выполняется.
Разновидность на этом типе разделения RANGE COLUMNS
разделение. Разделение RANGE COLUMNS
позволяет использовать многократные столбцы для того, чтобы определить
диапазоны разделения, которые применяются и к размещению строк в разделах и для того, чтобы определить включение
или исключение определенных разделов, выполняя сокращение раздела. См. Раздел
17.2.3.1,"RANGE COLUMNS
разделение", для получения дополнительной
информации.
Схемы выделения разделов, основанные на временных интервалах. Если Вы хотите реализовать схему выделения разделов, основанную на диапазонах или интервалы времени в MySQL 5.7, у Вас есть две опции:
Разделите таблицу RANGE
, и для выражения разделения,
используйте функцию, работающую на a DATE
, TIME
, или DATETIME
столбец и возврат целочисленного значения, как показано
здесь:
CREATE TABLE members ( firstname VARCHAR(25) NOT NULL, lastname VARCHAR(25) NOT NULL, username VARCHAR(16) NOT NULL, email VARCHAR(35), joined DATE NOT NULL)PARTITION BY RANGE( YEAR(joined) ) ( PARTITION p0 VALUES LESS THAN (1960), PARTITION p1 VALUES LESS THAN (1970), PARTITION p2 VALUES LESS THAN (1980), PARTITION p3 VALUES LESS THAN (1990), PARTITION p4 VALUES LESS THAN MAXVALUE);
В MySQL 5.7 также возможно разделить таблицу RANGE
основанный на
значении a TIMESTAMP
столбец, используя UNIX_TIMESTAMP()
функция, как показано в этом примере:
CREATE TABLE quarterly_report_status ( report_id INT NOT NULL, report_status VARCHAR(20) NOT NULL, report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) ( PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ), PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ), PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ), PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ), PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ), PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ), PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ), PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ), PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ), PARTITION p9 VALUES LESS THAN (MAXVALUE));
В MySQL 5.7, любом другом включении выражений TIMESTAMP
значения не разрешаются. (См. Ошибку #42849.)
Также возможно в MySQL 5.7 использовать UNIX_TIMESTAMP(timestamp_column)
как выражение разделения для
таблиц, которые делятся LIST
. Однако, это обычно не практично,
чтобы сделать так.
Разделите таблицу RANGE COLUMNS
, использование a DATE
или DATETIME
столбец как столбец разделения. Например, members
таблица могла быть
определена, используя joined
столбец непосредственно, как показано здесь:
CREATE TABLE members ( firstname VARCHAR(25) NOT NULL, lastname VARCHAR(25) NOT NULL, username VARCHAR(16) NOT NULL, email VARCHAR(35), joined DATE NOT NULL)PARTITION BY RANGE COLUMNS(joined) ( PARTITION p0 VALUES LESS THAN ('1960-01-01'), PARTITION p1 VALUES LESS THAN ('1970-01-01'), PARTITION p2 VALUES LESS THAN ('1980-01-01'), PARTITION p3 VALUES LESS THAN ('1990-01-01'), PARTITION p4 VALUES LESS THAN MAXVALUE);