Сделать MySQL автоинкрементный идентификатор (пере) начать с 1 - PullRequest
7 голосов
/ 10 декабря 2010

"БОЛЬШОЕ" ОБНОВЛЕНИЕ:

Хорошо, я неправильно понял всю точку автоинкремента.Я думаю, что это был бы более простой способ нацеливания на первый, второй, третий и т. Д. Ряды, но это просто неправильный подход.

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

Я не буду удалять этот вопрос, потому что я думаю, что это может быть полезно для кого-то с той же ошибочной идеей, НО БУДЕТ ПРЕДУПРЕЖДЕНО! :)


У меня есть очень простая таблица MySQL, которая выглядит следующим образом:

id    comment    user

1     hello      name1
2     bye        name2
3     hola       name3

Затем я удалил два первых комментария, результат:

id    comment    user

3     hola      name3

Итактеперь, когда я добавляю комментарии:

id    comment    user

3     hola      name3
5     chau      name4
6     xxx       name5

Моя проблема в том, что мне нужно, чтобы всякий раз, когда строка удалялась, она "начиналась заново" и выглядела так:

id    comment    user

1     hola      name3
2     chau      name4
3     xxx       name5

Я быхотелось бы узнать, как это возможно для некоторых, как «перезапустить» таблицу, чтобы она «всегда» индексировалась 1, 2, 3 и т. д.

Заранее спасибо !!


Надеюсь, я объяснил себя достаточно ясно, извините за все мои "простые знания английского", не стесняйтесь редактировать, если вы считаете, что слово может сбить с толку :) и, пожалуйста, попросите пояснений!

Кстати: я не добавил ни один из своего кода, потому что это упрощенная ситуация, и я, хотя это будет более запутанными менее полезны для других, но я думаю, что это поможет (или будет необходимо) рассказать мне об этом!

Ответы [ 10 ]

8 голосов
/ 06 июля 2011

Если нет проблем с внешним ключом, этот код сделает это:

set @id:=0;
update mytable
set id = (@id := @id + 1)
order by id;

Если есть проблемы с внешним ключом, убедитесь, что ваши ограничения определены следующим образом: до того, как запустите обновление:

ALTER CHILD_TABLE ADD CONSTRAINT
FOREIGN KEY MYTABLE_ID REFERENCES MYTABLE
ON UPDATE CASCADE; -- This is the important bit

Когда все будет сделано, выполните это, чтобы исправить значение auto_increment:

SELECT MAX(ID) + 1 FROM MYTABLE; -- note the output
ALTER TABLE MYTABLE AUTO_INCREMENT = <result from above>;
5 голосов
/ 10 декабря 2010

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

Вы могли бы использовать это действительно безобразное решение, пожалуйста, делайте это, только если вы находитесь под дулом пистолета или ваша собака находится в заложниках!

-- Create a new veriable.
SET @newId:=0;

-- Set all id's in the table to a new one and
-- also increment the counter in the same step.
-- It's basically just setting id to ++id.
UPDATE
    yourTableHere
SET
    id=@newId:=@newId+1;

-- Now prepare and execute an ALTER TABLE statement
-- which sets the next auto-increment value.
SET @query:=CONCAT("ALTER TABLE yourTableHere AUTO_INCREMENT=", @newId+1);
PREPARE sttmnt FROM @query;            
EXECUTE sttmnt;
DEALLOCATE PREPARE sttmnt;  

Это сбросит все идентификаторы в положение строки в таблице. Имейте в виду, что это приведет к изменению порядка строк в соответствии с тем, как MySQL получает их из механизма хранения, поэтому никакой гарантии порядка в любом случае нет.

Если у вас есть система, основанная на идентификаторах (например, отношения между таблицами), тогда вы ... ну, скажем, я надеюсь, у вас есть резервная копия.

3 голосов
/ 10 декабря 2010

Не может быть сделано с помощью функции автоинкремента MySQL. Вы можете свернуть свое собственное решение, например, смесь логики приложения и триггеров базы данных. НО, серьёзно, ваш дизайн сильно сломан, если вам потребуется переработать УНИКАЛЬНЫЕ ID.

Не могли бы вы просто создать другую таблицу, в которой вы бы сохранили подобные ссылки (это можно сделать, запросив минимум), и позволить вашей основной таблице указать на эту вспомогательную таблицу?

EDIT
Вот блог, который я погуглил, который решает вашу проблему: см. Здесь .

1 голос
/ 10 декабря 2010

Это не цель AUTO_INCREMENT.Он существует для генерации уникальных идентификаторов, а не для поддержания последовательности без пропусков.

Если у вас есть веская причина для этого, то сгенерируйте идентификаторы самостоятельно в своем коде.AUTO_INCREMENT не предоставит это вам.

