Zmiana kolejności / reset auto increment klucz podstawowy

Mam tabelę MySQL z automatycznym przyrostem klucza podstawowego. Usunąłem kilka wierszy na środku tabeli. Teraz mam na przykład coś takiego w kolumnie ID: 12, 13, 14, 19, 20. Usunąłem wiersze 15, 16, 17 i 18.

Chcę ponownie przypisać / zresetować / zmienić kolejność klucza podstawowego tak, że mam ciągłość, tj. zrobić 19 a 15, 20 a 16, i tak dalej.

Jak mogę to zrobić?

Author: Pang, 2009-04-11

15 answers

Możesz upuścić kolumnę klucza głównego i utworzyć ją ponownie. Wszystkie identyfikatory należy następnie przypisać w kolejności.

Jednak jest to prawdopodobnie zły pomysł w większości sytuacji. Jeśli masz inne tabele, które mają obce Klucze do tej tabeli, to na pewno nie będzie działać.

 99
Author: Tom Haigh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 13:42:34

Mimo, że to pytanie wydaje się być dość stare, zamieści odpowiedź dla kogoś, kto sięga tutaj szukając.

SET @count = 0;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;

Jeśli kolumna jest używana jako klucz obcy w innych tabelach, upewnij się, że używasz ON UPDATE CASCADE zamiast domyślnego ON UPDATE NO ACTION dla relacji klucza obcego w tych tabelach.

Ponadto, aby zresetować licznik AUTO_INCREMENT, możesz natychmiast wydać następującą instrukcję.

ALTER TABLE `users` AUTO_INCREMENT = 1;

Dla MySQL resetuje wartość na MAX(id) + 1.

 365
Author: Anshul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 04:17:09

Aby zresetować identyfikatory mojej tabeli User, używam następującego zapytania SQL. Zostało powiedziane powyżej, że zrujnuje to wszelkie relacje, które możesz mieć z innymi tabelami.

ALTER TABLE `users` DROP `id`;
ALTER TABLE `users` AUTO_INCREMENT = 1;
ALTER TABLE `users` ADD `id` int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
 64
Author: Ryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-25 23:19:19

Możesz po prostu użyć tego zapytania

alter table abc auto_increment = 1;
 32
Author: Aaron W.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-01 13:19:02
SET  @num := 0;

UPDATE your_table SET id = @num := (@num+1);

ALTER TABLE your_table AUTO_INCREMENT =1;

Myślę, że to da radę

 16
Author: bagyei37,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-12 10:48:45

Lub, z PhpMyAdmin, Usuń flagę "AutoIncrement", Zapisz, ustaw ją ponownie i zapisz.to go zresetuje.

 12
Author: lbrutti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-27 15:36:05
SELECT * from `user` ORDER BY `user_id`; 

SET @count = 0;

UPDATE `user`  SET `user_id` = @count:= @count + 1;

ALTER TABLE `user_id` AUTO_INCREMENT = 1;

If you want to order by

 3
Author: Shubham Malik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-12 09:47:57

W phpmyadmin

Uwaga: to zadziała, jeśli usuniesz ostatnie wiersze, a nie wiersze środkowe.

Goto twoja tabela - > kliknij menu Operacje - > goto opcje tabeli - > Zmień AUTO_INCREMENT na to nie od miejsca, w którym chcesz zacząć.

Twoja tabela autoincrement zaczyna się od tego nie.

Spróbuj. Tutaj wpisz opis obrazka

 1
Author: Anjani Barnwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-27 14:00:13

To działa - https://stackoverflow.com/a/5437720/10219008.....but Jeśli napotkasz problem 'kod błędu: 1265. Dane obcięte dla kolumny " id "w wierszu 1"...Następnie uruchom następujące. Dodawanie ignoruj w zapytaniu o aktualizację.

SET @count = 0;
set sql_mode = 'STRICT_ALL_TABLES';
UPDATE IGNORE web_keyword SET id = @count := (@count+1);
 1
Author: Anush B M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-13 07:43:36

Możesz usunąć funkcję automatycznego zwiększania klucza podstawowego tej kolumny, a następnie za każdym razem, gdy aktualizujesz tę kolumnę, Uruchom zapytanie przed ręką, które będzie liczyć wszystkie wiersze w tabeli, a następnie uruchom pętlę, która powtarza liczbę wierszy wstawiając każdą wartość do odpowiedniego wiersza, a na koniec uruchom zapytanie wstawiając nowy wiersz z wartością tej kolumny jest całkowita liczba wierszy plus jeden. Będzie to działać bezbłędnie i jest najbardziej absolutnym rozwiązaniem dla kogoś, kto próbuje osiągnąć to, co Ty są. Oto przykład kodu, którego możesz użyć dla funkcji:

