Как организовать разделы по автоинкременту и дате? - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть игра, в которой происходят битвы между соперниками.

Информация о битвах хранится в одной таблице. Информация о ходе битвы хранится в другой таблице.

Информация о битве, которая длилась несколько дней, go никому не нужна и должна быть дешево уничтожена. Я решил сделать это с помощью разделов и планировщика.

Все отлично работает, но само решение все еще сбивает с толку. Может быть, я изобрел велосипед, и есть более элегантное решение.

Пожалуйста, скажите ему более простое решение.

Спасибо.

Битва

CREATE TABLE `battle` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `attacker_id` int(11) NOT NULL DEFAULT 0,
  `defender_id` int(11) NOT NULL DEFAULT 0,
  ...
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=N DEFAULT CHARSET=utf8mb4
 PARTITION BY RANGE (`id`)
(PARTITION `d200412` VALUES LESS THAN (2004130000000000000) ENGINE = InnoDB,
 PARTITION `d200413` VALUES LESS THAN (2004140000000000000) ENGINE = InnoDB,
 PARTITION `d200414` VALUES LESS THAN (2004150000000000000) ENGINE = InnoDB)

Боевая рама

CREATE TABLE `battle_data` (
   `battle_id` bigint(20) NOT NULL DEFAULT 0,
   `frame` tinyint(4) NOT NULL DEFAULT 0,
   `events` blob NOT NULL,
   `add` int(11) NOT NULL DEFAULT 0,
   PRIMARY KEY (`battle_id`,`frame`) USING BTREE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  PARTITION BY RANGE (`battle_id`)
 (PARTITION `d200412` VALUES LESS THAN (2004130000000000000) ENGINE = InnoDB,
  PARTITION `d200413` VALUES LESS THAN (2004140000000000000) ENGINE = InnoDB,
  PARTITION `d200414` VALUES LESS THAN (2004150000000000000) ENGINE = InnoDB)

Планировщик

CREATE DEFINER=`main`@`%` EVENT `battle` ON SCHEDULE EVERY 1 DAY STARTS '2019-07-10 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN

SET @id_base = '%y%m%d';
SET @id_tail = '0000000000000';

SET @add_name = DATE_FORMAT(CURDATE(), @id_base);
SET @add_less = DATE_FORMAT(CURDATE() + INTERVAL 1 DAY, @id_base);

SET @drop_name = DATE_FORMAT(CURDATE() - INTERVAL 3 DAY, @id_base);

SET @sql = CONCAT('ALTER TABLE `battle` ADD PARTITION IF NOT EXISTS (PARTITION d', @add_name, ' VALUES LESS THAN (', @add_less, @id_tail, '))');
PREPARE query FROM @sql; EXECUTE query; DEALLOCATE PREPARE query;

SET @sql = CONCAT('ALTER TABLE `battle` DROP PARTITION IF EXISTS d', @drop_name);
PREPARE query FROM @sql; EXECUTE query; DEALLOCATE PREPARE query;

SET @sql = CONCAT('ALTER TABLE `battle_data` ADD PARTITION IF NOT EXISTS (PARTITION d', @add_name, ' VALUES LESS THAN (', @add_less, @id_tail, '))');
PREPARE query FROM @sql; EXECUTE query; DEALLOCATE PREPARE query;

SET @sql = CONCAT('ALTER TABLE `battle_data` DROP PARTITION IF EXISTS d', @drop_name);
PREPARE query FROM @sql; EXECUTE query; DEALLOCATE PREPARE query;

SET @sql = CONCAT('ALTER TABLE `battle` AUTO_INCREMENT = ', @add_name, @id_tail);
PREPARE query FROM @sql; EXECUTE query; DEALLOCATE PREPARE query;

END

1 Ответ

0 голосов
/ 22 апреля 2020

Заполнение BIGINT и auto_increment, и датой кажется fr agile.

Вам нужен auto_increment вообще? То есть у вас есть какая-то другая уникальная комбинация столбцов?

Предполагается, что у вас есть обычный auto_in c, плюс еще один столбец (dt), который является DATE или DATETIME или TIMESTAMP, вы можете сделать это

PRIMARY KEY(id, dt)

PARTITION BY RANGE (TO_DAYS(dt)) ...

Тогда DROP PARTITION и REORGANIZE PARTITION будут счастливы, и так с auto_in c.

См. http://mysql.rjweb.org/doc.php/partitionmaint для дальнейшего обсуждения, включая вопрос о том, зачем иметь раздел future.

...