0 голосов
/ 07 мая 2017
<code>    function backup_tables($host, $user, $pass, $dbname, $tables = '*'){

    $connect = mysqli_connect($host, $user, $pass , $dbname);

     mysqli_query($connect, "SET NAMES 'utf8'");


    //get all of the tables
    if($tables == '*'){
        $tables = array();
        $result = mysqli_query($connect, 'SHOW TABLES');
        while($row = mysqli_fetch_row($result))
        {
            $tables[] = $row[0];
        }
    }
    else
    {
        $tables = is_array($tables) ? $tables : explode(',',$tables);
    }

    foreach($tables as $table){
        $table = trim($table);
    // getting all table fields
    $tblDetails = mysqli_query($connect,"SHOW FULL COLUMNS FROM $table");

    // we may need to know how to create our table
    $tblCreate = mysqli_fetch_row(mysqli_query($connect, 'SHOW CREATE TABLE '.$table));

    // getting last line from table creation script in order to get info about engine ->suffix1
    $suffix1 = end(explode(PHP_EOL,$tblCreate[1]));

        // if there is auto increment we have to remove
        if (strpos($suffix1,"AUTO_INCREMENT")){ 
            $tmpArr = explode(" ",$suffix1);
            $newStr = '';
            foreach ($tmpArr as $term){
                if (!is_int(strpos($term, "AUTO_INCREMENT"))) $newStr .= $term . ' '; else $suffix4 = $term; // suffix4 stores next value of auto_increment 
            }
            $suffix1 = $newStr;
        } // now if there is auto_increment we removed from the last line of creation table script


        $return .= "DROP TABLE IF EXISTS `".$table."` CASCADE;\n\n";

     // starting creation table with our rules
        $kgbReturn = "CREATE TABLE `$table` (\n";


        while($cols = mysqli_fetch_row($tblDetails )){

            if ($cols[2]) $cols[2] = " COLLATE " . $cols[2]; //if a charset defined add to line
            if ($cols[3]=='NO') $cols[3] = " NOT NULL"; // if the field may be null 

            $kgbReturn .= "`".$cols[0]."` ".$cols[1]. $cols[2] . $cols[3]. ",\n"; //field creation line ready
        }


        $kgbReturn = rtrim($kgbReturn,",\n") . "\n" .trim($suffix1," ") . ";\n\n"; // table creation without auto_increment


        $tblDetails = mysqli_query($connect,"SHOW FULL COLUMNS FROM $table WHERE (`Key` LIKE 'PRI%')");
        $suffix2 = '';
        while($cols = mysqli_fetch_row($tblDetails )){
            $suffix2 .= "ALTER TABLE `". $table ."` \n ADD PRIMARY KEY (`".$cols[0]."`);\n\n";
        }


        $tblDetails = mysqli_query($connect,"SHOW FULL COLUMNS FROM $table WHERE (Extra LIKE 'auto_increment%')");
        $suffix3 = '';
        while($cols = mysqli_fetch_row($tblDetails )){
            $suffix3 = "ALTER TABLE `". $table ."` \n ADD PRIMARY KEY (`".$cols[0]."`);\n\n";
            $suffix3 = "ALTER TABLE `".$table."` \n MODIFY `".$cols[0]."` ".$cols[1]." NOT NULL AUTO_INCREMENT, ".$suffix4.";";
        }






        $return .= $kgbReturn;

        $result = mysqli_query($connect, 'SELECT * FROM '.$table);
        $num_fields = mysqli_num_fields($result);

        // insert into all values 
        for ($i = 0; $i < $num_fields; $i++){

            while($row = mysqli_fetch_row($result)){

                $return .= 'INSERT INTO '.$table.' VALUES(';

                for($j=0; $j < $num_fields; $j++){
                    $row[$j] = addslashes($row[$j]);
                    $row[$j] = str_replace (array("\r\n", "\n", "\r", PHP_EOL), '\r', $row[$j])
    ;

                    if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return .= '""'; }
                    if ($j < ($num_fields-1)) { $return .= ','; };
                }
                $return .= ");\n";
            }
        }
        $return .= "\n\n"; // insert values completed. 


        // now add primary key and auto increment statements if exist 
        $return .= $suffix2 . $suffix3 . "\n\n\n";  


        echo "<pre>".$return ."
"; // строка отладки. Комментируйте, если вам не нравится. } // нам нужно записать в файл, который закодирован как utf-8 $ bkTime = дата ('Y_m_j_H_i_s'); $ fileName = 'backup-db -'. $ bkTime. '. sql'; $ F = Еореп ($ имя_файла, "ш"); # Теперь UTF-8 - Добавить метку порядка байтов fwrite ($ f, pack ("CCC", 0xef, 0xbb, 0xbf)); FWRITE ($ е, $ возврата); fclose ($ е); }
0 голосов
/ 17 ноября 2013
ALTER TABLE event AUTO_INCREMENT = 1;
0 голосов
/ 21 января 2013
 update table_name set id =NULL; alter table table_name change column
 `id` `id` int auto_increment;
0 голосов
/ 10 декабря 2010

Акцентно, автоинкремент сделан для того, чтобы увеличить, независимо от количества строк.

Таблица ALTER TABLE AUTO_INCREMENT = 1 выполняет сброс, но вы можете получить некоторые плохие вещи, если ID начнет повторяться.

Итак, мой совет: оставьте его в покое:)

0 голосов
/ 10 декабря 2010

Возможно, ваш подход к решению, которое вы пытаетесь достичь, не верен, поскольку то, что вы пытаетесь достичь, невозможно «автоматически», а выполнение вручную, когда у вас есть тысячи строк, приведет к задержке системы .

Действительно ли необходимо, чтобы система настраивалась при каждом удалении?

0 голосов
/ 10 декабря 2010

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

Тем не менее, вот способ (см. Верхний комментарий) делать именно то, что вы хотите.

Для тех, кто хочет «сбросить» auto_increment, скажем, в списке, в котором было несколько удалений, и вы хотите изменить нумерацию всего, вы можете сделать следующее.

УДАЛИТЬ поле, к которому вы автоматически добавляете.
Измените таблицу, чтобы снова добавить поле с теми же атрибутами.

Вы заметите, что все существующие строки перенумерованы, и следующий номер auto_increment будет равен числу строк плюс 1.

(Имейте в виду, что ОТКЛЮЧЕНИЕ этого столбца удалит все существующие данные, поэтому, если у вас есть внешние ресурсы, которые полагаются на эти данные, или числа, которые уже там, вы можете разорвать связь. Также, как и с любой основной структурой изменение, это хорошая идея сделать резервную копию вашей таблицы, прежде чем вы внесете изменения.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...