Intereting Posts
SQL Несколько столбцов в разделе IN для преобразования в JPA Обновление столбца «заказ» MySQL? Имитировать функцию задержки в MySQL Просмотр переменных в SSIS во время отладки Проблема с SQLite Удалить строку PostgreSQL – вставлять строки на основе выбора из другой таблицы и обновлять FK в этой таблице с вновь вставленными строками Использование SqlCommand, как добавить несколько параметров к его объекту, вставка через winform в таблицу sql SQL – WHERE AGGREGATE> 1 SQL Compact Edition Вставить C # Linux альтернативы Sequel Pro? (Навигатор на основе графического интерфейса пользователя) Объединение нескольких строк в один столбец с использованием функции в Oracle с 3 связанными таблицами Управляющий символ Oracle SQL (для '&') Hibernate – отличные результаты с разбивкой на страницы Как заставить Oracle создавать инструкцию таблицы в SQL * Plus Разделите одну таблицу на несколько таблиц с помощью SQL

Автоматическое увеличение после удаления в MySQL

У меня есть таблица MySQL с полем первичного ключа, на котором включен AUTO_INCREMENT. Прочитав другие сообщения, я заметил людей с одинаковой проблемой и с разными ответами. Некоторые рекомендуют не использовать эту функцию, другие утверждают, что она не может быть «исправлена».

У меня есть:

table: course fields: courseID, courseName 

Пример: количество записей в таблице: 18. Если я удалю записи 16, 17 и 18 – я бы ожидал, что следующая запись будет иметь идентификатор курса 16, однако это будет 19, потому что последний введенный идентификатор курса был 18.

Мои знания SQL не удивительны, но все равно нужно обновить или обновить этот счет с помощью запроса (или настройки в интерфейсе phpMyAdmin)?

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


