Могу ли я иметь условие для запроса таблицы обрезания в последней версии mysql? [Дубликат]

Использовать метод queryset object update :

MyModel.objects.filter(pk=some_value).update(field1='some value')

57
задан halfer 16 July 2015 в 12:10
поделиться

16 ответов

ALTER TABLE foo AUTO_INCREMENT=1

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


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

62
ответ дан Michel Ayres 16 August 2018 в 02:24
поделиться
  • 1
    ОП МОЖЕТ это сделать, но не должен. Вы должны действительно пересмотреть этот совет, учитывая то, что пытается сделать OP. – Mike Sherov 6 February 2010 в 19:33
  • 2
    Вы правы. Лучше проигнорировать это. Учитывая это только для задания, я не буду входить в большие числа, и жизнь очень короткая. – OmidTahouri 6 February 2010 в 20:05
  • 3
    Это не мое место, чтобы сказать ему, как выложить свою базу данных или как сделать свою бизнес-логику. Он также упомянул в своем посте, что он читает другие сообщения / страницы, в которых говорится, что это плохая идея, поэтому он знает, что это не рекомендуемая практика, но в любом случае продолжит ее. – monksp 6 February 2010 в 20:17
  • 4
    соглашаются очень опасно по ряду причин. Во-первых, в многопользовательской системе у вас может быть много, сотни, тысячи обновлений в секунду и попытка переписать auto inc может либо замедлить работу системы, либо скомпрометировать ее. Двое других разработчиков не знали бы, что вы были = делаете это, возможно, и записываете записи через идентификатор, чтобы развратить систему. и т.п. – PurplePilot 6 February 2010 в 20:25
  • 5
    Это самый прямой ответ, который в настоящее время предоставляется прямому вопросу айзера. Нет никакого «совета». участвует. – Air 12 July 2013 в 16:10
  • 6
    В целом хорошая «практика» хотя также советуем не использовать ваше решение, если у вас есть причины, против которых мог бы пропустить OP. – ToBe 19 May 2014 в 15:53
  • 7
    Хотя это является плохой практикой, это лучший ответ, потому что он отвечает на то, что спросил ОП – Jojodmo 8 July 2015 в 23:03
  • 8
    Хорошие моменты. Ответ заставил меня подумать дважды. Я для одного не искал пробелов в auto_incr. потому что я собирался каким-то образом перебирать идентификаторы. Но я думаю, что лучше просто прокрутить строки :) – Nils Sens 10 October 2016 в 21:35
  • 9
    Так что это просто невозможно? Существуют веские причины для этого в тестовой среде. – Michael 15 September 2017 в 18:25

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

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

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

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

62
ответ дан Michel Ayres 16 August 2018 в 02:24
поделиться
  • 1
    Вы правы. Лучше проигнорировать это. Учитывая это только для задания, я не буду входить в большие числа, и жизнь очень короткая. – OmidTahouri 6 February 2010 в 20:05
  • 2
    соглашаются очень опасно по ряду причин. Во-первых, в многопользовательской системе у вас может быть много, сотни, тысячи обновлений в секунду и попытка переписать auto inc может либо замедлить работу системы, либо скомпрометировать ее. Двое других разработчиков не знали бы, что вы были = делаете это, возможно, и записываете записи через идентификатор, чтобы развратить систему. и т.п. – PurplePilot 6 February 2010 в 20:25
  • 3
    Хорошие моменты. Ответ заставил меня подумать дважды. Я для одного не искал пробелов в auto_incr. потому что я собирался каким-то образом перебирать идентификаторы. Но я думаю, что лучше просто прокрутить строки :) – Nils Sens 10 October 2016 в 21:35
  • 4
    Так что это просто невозможно? Существуют веские причины для этого в тестовой среде. – Michael 15 September 2017 в 18:25

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

Рассмотрим это:

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

0
ответ дан Charles Robertson 16 August 2018 в 02:24
поделиться

Я пришел сюда, чтобы найти ответ на вопрос 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 охватывает это.

2
ответ дан Community 16 August 2018 в 02:24
поделиться

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

    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();
    }
}
0
ответ дан dani bilel 16 August 2018 в 02:24
поделиться

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

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

14
ответ дан Darin Dimitrov 16 August 2018 в 02:24
поделиться
  • 1
    он хочет сохранить счет, а не заказывать. UPDATE кажется ненужным. – Mike Sherov 6 February 2010 в 19:34
  • 2
    Хорошо, если он хочет сохранить счет, тогда нет необходимости добавлять дополнительные столбцы. Простая функция count aggregate выполнит эту работу. – Darin Dimitrov 6 February 2010 в 19:39
  • 3
    право, это то, к чему я пытался добраться. – Mike Sherov 6 February 2010 в 19:45
  • 4
    Хорошо спасибо. Много ответов / комментариев за такое короткое время! : O Я пытаюсь взять их всех. Я посмотрю на функцию count :) – OmidTahouri 6 February 2010 в 19:52

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

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

0
ответ дан halfer 16 August 2018 в 02:24
поделиться

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

0
ответ дан Joshua Omwoyo 16 August 2018 в 02:24
поделиться

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

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

Примечание: здесь нельзя использовать функцию автоматического увеличения.

1
ответ дан mbinette 16 August 2018 в 02:24
поделиться

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

3
ответ дан Mike Sherov 16 August 2018 в 02:24
поделиться
  • 1
    Я думаю, он думает, что это какая-то ошибка. MySQL 20 лет. Это определенно не надзор. Существует очень веская причина, по которой автоинкремент не перерабатывает ключи. Ты совершенно прав Майк. – Charles Robertson 18 April 2015 в 21:51

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

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

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

1
ответ дан Peter Smartt 16 August 2018 в 02:24
поделиться

Попробуйте:

SET @num: = 0;

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

ALTER TABLE tableName AUTO_INCREMENT = 1;

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

пример: before

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

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

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

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

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

BUT

  1. Если где-то на вашем коде что-то использует автоинкрементное значение ... возможно, это атрибуция вызовет проблему.
  2. Если вы не используете это значение в своем коде, все должно быть в порядке.
8
ответ дан powtac 16 August 2018 в 02:24
поделиться
  • 1
    Если вы хотите сохранить старые значения и установить auto_increment на максимальное значение, вам нужно найти максимальное значение: 1. Заказывая их и принимайте значение последней строки / 2., а затем устанавливайте автоинкремент до этого максимального значения + 1 в вашем коде. – Claod 26 February 2015 в 16:07
  • 2
    Очень ценю. Это очень помогает мне решить проблему моего друга. Я нашел этот ответ после большого поиска в Интернете. – Ariful Islam 15 May 2018 в 00:27

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

0
ответ дан Sarfraz 16 August 2018 в 02:24
поделиться

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

ALTER TABLE table_name DROP column_name;
ALTER TABLE table_name ADD column_name int not null auto_increment primary key first;
1
ответ дан Tunaki 16 August 2018 в 02:24
поделиться

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

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

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

2
ответ дан user262976 16 August 2018 в 02:24
поделиться
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");
0
ответ дан user3351200 16 August 2018 в 02:24
поделиться
  • 1
    MySQL является реляционной базой данных. Когда существует несколько таблиц, должно быть отношение, определенное между таблицами. И это делается с использованием столбцов идентификаторов. Проблема с этим подходом заключается в том, что если вы начнете перенумерацию индексов таблицы, то будут срабатывать эффекты во всех таблицах, с которыми она связана. – liamvictor 17 March 2017 в 13:11
  • 2
    это работает для меня – user3351200 18 March 2017 в 08:04
Другие вопросы по тегам:

Похожие вопросы: