Comments 107
UFO just landed and posted this here
Да вообще не понятно зачем этот код вообще, если все эти действия реализуются одной строчкой :)
+1
Ну подобный код я встречал многократно и у вполне российских программистов :)
Да, неэффективно. Да, немногопоточно. Да, для этого есть автоинкременты или генераторы.
А как сделать это одной строчкой? (Ну если отбросить в строну тот факт, что так делать вообще нельзя.)
Да, неэффективно. Да, немногопоточно. Да, для этого есть автоинкременты или генераторы.
А как сделать это одной строчкой? (Ну если отбросить в строну тот факт, что так делать вообще нельзя.)
0
mysql_insert_id — Get the ID generated from the previous INSERT operation - код не об этом ? :)
+1
UFO just landed and posted this here
Именно об этом
+1
UFO just landed and posted this here
В данном случае, не только скрипт кривой, но и база спроектирована неверно. В ней поле id без auto_increment. Поэтому товарищ так извращается для получения следующего id для юзера, вместо mysql_insert_id
0
UFO just landed and posted this here
>В данном случае, не только скрипт кривой, но и база >спроектирована неверно. В ней поле id без auto_increment.
Слышали о SQLite 2 ? вот там auto_increment нет.
>Поэтому товарищ так извращается для получения следующего id для >юзера, вместо mysql_insert_id
mysql_insert_id возвращает ID, сгенерированный колонкой с AUTO_INCREMENT последним запросом INSERT к серверу
у нас тут нет AUTO_INCREMENT это раз, во вторых мы можем добавить юзера а потом еще сотню записей, а нам надо именно ID для нового ЮЗЕРА узнать, так что тоже не подходит ваш совет.
Слышали о SQLite 2 ? вот там auto_increment нет.
>Поэтому товарищ так извращается для получения следующего id для >юзера, вместо mysql_insert_id
mysql_insert_id возвращает ID, сгенерированный колонкой с AUTO_INCREMENT последним запросом INSERT к серверу
у нас тут нет AUTO_INCREMENT это раз, во вторых мы можем добавить юзера а потом еще сотню записей, а нам надо именно ID для нового ЮЗЕРА узнать, так что тоже не подходит ваш совет.
0
такой код пишут для переносимости на разные базы данных. Не во всех же есть автоинкременты (К примеру cmf drupal, там есть целая таблица - последовательности для этих целей)
0
UFO just landed and posted this here
autoincrement поля заполняются сами, если не передавать в INSERT их значения.
+1
Я нигде не противоречу. При регистрации юзера надо заполнить табличку, кроме прочих данных, необходимо заполнить поле id, а т.к. в таблице поле id не auto_increment - приходится извращаться
0
нет, не об этом
0
вот Вам одной строчкой (но длинной).
function getNewId( $tableName, $idFieldName ){ return $conn -> selectrow_arrayref("SELECT ( MAX($idFieldName) OR 0 ) + 1 FROM $tableName"); }
работоспособность не гарантирую, да и врядли кому это понадобится...
PS: улыбнуло)
function getNewId( $tableName, $idFieldName ){ return $conn -> selectrow_arrayref("SELECT ( MAX($idFieldName) OR 0 ) + 1 FROM $tableName"); }
работоспособность не гарантирую, да и врядли кому это понадобится...
PS: улыбнуло)
+3
Скорее всего, автор имел в виду не национальность автора опубликованного фрагмента, а его духовные корни. :)
0
UFO just landed and posted this here
Ну не одной строчкой, а SQL запрос вроде один будет, который и будет ID возвращать. Написать, не напишу, потому что навскидку не вспомню.
-2
MySQL-ный INSERT вернёт ID.
-1
UFO just landed and posted this here
Не всегда программист имеет возможность вот так просто работать с БД. Часто для этого приходится теребить админов, а это может занять некоторое время. Я, конечно, согласен, что регистрация на сайте — это дело важное, и при проектировании структуры базы данных нельзя делать таких ошибок, а раз уж они совершены, то исправлять их надо самым правильным образом. Так что программиста этого скрипта я ничуть не оправдываю, но сам подход вычисления нового id как (max(id) + 1) может быть иногда оправдан.
+2
UFO just landed and posted this here
mysql_query('ALTER ...
+4
А если у пользователя базы права SELECT, INSERT, UPDATE?
0
фантазировать можно до бесконечности, но это уже совсем фантастика: чтобы админ оказался одновременно умным для ограничения прав на мускуль и тупым, чтобы не дать девелоперу нормальных прав, плюс настолько недоступным, что для девелопера оказалось проще написать свою имплементацию прекрасно работающего авто_инкремента
учитывая то, что реализован-то этот костыль и то криво, можно с 99% вероятностью утверждать, что девелоперу просто неведом автоинкремент
учитывая то, что реализован-то этот костыль и то криво, можно с 99% вероятностью утверждать, что девелоперу просто неведом автоинкремент
+3
Мне кажется, что программист (или архитектор приложения) должен сам разрабатывать структуру БД и затем передавать ее админам на внедрение и сопровождение.
+2
UFO just landed and posted this here
Получение айдишника тупо сделали
0
UFO just landed and posted this here
Смотря когда это было. Думаю да, сравнительно тупого были... но не настолько... я постоянно даю код на оценки и такие вещи находили :)
У меня тупость была скорее в неоптимальности кода, а тут действительно тупость :)
Помню у меня была такая-же проблемма (нужно было получить айди след записи). Потратил тогда 3 часа, перебрал все возможности и выбрал mysql_insert_id :) Но потом понял что это всё херня и переписал код так, чтобы айдишник вообще был ненужен )
У меня тупость была скорее в неоптимальности кода, а тут действительно тупость :)
Помню у меня была такая-же проблемма (нужно было получить айди след записи). Потратил тогда 3 часа, перебрал все возможности и выбрал mysql_insert_id :) Но потом понял что это всё херня и переписал код так, чтобы айдишник вообще был ненужен )
0
mysql_insert_id()
-2
>>P.S. Программист индус
Чем вам индусы не нравятся? Такой "код" может написать любой, вне зависимости от его национальности.
Чем вам индусы не нравятся? Такой "код" может написать любой, вне зависимости от его национальности.
0
Вааще-то здесь проблема не в том как это делать (mysql_insert_id не поможет), а в том, что этого делать вааще не надо.
Индусы они смешные :)
Индусы они смешные :)
0
Мда. Индусы пишут много и криво. Но все же это работает. Иногда даже говорят - хорошо написано то, что работает...
Сразу вспоминаю:
if ($flag == false) {
# на вский случай
if (false == true)
exit;
include "execute.php";
или проверку булевых значений:
if (b.ToString().length < 5){...}
Сразу вспоминаю:
if ($flag == false) {
# на вский случай
if (false == true)
exit;
include "execute.php";
или проверку булевых значений:
if (b.ToString().length < 5){...}
0
В том-то и проблема, что это работает пока тестируешь на локальной машине и при маленьком потоке пользователей. А потом время от времени будет ломаться, чем больше нагрузка тем чаще.
Все из-за того, что среда многопользовательская и может придти два запроса с маленькой разницей по времени и будет конфликт ID.
Все из-за того, что среда многопользовательская и может придти два запроса с маленькой разницей по времени и будет конфликт ID.
0
if (false == true)
exit;
Защищает от подъебов в стиле #define true false
exit;
Защищает от подъебов в стиле #define true false
+2
Могу предположить, что код нужен. Для систем с возможностью удаления пользователей это гарантирует, что у нового пользователя не будет ID от какого-нить старого.
Соответственно следы в базе, относящиеся к старому ID не навредят новому пользователю.
Автоинкремент не гарантирует постоянное увеличение.
Хотя в любом случае - это защита от того, что надо самому же в базе подчищать или обходить иначе.
Соответственно следы в базе, относящиеся к старому ID не навредят новому пользователю.
Автоинкремент не гарантирует постоянное увеличение.
Хотя в любом случае - это защита от того, что надо самому же в базе подчищать или обходить иначе.
0
как это? автоинкремент именно это и гарантирует :)
+2
Если ничего не поменяли, то при переходе максимально возможного ID он пойдёт заполнять "дырки", начиная с 0. И кажется я видел, что было, что и не обязательно после перехода максимума...
-5
испугался, ибо кое-где на это завязывался. Сделал тест:
CREATE TABLE test (id tinyint NOT NULL auto_increment, PRIMARY KEY(id))
потом зафигачил туда 255 записей, у последней, разумеется. id=255
фигачу следующую: Duplicate entry '255' for key 1 in query: INSERT INTO test () VALUES ()
удалил пару строчек из середины, результат - тот же.
так что не заполняет он дырки.
CREATE TABLE test (id tinyint NOT NULL auto_increment, PRIMARY KEY(id))
потом зафигачил туда 255 записей, у последней, разумеется. id=255
фигачу следующую: Duplicate entry '255' for key 1 in query: INSERT INTO test () VALUES ()
удалил пару строчек из середины, результат - тот же.
так что не заполняет он дырки.
+2
ах да, движок InnoDB
0
и tinyint был unsigned :)
0
Значит пофиксили. Я это видел в 3.дремучем мускуле или раньше.
А установить счетчик на таблице вручную что даёт?
А установить счетчик на таблице вручную что даёт?
0
А попробуйте удалить последнюю запись и добавить новую - она получит номер уже удаленной! Это тоже неправильно, т.к. может нарушить сслочную логику.
+1
точно :)
с другой стороны, ситуация переполненного типа сама по себе ошибочная.
с другой стороны, ситуация переполненного типа сама по себе ошибочная.
0
Ссылочную логику нужно другими средствами беречь.
0
Это внутри базы, а за ее пределами?
Сейчас как раз разрабатываю систему синхронизации данных с партнерами. Недавно один объект стал лишним, его удалили, и партнеры предложили создать новый с тем же id - чтобы дырку заполнить.
Чуть не убил на месте! Битый час объяснял почему нельзя так делать!
Представьте, на первый объект накопилась информация, а дальше инфа начинает поступать для другого, но вы об этом еще не знаете. Что в итоге? Полный бред вместо информации.
Сейчас как раз разрабатываю систему синхронизации данных с партнерами. Недавно один объект стал лишним, его удалили, и партнеры предложили создать новый с тем же id - чтобы дырку заполнить.
Чуть не убил на месте! Битый час объяснял почему нельзя так делать!
Представьте, на первый объект накопилась информация, а дальше инфа начинает поступать для другого, но вы об этом еще не знаете. Что в итоге? Полный бред вместо информации.
0
Нельзя ничего вставлять в таблицу, если мы удалили запись и остались ссылки на эту запись. Ибо целостность нарушена.
В таких случаях помогает правильная проектировка базы, с ON DELETE CASCADE http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html - система сама удалит все ссылающиеся записи.
В таких случаях помогает правильная проектировка базы, с ON DELETE CASCADE http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html - система сама удалит все ссылающиеся записи.
0
Все так. Внутри базы мы можем контролировать, но после того как система разрастется и ее надо будет интегрировать с другими системами, начнутся проблемы.
Представьте, что в других системах есть ссылки на ваши объекты (неважно какие http, по id или еще как-то). Затем объект был удален и вместо него добавлен новый с тем же id. Внешняя система начинает работать с этим объектом - вот отличный источник «веселых» ошибок.
Представьте, что в других системах есть ссылки на ваши объекты (неважно какие http, по id или еще как-то). Затем объект был удален и вместо него добавлен новый с тем же id. Внешняя система начинает работать с этим объектом - вот отличный источник «веселых» ошибок.
0
Автоинкремент как раз гарантирует постоянное увеличение. в MyISAM БД точно.
0
походу я зажрался в оракле со всякими там сиквенсами...
+1
вот вы пишете про фиговый код, написали бы правильный вариант, чтобы новичкам понятно было, как не следует делать...
+3
эх... были врермена писал что-то вроде этого опуса :)) стыдно :)) Но с чего-то нужно начинать. Человек просто не знает об autoincrement :)
0
Я программер. В коде вижу косяк с >=0
Других моментов, которых можно назвать косяками - не вижу. Все остальное может быть объяснено.
Автор, плиз, скажи, а где здесь бред?
Напиши код, который не использует автоинкримент (по разным причинам это может быть нужно), как-то отработает в случае, если в запросе вывалится в исключение (нет таблицы, прав или соединения с базой данных), если запрос вернет пустое количество строк или действительно вернет значение.
Может в PHP есть это все одной командой?
Других моментов, которых можно назвать косяками - не вижу. Все остальное может быть объяснено.
Автор, плиз, скажи, а где здесь бред?
Напиши код, который не использует автоинкримент (по разным причинам это может быть нужно), как-то отработает в случае, если в запросе вывалится в исключение (нет таблицы, прав или соединения с базой данных), если запрос вернет пустое количество строк или действительно вернет значение.
Может в PHP есть это все одной командой?
0
Я вижу 2 косяка:
1) при большом кол-ве запросов возникнут глюки вставки, когда второй запрос придет между взятием max и записью max+1 в базу
2) при удалении последней записи нарушается ссылочная целостность.
Честно говоря, я ни разу не сталкивался с ситуацией, когда нельзя было использовать автоинкрементое поле. И всегда это было самое надежное решение. Поделитесь, пожалуйста, информацией когда оно не подходит.
1) при большом кол-ве запросов возникнут глюки вставки, когда второй запрос придет между взятием max и записью max+1 в базу
2) при удалении последней записи нарушается ссылочная целостность.
Честно говоря, я ни разу не сталкивался с ситуацией, когда нельзя было использовать автоинкрементое поле. И всегда это было самое надежное решение. Поделитесь, пожалуйста, информацией когда оно не подходит.
0
Поддерживаю!
Если есть какие-то сложности можно сделать в БД таблицу со счетчиками и увеличивать ее используя update. Написать хранимку в конце концов. Или триггер. ;-) Сейчас пятый мускуль уже не редкость.
Нужно помнить, что в innodb значение автоинкремента вычисляется при каждом запуске сервера БД. И после удаления последних записей из таблицы с последующим рестартом сервера опять же можем получить нарушение ссылочной целостности.
Если есть какие-то сложности можно сделать в БД таблицу со счетчиками и увеличивать ее используя update. Написать хранимку в конце концов. Или триггер. ;-) Сейчас пятый мускуль уже не редкость.
Нужно помнить, что в innodb значение автоинкремента вычисляется при каждом запуске сервера БД. И после удаления последних записей из таблицы с последующим рестартом сервера опять же можем получить нарушение ссылочной целостности.
0
Как вариант, но, думаю, тут придется лочить таблицу или использовать транзакции, чтобы избежать все той же проблемы с двойной вставкой.
Насчет поведения автоинкрмента в innodb не знал (последнее время чаще работаю с другой БД). Это всегда так? Или можно как-то этого избежать?
Насчет поведения автоинкрмента в innodb не знал (последнее время чаще работаю с другой БД). Это всегда так? Или можно как-то этого избежать?
0
Я вот видел такую. Программа требовала заполнения других таблиц с ссылками на эту запись до добавления самой записи. Хотя это скорее ошибка проектирования.
0
+1
то что работает - написано правильно (до тех пор, пока не перестанет работать)
Единственное, что надо ответственно относиться к проектированию БД и кода, а то потом поддерживать зае...шся
то что работает - написано правильно (до тех пор, пока не перестанет работать)
Единственное, что надо ответственно относиться к проектированию БД и кода, а то потом поддерживать зае...шся
0
В очередной раз заставило взгрустнуть о том, когда же наконец в mysql сделают sequence
0
Кароч. Единственное, что ясно из этого, что автор кода не читал доки по мускулу до конца и не задумывался, что перед созданием базы надо хотя бы продумать ее структуру, спросить бывалых.
ЗЫ: В данном случае автоинкремент решает все проблемы.
ЗЫ: В данном случае автоинкремент решает все проблемы.
0
Еще было бы интересно увидеть каким образом индус использует эту функцию. Может там какой медитативный код, с предсказанием ID пользователя, который еще не зарегистрировался :-)
0
Только-только у себя написал про аналогичное. Афтар моего опуса - итальянец.
0
При использовании LINQ to SQL в .Net, при добавлении объекта пользователя в базу, id заполнится сам.
Dim newUser = New User() With {.Name = "Name"}
db.Users.InsertOnSubmit(newUser)
db.SubmitChanges()
return newUser.id
Dim newUser = New User() With {.Name = "Name"}
db.Users.InsertOnSubmit(newUser)
db.SubmitChanges()
return newUser.id
0
А ведь мог взять все записи, написать функцию сортировки массива, и взять последний элемент ;)
0
Кстати - подход с MAX(id) идеален для возрастающих ID, где выпады критичны. auto_increment при удалении последней записи не уменьшается.
а в остальном - wtf))
а в остальном - wtf))
-1
где могут быть критичны "выпады"?
ремарка: субд реляционная
ремарка: субд реляционная
0
вполне возможны, когда требуется строгий порядок ID, в ТЗ всё бывает
причем это логично только в том случае, если удаляются последнии записи, а не в середине.
причем это логично только в том случае, если удаляются последнии записи, а не в середине.
0
>> в ТЗ всё бывает
да уж... ТЗ должно регламентировать результат, а не реализацию
так или иначе - конкретный жизненный пример приведёте или нет? :-)
да уж... ТЗ должно регламентировать результат, а не реализацию
так или иначе - конкретный жизненный пример приведёте или нет? :-)
0
лично в моих некоторых проектах такое требование есть - чтобы у новой записи был строго следующий идентификатор.
0
рациональная причина так делать будет озвучена или нет?
(прошу уже в третий раз)
(прошу уже в третий раз)
0
Подскажите вот здесь ..$record[0]+1.. "+1" зачем? Нехватает фантазии? )
0
мой мозг
какие каменты
бл%дь
бл%дь
бл%дь
ребята
это
жесточайший
пи%дец
может, вы ещё и минусуете топик, потому что не можете понять, где тут бред?
какие каменты
бл%дь
бл%дь
бл%дь
ребята
это
жесточайший
пи%дец
может, вы ещё и минусуете топик, потому что не можете понять, где тут бред?
+2
Ааа... я прослезился. Когда стажером писал программку в MS Access, приблизительно так же регистрировал новые записи фильмов и компаний в БД. Зато работало! :)
Жалко ее код я уже давно потерял, сейчас было бы ржачно наверно.
Жалко ее код я уже давно потерял, сейчас было бы ржачно наверно.
0
Only those users with full accounts are able to leave comments. Log in, please.
Интересный отрывок скрипта регистрации