Учитывая все советы, я решил игнорировать эту «проблему». Я просто удалю и добавлю записи, в то время как автоматическое приращение сделает это. Я думаю, это не имеет большого значения, каково это число, поскольку оно используется только как уникальный идентификатор и не имеет (как упоминалось выше) делового значения.

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

    То, что вы пытаетесь сделать, звучит опасно, поскольку это не предназначено для использования AUTO_INCREMENT .

    Если вы действительно хотите найти наименьшее неиспользованное значение ключа, вообще не используйте AUTO_INCREMENT и управляйте своими ключами вручную. Однако это НЕ рекомендуемая практика.

    Сделайте шаг назад и спросите: « Почему вам нужно перерабатывать значения ключей? ». Если unsigned INT (или BIGINT ) не обеспечивают достаточно большое пространство клавиш?

    У вас действительно будет больше 18,446,744,073,709,551,615 уникальных записей в течение срока вашей заявки?

     ALTER TABLE foo AUTO_INCREMENT=1 

    Если вы удалили самые последние записи, это должно привести к использованию следующей самой низкой доступной. Как и в случае, если уже нет 19, удаление 16-18 приведет к сбросу автоинкремента для использования 16.


    EDIT: Я пропустил бит о phpmyadmin. Вы можете установить его там тоже. Перейдите на экран таблицы и перейдите на вкладку операций. Там есть поле AUTOINCREMENT которое вы можете установить на все, что вам нужно вручную.

    Первичные ключи автоинкремента в базе данных используются для однозначной идентификации данной строки и не должны иметь никакого бизнес- значения. Поэтому оставьте первичный ключ как есть и добавьте еще один столбец, называемый, например, courseOrder . Затем, когда вы удаляете запись из базы данных, вы можете отправить дополнительный оператор UPDATE, чтобы courseOrder столбец courseOrder всех строк, у которых courseOrder больше, чем тот, который вы сейчас удаляете.

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

    Пытаться :

    SET @num: = 0;

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

    ALTER TABLE tableName AUTO_INCREMENT = 1;

    Это приведет к сбросу значения с автоинкрементами, а затем подсчет каждой строки, пока для него будет создано новое значение.

    пример: до

    • 1: первое значение здесь
    • 2: второе значение здесь
    • X: удаленное значение
    • 4: Остальная часть таблицы
    • 5: Остальное остальное ..

    поэтому в таблице будет отображаться массив: 1,2,4,5

    Пример: ПОСЛЕ (если вы используете эту команду, вы получите)

    • 1: первое значение здесь
    • 2: второе значение здесь
    • 3: Остальная часть таблицы
    • 4: остальная часть остального

    Никаких следов удаляемого значения, а оставшаяся часть увеличивается с этим новым счетчиком.

    НО

    1. Если где-то на вашем коде что-то использует автоинкрементное значение … возможно, это атрибуция вызовет проблему.
    2. Если вы не используете это значение в своем коде, все должно быть в порядке.

    Вы не должны полагаться на идентификатор AUTO_INCREMENT, чтобы узнать, сколько записей у вас в таблице. Вы должны использовать SELECT COUNT(*) FROM course . ID, чтобы однозначно идентифицировать курс и могут использоваться как ссылки в других таблицах, поэтому вы не должны повторять идентификаторы и не должны пытаться сбросить поле автоматического приращения.

    вы можете выбрать идентификаторы:

     set @rank = 0; select id, @rank:=@rank+1 from tbl order by id 

    результатом является список идентификаторов и их позиции в последовательности.

    вы также можете сбросить идентификаторы следующим образом:

     set @rank = 0; update tbl a join (select id, @rank:=@rank+1 as rank from tbl order by id) b on a.id = b.id set a.id = b.rank; 

    вы также можете просто распечатать первый неиспользуемый идентификатор так:

     select min(id) as next_id from ((select a.id from (select 1 as id) a left join tbl b on a.id = b.id where b.id is null) union (select min(a.id) + 1 as id from tbl a left join tbl b on a.id+1 = b.id where b.id is null)) c; 

    после каждой вставки вы можете сбросить auto_increment:

     alter table tbl auto_increment = 16 

    или явно установить значение id при выполнении вставки:

     insert into tbl values (16, 'something'); 

    обычно это необязательно, у вас есть count(*) и возможность создания номера ранжирования в ваших результирующих наборах. типичным ранжированием может быть:

     set @rank = 0; select a.name, a.amount, b.rank from cust a, (select amount, @rank:=@rank+1 as rank from cust order by amount desc) b where a.amount = b.amount 

    клиенты оцениваются по затраченной сумме.

    У меня очень простой, но сложный метод.

    При удалении строки вы можете сохранить идентификаторы в другую временную таблицу. После этого, когда вы вставляете новые данные в основную таблицу, вы можете искать и выбирать идентификаторы из временной таблицы. Поэтому используйте проверку здесь. Если временная таблица не имеет идентификаторов, затем вычисляет максимальный идентификатор в основной таблице и устанавливает новый ID как: new_ID = old_max_ID+1 .

    NB: Вы не можете использовать функцию автоматического увеличения.

    Я пришел сюда, чтобы найти ответ на вопрос Title "MySQL - Auto Increment after delete" но я мог только найти ответ на это в вопросах

    • Как удалить определенную строку из таблицы mysql?
    • Как сбросить AUTO_INCREMENT в MySQL?

    Используя что-то вроде:

     DELETE FROM table; ALTER TABLE table AUTO_INCREMENT = 1; 

    Обратите внимание, что ответ Дарина Димитрова очень хорошо объясняет AUTO_INCREMENT и его использование. Взгляните туда, прежде чем делать что-то, о чем вы можете пожалеть.

    PS: Сам вопрос больше "Why you need to recycle key values?" и ответ Дольфа говорит об этом.

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

    То, что вы пытаетесь сделать, очень опасно. Подумайте об этом внимательно. Существует очень веская причина для поведения автоматического приращения по умолчанию.

    Учти это:

    Запись удаляется в одной таблице, которая имеет отношение к другой таблице. Соответствующая запись во второй таблице не может быть удалена для целей аудита. Эта запись становится сиротой из первой таблицы. Если новая запись вставляется в первую таблицу и используется последовательный первичный ключ, эта запись теперь привязана к сироте. Очевидно, это плохо. При использовании автоматической инкрементной PK всегда гарантируется идентификатор, который никогда не использовался раньше. Это означает, что сироты остаются сиротами, что является правильным.

    Я могу придумать множество сценариев, где вам может понадобиться это сделать, особенно во время процесса миграции или разработки. Например, мне просто нужно было создать новую таблицу, перекрестно соединяя две существующие таблицы (как часть сложного процесса настройки), а затем мне нужно было добавить первичный ключ после события. Вы можете удалить существующий столбец первичного ключа, а затем сделать это.

     ALTER TABLE my_table ADD `ID` INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`ID`); 

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

    На самом деле есть способ исправить это. Сначала вы удаляете столбец первичного ключа auto_incremented, а затем добавляете его снова, например:

     ALTER TABLE table_name DROP column_name; ALTER TABLE table_name ADD column_name int not null auto_increment primary key first; 
     if($id == 1){ // deleting first row mysqli_query($db,"UPDATE employees SET id=id-1 WHERE id>1"); } else if($id>1 && $id<$num){ // deleting middle row mysqli_query($db,"UPDATE employees SET id=id-1 WHERE id>$id"); } else if($id == $num){ // deleting last row mysqli_query($db,"ALTER TABLE employees AUTO_INCREMENT = $num"); } else{ echo "ERROR"; } mysqli_query($db,"ALTER TABLE employees AUTO_INCREMENT = $num"); 

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

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

    Это определенно не рекомендуется. Если у вас есть большая база данных с несколькими таблицами, возможно, вы сохранили идентификатор пользователя как id в таблице 2. Если вы измените таблицу 1, то, вероятно, предполагаемый идентификатор пользователя не будет являться предполагаемой таблицей 2 id.

    вот функция, которая исправляет вашу проблему

      public static void fixID(Connection conn, String table) { try { Statement myStmt = conn.createStatement(); ResultSet myRs; int i = 1, id = 1, n = 0; boolean b; String sql; myRs = myStmt.executeQuery("select max(id) from " + table); if (myRs.next()) { n = myRs.getInt(1); } while (i <= n) { b = false; myRs = null; while (!b) { myRs = myStmt.executeQuery("select id from " + table + " where id=" + id); if (!myRs.next()) { id++; } else { b = true; } } sql = "UPDATE " + table + " set id =" + i + " WHERE id=" + id; myStmt.execute(sql); i++; id++; } } catch (SQLException e) { e.printStackTrace(); } }