Часто мне приходится иметь дело с таблицами, которые содержат редко или даже никогда не обновляемые данные.
Хорошим примером таких данных являются различные журналы.
Некоторые таблицы регулярно очищаются от устаревших данных, а в некоторых приходится хранить записи «вечно».
Поэтому такие таблицы «разбухают» и работа с ними становится сложной операцией для всей системы.
Чтобы снизить нагрузку на диск и файловую систему, придумали разметку, или просто разбиение на разделы.
Файл табличных данных разбивается по некоторому условию на несколько небольших файлов – разделов.
В случае журналов разумно разделить таблицы по полям, содержащим даты событий.
Часто бывает разумно разрезать таблицу разделов по годам или месяцам или дням месяца/недели.
Что-то мне подсказывает, что резать придётся по полю timestamp. Давайте сделаем табличку:
А что если, например, вам нужно организовать таблицу с журналами по дням месяца? То есть что-то записывается в таблицу, хранится месяц-два, а потом удаляется.CREATE TABLE `foo` ( `id` int(11) NOT NULL AUTO_INCREMENT, `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `name` varchar(30) DEFAULT NULL, `email` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`) );
Что, если мы хотим вырезать вот так: ALTER TABLE foo PARTITION BY RANGE (YEAR(date_added))
(
PARTITION p2011 VALUES LESS THAN (2012) ,
PARTITION p2012 VALUES LESS THAN (2013) ,
PARTITION p2013 VALUES LESS THAN (2014)
);
Мы получаем: ERROR 1486 (HY000): Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
Объяснение этому следующее: «TIMESTAMP внутренне преобразуется в часовой пояс локального сеанса».
ХОРОШО: SELECT UNIX_TIMESTAMP('2012-01-01 00:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2012-01-01 00:00:00') |
+---------------------------------------+
| 1325361600 |
+---------------------------------------+
SELECT UNIX_TIMESTAMP('2013-01-01 00:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2013-01-01 00:00:00') |
+---------------------------------------+
| 1356984000 |
+---------------------------------------+
SELECT UNIX_TIMESTAMP('2014-01-01 00:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2014-01-01 00:00:00') |
+---------------------------------------+
| 1388520000 |
+---------------------------------------+
Сейчас: ALTER TABLE foo PARTITION BY RANGE (UNIX_TIMESTAMP(date_added))
(
PARTITION p2011 VALUES LESS THAN (1325361600) ,
PARTITION p2012 VALUES LESS THAN (1356984000) ,
PARTITION p2013 VALUES LESS THAN (1388520000) ,
PARTITION pMAXVALUE VALUES LESS THAN (MAXVALUE)
);
Итак, теперь мы получаем: ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
Это лечится: ALTER table foo DROP PRIMARY KEY, add PRIMARY KEY (`id`,`date_added`);
Снова: ALTER TABLE foo PARTITION BY RANGE (UNIX_TIMESTAMP(date_added))
(
PARTITION p2011 VALUES LESS THAN (1325361600) ,
PARTITION p2012 VALUES LESS THAN (1356984000) ,
PARTITION p2013 VALUES LESS THAN (1388520000) ,
PARTITION pMAXVALUE VALUES LESS THAN (MAXVALUE)
);
Все ок.
Мы получаем: CREATE TABLE `foo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`name` varchar(30) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`,`date_added`)
) ENGINE=InnoDB
PARTITION BY RANGE (UNIX_TIMESTAMP(date_added))
(PARTITION p2011 VALUES LESS THAN (1325361600) ENGINE = InnoDB,
PARTITION p2012 VALUES LESS THAN (1356984000) ENGINE = InnoDB,
PARTITION p2013 VALUES LESS THAN (1388520000) ENGINE = InnoDB,
PARTITION pMAXVALUE VALUES LESS THAN MAXVALUE ENGINE = InnoDB
);
Большой!
Этот тип «нарезки» подойдет, если вам нужно упорядочить архивные данные по файлам «по годам» или по месяцам.
А что если, например, вам нужно отсортировать таблицу с логами по дням месяца? то есть в таблице написано что-то, что хранится месяц-два, а потом протирается.
То есть, что если мы хотим разрезать вот так: Теги: #mysql раздел Разделение #MySQL
-
Облачное Жкх: Взгляд Изнутри
19 Oct, 24 -
Разбор В Нлтк. Продолжение
19 Oct, 24 -
[Научная Фантастика] Cloudbass
19 Oct, 24