Использовать метод queryset object update
:
MyModel.objects.filter(pk=some_value).update(field1='some value')
ALTER TABLE foo AUTO_INCREMENT=1
Если вы удалили самые последние записи, это должно заставить его использовать следующую самую низкую доступную. Как и в случае, если уже нет 19, удаление 16-18 приведет к сбросу автоинкремента для использования 16.
EDIT: я пропустил бит о phpmyadmin. Вы можете установить его там тоже. Перейдите на экран таблицы и перейдите на вкладку операций. Там есть поле AUTOINCREMENT
, в котором вы можете установить все, что вам нужно вручную.
То, что вы пытаетесь сделать, звучит опасно, поскольку это не намеренное использование AUTO_INCREMENT
.
Если вы действительно хотите найти наименьшее неиспользованное значение ключа, не используйте AUTO_INCREMENT
и управлять своими ключами вручную.
Сделайте шаг назад и спросите «, почему вам нужно перерабатывать значения ключей? » Делать unsigned INT
(или BIGINT
) не обеспечивают достаточно большое пространство для ключей?
На самом деле вы будете иметь больше 18,446,744,073,709,551,615
уникальных записей за всю жизнь вашего приложения?
То, что вы пытаетесь сделать, очень опасно. Подумайте об этом внимательно. Существует очень веская причина для поведения автоматического приращения по умолчанию.
Рассмотрим это:
Запись удаляется в одной таблице, которая имеет отношение к другой таблице. Соответствующая запись во второй таблице не может быть удалена для целей аудита. Эта запись становится сиротой из первой таблицы. Если новая запись вставляется в первую таблицу и используется последовательный первичный ключ, эта запись теперь привязана к сироте. Очевидно, это плохо. При использовании автоматической инкрементной PK всегда гарантируется идентификатор, который никогда не использовался раньше. Это означает, что сироты остаются сиротами, что является правильным.
Я пришел сюда, чтобы найти ответ на вопрос Title "MySQL - Auto Increment after delete"
, но я мог найти ответ для этого в вопросах
Используя что-то вроде:
DELETE FROM table;
ALTER TABLE table AUTO_INCREMENT = 1;
< hr> Обратите внимание, что ответ Дарина Димитрова очень хорошо объясняет AUTO_INCREMENT
и его использование. Взгляните туда, прежде чем делать что-то, о чем вы могли бы пожалеть.
PS: Сам вопрос больше "Why you need to recycle key values?"
и . Ответ Dolph охватывает это.
здесь функция, которая исправляет вашу проблему
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();
}
}
Первичные ключи автоинкремента в базе данных используются для однозначной идентификации данной строки и не должны иметь никакого значения business . Поэтому оставьте первичный ключ как есть и добавьте другой столбец, названный, например, courseOrder
. Затем, когда вы удаляете запись из базы данных, вы можете отправить дополнительный оператор UPDATE для уменьшения столбца courseOrder
всех строк, у которых courseOrder
больше, чем тот, который вы сейчас удаляете.
В качестве побочной заметки вы никогда не должны изменять значение первичного ключа в реляционной базе данных, потому что могут быть другие таблицы, которые ссылаются на него как на внешний ключ, и его изменение может нарушать ссылочные ограничения.
count
aggregate выполнит эту работу.
– Darin Dimitrov
6 February 2010 в 19:39
Вы можете подумать о создании триггера после удаления, чтобы вы могли обновить значение автоинкремента и значение идентификатора для всех строк, которое не похоже на то, что вы хотели видеть.
Таким образом, вы можете работать с одна и та же таблица и автоматическое приращение будут исправлены автоматически, всякий раз, когда вы удалите строку, триггер зафиксирует ее.
Это определенно не рекомендуется. Если у вас есть большая база данных с несколькими таблицами, возможно, вы, вероятно, сохранили идентификатор пользователя как id в таблице 2. Если вы измените таблицу 1, то, вероятно, предполагаемый идентификатор пользователя не станет целевой таблицей 2 id.
У меня очень простой, но хитрый метод.
При удалении строки вы можете сохранить идентификаторы в другую временную таблицу. После этого, когда вы вставляете новые данные в основную таблицу, вы можете искать и выбирать идентификаторы из временной таблицы. Поэтому используйте проверку здесь. Если временная таблица не имеет идентификаторов, затем вычисляет максимальный идентификатор в основной таблице и устанавливает новый идентификатор следующим образом: new_ID = old_max_ID+1
.
Примечание: здесь нельзя использовать функцию автоматического увеличения.
Вы не должны полагаться на идентификатор AUTO_INCREMENT, чтобы узнать, сколько записей у вас в таблице. Вы должны использовать SELECT COUNT(*) FROM course
. ID, чтобы однозначно идентифицировать курс и могут использоваться как ссылки в других таблицах, поэтому вы не должны повторять идентификаторы и не должны пытаться сбросить поле автоматического приращения.
Я могу придумать множество сценариев, где вам может понадобиться это сделать, особенно во время процесса миграции или разработки. Например, мне просто нужно было создать новую таблицу, перекрестно соединяя две существующие таблицы (как часть сложного процесса настройки), а затем мне нужно было добавить первичный ключ после события. Вы можете удалить существующий столбец первичного ключа, а затем сделать это.
ALTER TABLE my_table ADD `ID` INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`ID`);
Для живой системы это не очень хорошая идея, особенно если есть другие таблицы с внешними ключами, указывающими на нее.
Попробуйте:
SET @num: = 0;
UPDATE your_table SET id = @num: = (@ num + 1);
ALTER TABLE
blockquote>tableName
AUTO_INCREMENT = 1;Это приведет к сбросу значения автоинкремента, а затем подсчет каждой строки, пока для него будет создано новое значение.
пример: before
- 1: первое значение здесь
- 2: второе значение здесь
- X: удаленное значение
- 4 : Остальная часть таблицы
- 5: Остальная часть остального ..
, поэтому в таблице будет отображаться массив: 1,2,4,5
Пример: ПОСЛЕ (если вы используете эту команду, вы получите)
- 1: первое значение здесь
- 2: второе значение здесь
- 3: Остальная часть таблицы
- 4: остальная часть остального
Нет следа удаляемого значения, а остальная часть приращения продолжается с помощью этого новый счет.
BUT
- Если где-то на вашем коде что-то использует автоинкрементное значение ... возможно, это атрибуция вызовет проблему.
- Если вы не используете это значение в своем коде, все должно быть в порядке.
Вы можете использовать клиентское программное обеспечение / скрипт mysql, чтобы указать, где должен начинаться первичный ключ после удаления необходимых записей.
На самом деле есть способ исправить это. Сначала вы удаляете столбец первичного ключа автоматического увеличения, а затем добавляете его снова, например:
ALTER TABLE table_name DROP column_name;
ALTER TABLE table_name ADD column_name int not null auto_increment primary key first;
вы можете выбрать такие идентификаторы:
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;
вы также можете просто распечатать первый неиспользуемый id следующим образом:
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
клиентов, оцененных по затраченной сумме.
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");