I have a MySQL table with an auto increment primary key. I deleted some rows in the middle of the table. Now I have, for example, something like this in the ID column: 12, 1
SET @num := 0;
UPDATE your_table SET id = @num := (@num+1);
ALTER TABLE your_table AUTO_INCREMENT =1;
I think this will do it
The best choice is to alter the column and remove the auto_increment attribute. Then issue another alter statement and put auto_increment back onto the column. This will reset the count to the max+1 of the current rows and thus preserve foreign key references back to this table, from other tables in your database, or any other key usage for that column.
This works - https://stackoverflow.com/a/5437720/10219008.....but if you run into an issue 'Error Code: 1265. Data truncated for column 'id' at row 1'...Then run the following. Adding ignore on the update query.
SET @count = 0;
set sql_mode = 'STRICT_ALL_TABLES';
UPDATE IGNORE web_keyword SET id = @count := (@count+1);
for InnoDB, do this (this will remove all records from a table, make a bakcup first):
SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS ;
SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION ;
SET NAMES utf8 ;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 ;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 ;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' ;
SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 ;
/* ================================================= */
drop table tablename;
CREATE TABLE `tablename` (
table structure here!
) ENGINE=InnoDB AUTO_INCREMENT= ai number to reset DEFAULT CHARSET= char set here;
/* ================================================= */
SET SQL_MODE=@OLD_SQL_MODE ;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS ;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS ;
SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT ;
SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS ;
SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION ;
SET SQL_NOTES=@OLD_SQL_NOTES ;
My opinion is to create a new column called row_order. then reorder that column. I'm not accepting the changes to the primary key. As an example, if the order column is banner_position, I have done something like this, This is for deleting, updating, creating of banner position column. Call this function reorder them respectively.
public function updatePositions(){
$offers = Offer::select('banner_position')->orderBy('banner_position')->get();
$offersCount = Offer::max('banner_position');
$range = range(1, $offersCount);
$existingBannerPositions = [];
foreach($offers as $offer){
$existingBannerPositions[] = $offer->banner_position;
}
sort($existingBannerPositions);
foreach($existingBannerPositions as $key => $position){
$numbersLessThanPosition = range(1,$position);
$freshNumbersLessThanPosition = array_diff($numbersLessThanPosition, $existingBannerPositions);
if(count($freshNumbersLessThanPosition)>0) {
$existingBannerPositions[$key] = current($freshNumbersLessThanPosition);
Offer::where('banner_position',$position)->update(array('banner_position'=> current($freshNumbersLessThanPosition)));
}
}
}
You can also simply avoid using numeric IDs as Primary Key. You could use Country codes as primary id if the table holds countries information, or you could use permalinks, if it hold articles for example.
You could also simply use a random, or an MD5 value. All this options have it's own benefits, specially on IT sec. numeric IDs are easy to enumerate.