$table_row_count = mysql_result(mysql_query("SELECT COUNT(`field_1`) FROM `table`"), 0);
$viewsrowsdata = mysql_query("
    SELECT `rank`, `field1`, `field2`, `field3`, `field4`
        FROM (SELECT (@rank:=@rank+1) as `rank`, `field1`, `field2`, `field3`, `field4`
            FROM (SELECT * FROM `views`) a
            CROSS JOIN (SELECT @rank:=0) b
            ORDER BY rank ASC) c
");
while ($row = mysql_fetch_assoc($viewsrowsdata)) {
    $data[] = $row;
}
foreach ($data as $row) {
    $new_field_1 = (int)$row['rank'];
    $old_field_1 = (int)$row['field1'];
    mysql_query("UPDATE `table` SET `field_1` = $new_field_1 WHERE `field_1` = $old_field_1");
}
mysql_query("INSERT INTO `table` (`field1`, `field2`, `field3`, `field4`) VALUES ('$table_row_count' + 1, '$field_2_value', 'field_3_value', 'field_4_value')");

Tutaj utworzyłem tablicę asocjacyjną, którą dodałem do kolumny rank z zapytaniem w ramach zapytania select, które nadawało każdemu wierszowi wartość rank zaczynającą się od 1. Następnie przeszedłem przez tablicę asocjacyjną.

Inną opcją byłoby pobranie liczby wierszy, uruchomienie podstawowego zapytania select, pobranie tablicy asocjacyjnej i iteracja jej w ten sam sposób, ale z dodaną zmienną, która aktualizuje się za pomocą każdego iteracja. Jest to mniej elastyczne, ale osiągnie to samo.

$table_row_count = mysql_result(mysql_query("SELECT COUNT(`field_1`) FROM `table`"), 0);
$viewsrowsdata = mysql_query("SELECT * FROM `table`");
$updated_key = 0;
while ($row = mysql_fetch_assoc($viewsrowsdata)) {
    $data[] = $row;
}
foreach ($data as $row) {
    $updated_key = $updated_key + 1;
    mysql_query("UPDATE `table` SET `field_1` = '$updated_key' WHERE `field_1` = '$row['field_1']'");
}
mysql_query("INSERT INTO `table` (`field1`, `field2`, `field3`, `field4`) VALUES ('$table_row_count' + 1, '$field_2_value', 'field_3_value', 'field_4_value')");
 0
Author: willy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-29 14:13:00

Dla InnoDB, zrób to (spowoduje to usunięcie wszystkich rekordów z tabeli, utworzenie bakcup):

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 ;
 0
Author: Luis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-25 19:22:37

Miałem te same wątpliwości, ale nie mogłem wprowadzić żadnych zmian w tabeli, zdecydowałem, że wykonując następujące czynności, widząc mój identyfikator nie przekroczył maksymalnej liczby ustawionej w zmiennej @count:

SET @count = 40000000;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;

SET @count = 0;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;

ALTER TABLE `users` AUTO_INCREMENT = 1;

Rozwiązanie wymaga, ale jest bezpieczne i było konieczne, ponieważ moja tabela posiadała klucze obce z danymi w innej tabeli.

 0
Author: Rodrigo Prazim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-04 06:24:56

Najlepszym wyborem jest zmiana kolumny i usunięcie atrybutu auto_increment. Następnie wydaj kolejną instrukcję alter i umieść auto_increment z powrotem na kolumnie. Spowoduje to zresetowanie liczby do max + 1 bieżących wierszy, a tym samym zachowanie odniesień do kluczy obcych z powrotem do tej tabeli, z innych tabel w bazie danych lub innego użycia klucza dla tej kolumny.

 0
Author: Grwww,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-09 18:36:53

Moim zdaniem należy utworzyć nową kolumnę o nazwie row_order. więc zmień kolejność tej kolumny. Nie akceptuję zmian w głównym kluczu. Jako przykład, jeśli kolumna kolejności to banner_position, zrobiłem coś takiego, to jest do usuwania, aktualizacji, tworzenia kolumny pozycji banera. Wywołanie tej funkcji odpowiednio je uporządkować.

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)));
        }
    }
}
 0
Author: Viraj Amarasinghe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-29 08:47:09

Można również po prostu uniknąć używania identyfikatorów numerycznych jako klucza podstawowego. Możesz użyć kodów krajów jako głównego identyfikatora, jeśli tabela zawiera informacje o krajach lub możesz użyć linków stałych, jeśli zawiera na przykład artykuły.

Możesz również po prostu użyć losowej lub wartości MD5. Wszystkie te opcje mają swoje własne zalety, szczególnie na nim sec. numeric IDs są łatwe do wyliczenia.

 -2
Author: Chris Russo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-30 02:35:49