Что может ограничить значение столбца индекса автоинкремента в таблице MYSQL от достижения чрезмерного размера? - PullRequest
1 голос
/ 07 октября 2019

Что мешает значению индекса автоинкремента в MYSQL достичь астрономического размера, когда записи постоянно добавляются и удаляются из таблицы? Что должно предотвратить его неограниченное увеличение до тех пор, пока не будет достигнут предел размера поля? В настоящее время я делаю это, удаляя и повторно добавляя столбец индекса каждый раз, когда добавляется запись, но я беспокоюсь о проблемах, которые это может вызвать, когда существует несколько пользователей таблицы одновременно. Я хочу сохранить размер таблицы на уровне 30 самых последних записей, поэтому я удаляю запись с id = 1 каждый раз, когда добавляется новая запись, затем удаляю и повторно добавляю столбец индекса, чтобы сбросить индекс. Не существует внешних ключей или другого кода, который использует значение индекса, поэтому изменение связи между значением индекса и строкой не представляет проблемы. Это мой текущий php код:

if ($count > 30) {
$sql = "DELETE FROM news WHERE id=1";

if (mysqli_query($con, $sql)) {
}
$deletecolumn= mysqli_query($con,"ALTER TABLE news DROP id");
$added= mysqli_query($con,"ALTER TABLE news ADD id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;");
}

Есть ли лучший способ сделать это?

Ответы [ 3 ]

3 голосов
/ 07 октября 2019

Вероятно, было бы лучше создать HASH из данных и использовать его в качестве первичного ключа, иначе лучше подходит объединенный первичный ключ.

Чтобы сохранить максимальное количество записей Х, вам понадобится временная метка. После добавления одного вы можете удалить самый старый. Вы можете запустить cron для удаления старых.

Затем вы можете использовать:

SELECT `col1`, `col2` FROM `mytable` ORDER BY `added_timestamp` DESC LIMIT 30

UPDATE: Удаление после 30 самых новых будет:

DELETE FROM `mytable` WHERE `added_timestamp` NOT IN (SELECT `d2`.`added_timestamp` FROM `d2`.`mytable` AS `d2` ORDER BY `d2`.`added_timestamp` DESC LIMIT 30)

Однако этот запрос не так эффективно выполнять после каждой вставки. Я бы запустил его в cron.

Другой способ - удалить один за другим после вставки:

DELETE FROM `mytable` ORDER BY `added_timestamp` ASC LIMIT 1

Но у вас могут возникнуть проблемы с параллельным запуском.

0 голосов
/ 07 октября 2019

Если вы беспокоитесь о достижении максимального размера, который может представлять целое число, вы можете использовать bigint без знака вместо int.

Это типы целых чисел, доступные вам в MySQL:

TINYINT            - 127
UNSIGNED TINYINT   - 255
SMALLINT           - 32767
UNSIGNED SMALLINT  - 65535
MEDIUMINT          - 8388607
UNSIGNED MEDIUMINT - 16777215
INT                - 2147483647
UNSIGNED INT       - 4294967295
BIGINT             - 9223372036854775807
UNSIGNED BIGINT    - 18446744073709551615

Кроме того, из соображений производительности следует избегать изменения и удаления каждой вставки. В качестве альтернативы, вы можете просто вставить всякий раз, когда есть новая запись и позволить увеличить идентификатор. Если вы хотите 30 самых последних строк, выберите их по убыванию идентификатора и ограничьте до 30.

select * from news order by id desc limit 30

Один раз в день или по некоторому расписанию вы можете выполнить очистку, чтобы удалить все, кроме самых последних 30,если они не представляют для вас исторической ценности.

Например:

DELETE FROM `news`
WHERE id NOT IN (
  SELECT id
  FROM (
    SELECT id
    FROM `news`
    ORDER BY id DESC
    LIMIT 30 
  )
);
0 голосов
/ 07 октября 2019

У вас есть как минимум две опции:

1) использовать BIGINT вместо INT с атрибутом UNSIGNED

Максимальное значение дляполе без знака BIGINT равно 26 4 -1, может быть очень трудно достичь его предела.

2) удалить поле идентификатора и создать свой собственный уникальный идентификатор для каждой строки

Выполните этот запрос один раз, и он будет выполнен:

ALTER TABLE news MODIFY COLUMN id BIGINT AUTO_INCREMENT;
...