Вам нужен следующий идентификатор или идентификатор строки, которую вы сейчас вставляете? То есть должен ли идентификатор в конце кода платежа быть идентификатором строки, в которой хранится код платежа?
Майк,
id строки, которую я сейчас вставляю
faressoft
6
В этом случае объединяйте значения при их получении, а не при их вставке. Это намного проще, и вы исключаете получение неправильного идентификатора или необходимость запускать обновление - подумайте, что произойдет, если строка, которую вы только что вставили, будет запрошена другим клиентом до того, как обновление успеет запуститься: клиент закончится неверным кодом платежа. В системе с низким трафиком этого может и не произойти, но я не вижу смысла рисковать.
Спасибо за первые два варианта .. Но третий - это всего лишь номер два, вызываемый из PHP .. Не уверен, что делает это быстрее в больших базах данных ...
Джерард Онилл
1
@GerardONeill Удалено
ravi404
3
поскольку для извлечения данных из information_schema.tables используется кеш, это решение больше не работает для mysql 8.
Вы можете получить следующее значение автоинкремента, выполнив:
SHOW TABLE STATUS FROM tablename LIKE Auto_increment
/*or*/SELECT`auto_increment`FROM INFORMATION_SCHEMA.TABLES
WHERE table_name ='tablename'
Обратите внимание, что вы не должны использовать это для изменения таблицы, вместо этого используйте столбец auto_increment, чтобы сделать это автоматически.
Проблема в том, что last_insert_id()это ретроспективно и, следовательно, может быть гарантировано в рамках текущего соединения.
Этот ребенок перспективен и, следовательно, не уникален для каждого соединения, и на него нельзя положиться.
Только в базе данных с одним подключением это могло бы работать, но сегодня базы данных с одним подключением имеют привычку завтра превращаться в базы данных с несколькими подключениями.
Я не понижал его, но проблема с попыткой использовать последнее автоматически увеличивающееся значение заключается в том, что оно может быть не последним к тому времени, когда вы начнете его использовать - независимо от того, как быстро выполняется SELECT и последующий INSERT.
Mike
@Mike, а что, если это делается одним запросом? Что-то вроде insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'? Я бы использовал обновление в after insertтриггере и last_insert_id(), хотя ...
binaryLV
1
@binaryLV: чем меньше разрыв между SELECT и INSERT, тем меньше вероятность того, что значение изменится, но это не исключает полностью. Представьте себе систему с тысячами посещений в минуту в базе данных - шансы на изменение значения резко возрастают. Блокировка таблицы или строки может предотвратить это, если она выполняется как единый запрос, но это зависит от определенного поведения механизма базы данных, которое может быть плохо документировано. Я бы пошел с последующим, UPDATEесли бы тоже. Но я бы предпочел просто объединить их во время отображения и избавить от лишних хлопот.
Майк,
3
SHOW TABLE STATUSожидает увидеть database nameпосле FROMи 'table name pattern'после LIKE.
x-yuri
2
поскольку для извлечения данных из information_schema.tables используется кеш, это решение больше не работает для mysql 8.
Бруно,
15
Это вернет значение автоматического увеличения для базы данных MySQL, и я не проверял с другими базами данных. Обратите внимание, что если вы используете любую другую базу данных, синтаксис запроса может быть другим.
SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name ='your_table_name'and table_schema ='your_database_name';SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name ='your_table_name'and table_schema =database();
ВЫБЕРИТЕ AUTO_INCREMENT ИЗ information_schema.tables, ГДЕ table_name = 'your_table_name' и table_schema = 'your_database_name';
LJay
10
В верхнем ответе для решения используется PHP MySQL_ , и я подумал, что поделюсь обновленным решением PHP MySQLi_ для достижения этой цели. В этом примере нет вывода ошибок!
$db = new mysqli('localhost','user','pass','database');$sql ="SHOW TABLE STATUS LIKE 'table'";$result=$db->query($sql);$row=$result->fetch_assoc();
echo $row['Auto_increment'];
Выбрасывает следующее автоматическое приращение, появляющееся в таблице.
Помните о первом методе, если будет отброшена запись с наивысшим идентификатором, тогда вы создадите новую запись с идентификатором, который использовался ранее.
Том Дженкинсон
и если предыдущий ключ использовался в других таблицах и все еще хранится там, вы можете получить очень странную магию
Тебе,
первый возвращает неправильный идентификатор, если вы отбрасываете последнюю вставленную запись,
Али Парса
6
Решение:
CREATETRIGGER`IdTrigger` BEFORE INSERTON`payments`FOR EACH ROWBEGINSELECT AUTO_INCREMENT Into@xId
FROM information_schema.tables
WHERE
Table_SCHEMA ="DataBaseName"AND
table_name ="payments";SET NEW.`payment_code`= CONCAT("sahf4d2fdd45",@xId);END;
Обновление payment_codeв after insertтриггере кажется лучшим вариантом.
binaryLV
3
Вы не можете использовать идентификатор при вставке, он вам и не нужен. MySQL даже не знает ID, когда вы вставляете эту запись. Вы можете просто сохранить "sahf4d2fdd45"в payment_codeтаблице и использовать idиpayment_code дальнейшем.
Если вам действительно нужен ваш payment_code, чтобы в нем был идентификатор, ОБНОВИТЕ строку после вставки, чтобы добавить идентификатор.
+1 Чтобы сделать это немного более явным: если вы берете «последнее» значение из столбца, оно гарантированно будет последним значением только в тот момент, когда вы его получили. Это может быть не последнее значение, когда вы собираетесь использовать это значение в последующей вставке. В случае столбца с автоматическим приращением всегда есть вероятность, что другое значение было добавлено между временем, когда вы получили идентификатор, и временем, когда вы вставили его в другое место. Если вы ссылаетесь на только что вставленную строку, можно использовать LAST_INSERT_ID (). Если вы пытаетесь обеспечить уникальное значение, это не так.
Майк,
@cularis, MySQL знает следующий идентификатор auto_increment, он указан в information_schema.tablesтаблице.
Johan
1
@faressoft: если идея состоит в том, чтобы иметь код платежа, который состоит из уникальной строки и идентификатора строки, содержащей этот код платежа, просто объедините их при получении строки - либо с SELECT ... CONCAT(payment_code, id), либо в коде вашего приложения. Вы даже можете заключить SELECTв a VIEW, чтобы всегда возвращать правильное значение, не беспокоясь о CONCAT в каждом SELECT из вашего приложения.
Майк,
3
Для чего вам нужен следующий инкрементный идентификатор?
MySQL допускает только одно поле с автоинкрементом для каждой таблицы, и оно также должно быть первичным ключом, чтобы гарантировать уникальность.
Обратите внимание, что когда вы получаете следующий идентификатор вставки, он может быть недоступен при его использовании, поскольку имеющееся у вас значение находится только в рамках этой транзакции. Следовательно, в зависимости от нагрузки на вашу базу данных, это значение может уже использоваться к моменту поступления следующего запроса.
Я бы посоветовал вам пересмотреть свой дизайн, чтобы убедиться, что вам не нужно знать, какое значение автоинкремента назначить следующим
Не рекомендуется предполагать, какое приложение требует ID. Существуют приложения, подобные тому, над которым я работаю в данный момент, которому требуется следующий инкрементный идентификатор, и полученное значение не находится в опасности быть выделенным другому сценарию.
JG Estiot
3
Предлагаю переосмыслить то, что вы делаете. Я никогда не встречал ни одного случая, когда требовались бы эти специальные знания. Следующий идентификатор - это особая деталь реализации, и я бы не стал рассчитывать на то, что он безопасен для ACID.
Сделайте одну простую транзакцию, которая обновит вашу вставленную строку с последним идентификатором:
BEGIN;INSERTINTO payments (date, item, method)VALUES(NOW(),'1 Month','paypal');UPDATE payments SET payment_code = CONCAT("sahf4d2fdd45", LAST_INSERT_ID())WHERE id = LAST_INSERT_ID();COMMIT;
Я могу назвать один такой вариант использования, я пытаюсь диагностировать производственную проблему, поэтому мне нужно выяснить, действительно ли последняя строка в таблице является последней строкой или была добавлена одна после той, которая каким-то образом была удалена, таблица имеет поле auto_increment, поэтому, найдя эту информацию, я могу сделать вывод, была ли строка удалена или никогда не добавлялась.
Усман
1
Возможно, это сработает для вас, но я бы не стал на это полагаться, поскольку не думаю, что у вас есть на это гарантии: dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html " когда столбец AUTO_INCREMENT является частью индекса с несколькими столбцами), значения AUTO_INCREMENT используются повторно, если вы удаляете строку с наибольшим значением AUTO_INCREMENT в любой группе ».
Маркус Малкуш
Спасибо, полезная информация, также согласно вашей общей ссылке auto_increment можно сбросить, вставив вручную номер, так что да, это ненадежно.
Усман
2
Вам необходимо подключиться к MySQL и выбрать базу данных, прежде чем вы сможете это сделать.
$table_name ="myTable";$query = mysql_query("SHOW TABLE STATUS WHERE name='$table_name'");$row= mysql_fetch_array($query);$next_inc_value =$row["AUTO_INCREMENT"];
используйте mysql_insert_id (). mysql_insert_id () воздействует на последний выполненный запрос, обязательно вызовите mysql_insert_id () сразу после запроса, который генерирует значение.
Ниже приведен пример использования:
<?php
$link = mysql_connect('localhost','username','password');if(!$link){
die('Could not connect: '. mysql_error());}
mysql_select_db('mydb');
mysql_query("INSERT INTO mytable VALUES('','value')");
printf("Last inserted record has id %d\n", mysql_insert_id());?>
Надеюсь, приведенный выше пример окажется полезным.
Я тоже согласен, что это самый простой подход. Не уверен, почему вас проголосовали против, но я компенсирую это голосом за.
recurse
Я не упоминал о необходимости транзакции, если вы не обернете его внутри транзакции, этот код паршивый, поскольку он соответствует реальной загрузке.
Тебе,
1
Что делать, если последняя строка была удалена? Или несколько последних строк были удалены?
Liam W
Не связанные с проблемами, освобожденные ключи не используются, если вы не укажете это явно
Тебе,
1
используя ответ ravi404:
CREATEFUNCTION`getAutoincrementalNextVal`(`TableName` VARCHAR(50))
RETURNS BIGINT
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''BEGINDECLARE Value BIGINT;SELECT
AUTO_INCREMENT INTO Value
FROM
information_schema.tables
WHERE
table_name = TableName AND
table_schema =DATABASE();RETURN Value;END
используя в запросе на вставку, чтобы создать хеш SHA1. напр .:
Это всегда работает? Есть ли условия гонки, если две вставки выполняются одновременно?
Jmons
0
Улучшение @ ravi404, если ваше смещение автоинкремента НЕ 1:
SELECT(`auto_increment`-1)+ IFNULL(@@auto_increment_offset,1)FROM INFORMATION_SCHEMA.TABLES
WHERE table_name = your_table_name
AND table_schema =DATABASE();
( auto_increment-1): механизм db, кажется, всегда учитывает смещение 1. Поэтому вам нужно отказаться от этого предположения, а затем добавить необязательное значение @@ auto_increment_offset или значение по умолчанию 1: IFNULL (@@ auto_increment_offset, 1)
$auto_inc_db = mysql_query("SELECT * FROM my_table_name ORDER BY id ASC ");while($auto_inc_result = mysql_fetch_array($auto_inc_db)){$last_id =$auto_inc_result['id'];}$next_id =($last_id+1);
echo $next_id;//this is the new id,if auto increment ison
auto_increment
столбикОтветы:
Используйте
LAST_INSERT_ID()
из вашего SQL-запроса.Или
Вы также можете использовать его
mysql_insert_id()
для получения с помощью PHP.источник
LAST_INSERT_ID()
.mysqli_insert_id
Ты можешь использовать
или если вы не хотите использовать information_schema, вы можете использовать это
источник
TABLES.AUTO_INCREMENT
находится в кеше dev.mysql.com/doc/refman/8.0/en/… . В блоге Mysql также есть несколько сообщений об этом, но система, которую они упоминают, кажется устаревшей: mysqlserverteam.com/… mysqlserverteam.com/…Вы можете получить следующее значение автоинкремента, выполнив:
Обратите внимание, что вы не должны использовать это для изменения таблицы, вместо этого используйте столбец auto_increment, чтобы сделать это автоматически.
Проблема в том, что
last_insert_id()
это ретроспективно и, следовательно, может быть гарантировано в рамках текущего соединения.Этот ребенок перспективен и, следовательно, не уникален для каждого соединения, и на него нельзя положиться.
Только в базе данных с одним подключением это могло бы работать, но сегодня базы данных с одним подключением имеют привычку завтра превращаться в базы данных с несколькими подключениями.
Видеть:
SHOW TABLE STATUS
источник
insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'
? Я бы использовал обновление вafter insert
триггере иlast_insert_id()
, хотя ...UPDATE
если бы тоже. Но я бы предпочел просто объединить их во время отображения и избавить от лишних хлопот.SHOW TABLE STATUS
ожидает увидетьdatabase name
послеFROM
и'table name pattern'
послеLIKE
.Это вернет значение автоматического увеличения для базы данных MySQL, и я не проверял с другими базами данных. Обратите внимание, что если вы используете любую другую базу данных, синтаксис запроса может быть другим.
источник
В верхнем ответе для решения используется PHP MySQL_ , и я подумал, что поделюсь обновленным решением PHP MySQLi_ для достижения этой цели. В этом примере нет вывода ошибок!
Выбрасывает следующее автоматическое приращение, появляющееся в таблице.
источник
В PHP вы можете попробовать следующее:
ИЛИ
источник
Решение:
"DataBaseName" - это название нашей базы данных.
источник
Простой запрос подойдет
SHOW TABLE STATUS LIKE 'table_name'
источник
Вы можете использовать триггер mysql
источник
payment_code
вafter insert
триггере кажется лучшим вариантом.Вы не можете использовать идентификатор при вставке, он вам и не нужен. MySQL даже не знает ID, когда вы вставляете эту запись. Вы можете просто сохранить
"sahf4d2fdd45"
вpayment_code
таблице и использоватьid
иpayment_code
дальнейшем.Если вам действительно нужен ваш payment_code, чтобы в нем был идентификатор, ОБНОВИТЕ строку после вставки, чтобы добавить идентификатор.
источник
information_schema.tables
таблице.SELECT ... CONCAT(payment_code, id)
, либо в коде вашего приложения. Вы даже можете заключитьSELECT
в aVIEW
, чтобы всегда возвращать правильное значение, не беспокоясь о CONCAT в каждом SELECT из вашего приложения.Для чего вам нужен следующий инкрементный идентификатор?
MySQL допускает только одно поле с автоинкрементом для каждой таблицы, и оно также должно быть первичным ключом, чтобы гарантировать уникальность.
Обратите внимание, что когда вы получаете следующий идентификатор вставки, он может быть недоступен при его использовании, поскольку имеющееся у вас значение находится только в рамках этой транзакции. Следовательно, в зависимости от нагрузки на вашу базу данных, это значение может уже использоваться к моменту поступления следующего запроса.
Я бы посоветовал вам пересмотреть свой дизайн, чтобы убедиться, что вам не нужно знать, какое значение автоинкремента назначить следующим
источник
Предлагаю переосмыслить то, что вы делаете. Я никогда не встречал ни одного случая, когда требовались бы эти специальные знания. Следующий идентификатор - это особая деталь реализации, и я бы не стал рассчитывать на то, что он безопасен для ACID.
Сделайте одну простую транзакцию, которая обновит вашу вставленную строку с последним идентификатором:
источник
Вам необходимо подключиться к MySQL и выбрать базу данных, прежде чем вы сможете это сделать.
источник
используйте mysql_insert_id (). mysql_insert_id () воздействует на последний выполненный запрос, обязательно вызовите mysql_insert_id () сразу после запроса, который генерирует значение.
Ниже приведен пример использования:
Надеюсь, приведенный выше пример окажется полезным.
источник
Это оно :)
источник
Хотя сомневаюсь в его продуктивности, но надежен на 100%
источник
используя ответ ravi404:
используя в запросе на вставку, чтобы создать хеш SHA1. напр .:
источник
Улучшение @ ravi404, если ваше смещение автоинкремента НЕ 1:
(
auto_increment
-1): механизм db, кажется, всегда учитывает смещение 1. Поэтому вам нужно отказаться от этого предположения, а затем добавить необязательное значение @@ auto_increment_offset или значение по умолчанию 1: IFNULL (@@ auto_increment_offset, 1)источник
Для меня это работает и выглядит просто:
источник
$last_id
повторно, когда можно простоDESC
. Вашwhile
блок проделал кучу бесполезной работы.Если не возвращается правильный AUTO_INCREMENT, попробуйте:
Этот чистый кеш для таблицы в BD
источник