简体   繁体   中英

What can limit the value of the autoincrement index column in a MYSQL table from reaching excessive size?

What is to prevent the value of an auto-increment index in MYSQL from reaching astronomical size when records are constantly being added to and deleted from the table? What is to prevent it from increasing without limit until the size limit of the field is reached? Currently, I am doing it by deleting and re-adding the index column every time a record is added, but I am worried about the problems this could cause when there are multiple simultaneous users of the table. I wish to maintain the size of the table at the 30 most recent records, so I delete the record with id=1 each time a new record is added, then delete and re-add the index column in order to reset the index. There are no foreign keys or other code that uses the index value, so changing the association between the index value and the row does not represent a problem. This is my current php code:

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;");
}

Is there a better way to do this?

Probably it would be better to create a HASH from the data and use it as a primary key or a concatenated primary key might suit better.

To maintain the top X number of records, you would need a timestamp. After you add one you can delete the oldest. You could run a cron for deleting the older ones.

You can then use:

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

UPDATE: Deleting after the 30 newest would be:

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)

However, this query is not that efficient to run after every insert. I would run it in a cron.

Another way is to delete one by after insert:

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

But you might run into issues with parallel running it.

You have at least two options:

1) use BIGINT instead of INT , with the UNSIGNED attribute

The maximum value for an unsigned BIGINT field is 26 4 -1, may be very difficult to reach its limit.

2) remove the ID field and create your custom unique identifier for each rows

Execute this query once and its done:

ALTER TABLE news MODIFY COLUMN id BIGINT AUTO_INCREMENT;

If you are concerned about hitting the maximum size that in integer can represent, you could use an unsigned bigint instead of an int.

These are the integer types available to you in 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

Also, you should avoid doing an alter able and a delete on every insert for performance reasons. As an an alternative, you could just insert whenever there is a new record and allow the id to increase. When you want the 30 most recent rows, select by descending id, and limit to 30.

select * from news order by id desc limit 30

Once a day or on some schedule, you could do a cleanup to delete all but the most recent 30, if they are of no historic value to you.

For example:

DELETE FROM `news`
WHERE id NOT IN (
  SELECT id
  FROM (
    SELECT id
    FROM `news`
    ORDER BY id DESC
    LIMIT 30 
  )
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM