Столбец MySQL с автоинкрементом - PullRequest
0 голосов
/ 11 октября 2011

Я создал мини-cms.Каждая страница имеет уникальный идентификатор.Пользователи могут добавлять, редактировать, удалять страницы.

Допустим, у нас есть 10 страниц, а user1 удаляет его страницы 5-8.Так что теперь у нас есть страницы с идентификаторами 1,2,3,4,9,10.Можно ли в следующий раз заполнить строки идентификаторами 5-8?Если да, как их искать и заполнить?Кстати, мое поле 'id' автоинкрементно

Ответы [ 4 ]

3 голосов
/ 11 октября 2011

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

Откровенно говоря, какой смысл? Значение id равно 1 или 201321941 не имеет значения для компьютера. Если вы думаете, что «некрасиво» иметь пробелы после удаления чего-либо, вам нужно изменить свою логику и прекратить использовать auto_increments или хотя бы соответствовать им.

Первое, что вам нужно знать, это то, что вы никогда никогда не хотите вмешиваться в auto_increment. Почему?

Прежде всего, auto_increment всегда используется для первичного ключа с таблицами MySQL, и, следовательно, это суррогатный первичный ключ, который означает, что MySQL определяет, как его сгенерировать физически. Если вы добавите человеческий фактор к алгоритму, который имеет дело с чувствительными вещами (например, всегда правильно генерирует следующее целое число для конкретной таблицы, принимая транзакции и что не учитывается) - вы получите катастрофу.

Во-вторых, для некоторых механизмов, таких как InnoDB, первичный ключ определяет физический порядок хранения данных. Что это значит? Скажем, у вас есть 1 миллион записей в вашей таблице, и способ, которым InnoDB хранит данные, заключается в добавлении самой последней записи в файл данных, поскольку каждый следующий идентификатор больше предыдущего. Затем вы, скажем, удалите число 500 000, и вы хотите использовать его повторно. Это означает, что физически InnoDB должен вставить запись в строку 500 000 (упрощенное объяснение) и переупорядочить b-дерево, чтобы соответствовать изменению, которое намного дороже, чем просто добавление данных.

Есть и другие причины, которые я действительно не хочу сейчас упоминать, но если вы хотите какой-то последовательный порядок или отображение ваших идентификаторов - тогда создайте другое поле под названием sequence_id или что-то подобное и создайте триггер, который будет правильно справиться с этим (увеличить или уменьшить). В противном случае, не делайте то, что может причинить вам боль.

2 голосов
/ 11 октября 2011

Ты не должен этого делать.

Уникальный идентификатор не является числом. Это уникальный идентификатор. Уникальный. Понял?
Никогда не следует прикасаться к уникальному идентификатору. Он идентифицирует строку и должен застрять с ней навсегда.

Что касается вашей "проблемы",

  1. Я сомневаюсь, что кто-нибудь когда-либо заметит такое несоответствие в цифрах. Особенно, если у вас есть некоторая иерархия для ваших страниц.

  2. Если вы хотите, чтобы на вашем сайте были хорошие URL-адреса - делайте их по-настоящему красивыми, с надписями news, articles и т. Д. Это было бы намного лучше, чем ваши глупые заказанные числа.

0 голосов
/ 11 октября 2011

Вы можете сделать (вы должны удалить автоинкремент):

SELECT id FROM page_table ORDER BY id ASC

Затем вы найдете первый номер идентификатора, который не установлен

// $result is a one dimension array containing all ids (so you have to parse what sql query returns before)

$autoIncStartVal = 1;

$nextId = null;

// count($result) + 1 if there is no "hole" in id (so $nextId will be count($result) + 1
for($i=0;$i<count($result) + 1;$i++) { 

  if(!isset($result[$i]) OR $result[$i] != $i + $autoIncStartVal) {
    $nextId = $i+$autoIncStartVal;
    break;
  }

}

Пример:

$result = array(1,2,4,5);

$autoIncStartVal = 1;
$nextId = null;

    for($i=0;$i<count($result) + 1;$i++) { 
      if(!isset($result[$i]) OR $result[$i] != $i + $autoIncStartVal) {
        $nextId = $i+$autoIncStartVal;
        break;
      }
    }

var_dump($nextId); // 3

Это найдет следующий идентификатор в точный момент выполнения запроса SQL.Если два запроса выполняются одновременно, они будут возвращать один и тот же идентификатор и, следовательно, $ nextid будет иметь одинаковое значение 2 раза

0 голосов
/ 11 октября 2011


Вы можете сделать это, если ID не имеет автоматического увеличения.А во время удаления записей (страниц) вы должны хранить все идентификаторы в одной таблице и создавать журнал удаленных записей.теперь, когда вы вставляете какие-либо новые записи в это время, вы можете проверить идентификатор удаленных записей в таблице текущих записей;если этого идентификатора там не существует, то вы можете создать этот идентификатор по запросу. Таким образом, к концу некоторых записей ваши пропущенные идентификаторы записей будут заполнены текущими записями.

Единственный вариант, который у вас есть,из этой проблемы .. вы можете использовать эту опцию, если это необходимо.

Спасибо.

...