#mysql #partition
#mysql #раздел
Вопрос:
У меня проблема с разделением таблицы в MySQL. Я хочу, чтобы раздел таблицы reminders
зависел от квартала года, потому что я думаю, что смогу удалить список напоминаний, срок действия которых истек позже.
Возможно, мне следует добавить поле в primary key
или unique key
для работы с разделением. Пожалуйста, помогите мне с этой проблемой.
CREATE TABLE `reminders`
(
`id` bigint(20) NOT NULL,
`mer_reminder_id` varchar(255) UNIQUE NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`type` varchar(32) DEFAULT NULL,
`priority` int(11) DEFAULT NULL,
`due` timestamp NULL DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`template` varchar(32) DEFAULT NULL,
`action_id` bigint(20) NOT NULL,
`merchant_id` bigint(20) NOT NULL,
`expired` bool NULL DEFAULT NULL,
PRIMARY KEY (`id`, `created_at`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
PARTITION BY RANGE ( UNIX_TIMESTAMP(created_at) ) (
PARTITION zpm_reminder_reminders_q1_2019 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-04-01 00:00:00') ),
PARTITION zpm_reminder_reminders_q2_2019 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-07-01 00:00:00') ),
PARTITION zpm_reminder_reminders_q3_2019 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-10-01 00:00:00') ),
PARTITION zpm_reminder_reminders_q4_2019 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-01-01 00:00:00') ),
PARTITION zpm_reminder_reminders_q1_2020 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-04-01 00:00:00') ),
PARTITION zpm_reminder_reminders_q2_2020 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-07-01 00:00:00') ),
PARTITION zpm_reminder_reminders_q3_2020 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-10-01 00:00:00') ),
PARTITION zpm_reminder_reminders_q4_2020 VALUES LESS THAN ( UNIX_TIMESTAMP('2021-01-01 00:00:00') )
);
Проблема: #1503 - A UNIQUE INDEX must include all columns in the table's partitioning function
Ответ №1:
Сообщение об ошибке говорит само за себя: если ваша таблица разбита на разделы и имеет уникальный ключ, каждый столбец, используемый в уникальном ключе, также должен использоваться как часть раздела. Вы используете UNIX_TIMESTAMP(created_at)
для разделения, но у вас включен уникальный ключ mer_reminder_id
, поэтому эта конфигурация недопустима.
Мой совет: не используйте разделы MySQL для этого. Они чрезвычайно ограничивают, а также часто дают ошибки. Если вам нужно удалить старые строки в этой таблице, используйте DELETE
с условием — если ваша таблица не очень большая, вы потратите гораздо больше времени на обслуживание разделов, чем сэкономите на более быстрых операциях удаления.
(Кстати, я вижу потенциальную проблему с дизайном в вашей таблице — первичный ключ в вашей таблице, вероятно, должен быть id
, а не (id, created_at)
. Временные метки почти никогда не относятся к первичным ключам.)