Разделение Mysql По Году (Дата) / Месяц (Дата) / Деньнедели (Дата)

Часто мне приходится иметь дело с таблицами, которые содержат редко или даже никогда не обновляемые данные.

Хорошим примером таких данных являются различные журналы.

Некоторые таблицы регулярно очищаются от устаревших данных, а в некоторых приходится хранить записи «вечно».

Поэтому такие таблицы «разбухают» и работа с ними становится сложной операцией для всей системы.

Чтобы снизить нагрузку на диск и файловую систему, придумали разметку, или просто разбиение на разделы.

Файл табличных данных разбивается по некоторому условию на несколько небольших файлов – разделов.

В случае журналов разумно разделить таблицы по полям, содержащим даты событий.

Часто бывает разумно разрезать таблицу разделов по годам или месяцам или дням месяца/недели.

Что-то мне подсказывает, что резать придётся по полю 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

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.