Pull to refresh

Comments 107

UFO just landed and posted this here
Да вообще не понятно зачем этот код вообще, если все эти действия реализуются одной строчкой :)
Ну подобный код я встречал многократно и у вполне российских программистов :)
Да, неэффективно. Да, немногопоточно. Да, для этого есть автоинкременты или генераторы.
А как сделать это одной строчкой? (Ну если отбросить в строну тот факт, что так делать вообще нельзя.)
mysql_insert_id — Get the ID generated from the previous INSERT operation - код не об этом ? :)
UFO just landed and posted this here
UFO just landed and posted this here
В данном случае, не только скрипт кривой, но и база спроектирована неверно. В ней поле id без auto_increment. Поэтому товарищ так извращается для получения следующего id для юзера, вместо mysql_insert_id
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 для нового ЮЗЕРА узнать, так что тоже не подходит ваш совет.
ааа-а-а-а извиняюсь, только ща увидел что юзается именно mysql_query :)
ага, только хотел написать, не смущают ли вас приставки mysql* в названии функций :)
такой код пишут для переносимости на разные базы данных. Не во всех же есть автоинкременты (К примеру cmf drupal, там есть целая таблица - последовательности для этих целей)
UFO just landed and posted this here
autoincrement поля заполняются сами, если не передавать в INSERT их значения.
автоинкремент использовать Шива не велит
Ганеш наоборот всеми лапами и хоботом ЗА! :)
Скорее Брахма (создатель) или Вишну (хранитель). Шива - Бог разрушения, его при программировании призывать не следует)
а вы Snow Сrash не читали? там про Шиву есть :)
Я нигде не противоречу. При регистрации юзера надо заполнить табличку, кроме прочих данных, необходимо заполнить поле id, а т.к. в таблице поле id не auto_increment - приходится извращаться
UFO just landed and posted this here
вот Вам одной строчкой (но длинной).
function getNewId( $tableName, $idFieldName ){ return $conn -> selectrow_arrayref("SELECT ( MAX($idFieldName) OR 0 ) + 1 FROM $tableName"); }

работоспособность не гарантирую, да и врядли кому это понадобится...
PS: улыбнуло)
в таком виде у вас $conn в функции не будет существовать :)
Скорее всего, автор имел в виду не национальность автора опубликованного фрагмента, а его духовные корни. :)
UFO just landed and posted this here
Ну не одной строчкой, а SQL запрос вроде один будет, который и будет ID возвращать. Написать, не напишу, потому что навскидку не вспомню.
сам по себе insert никуда ничего не возвращает
UFO just landed and posted this here
Не всегда программист имеет возможность вот так просто работать с БД. Часто для этого приходится теребить админов, а это может занять некоторое время. Я, конечно, согласен, что регистрация на сайте — это дело важное, и при проектировании структуры базы данных нельзя делать таких ошибок, а раз уж они совершены, то исправлять их надо самым правильным образом. Так что программиста этого скрипта я ничуть не оправдываю, но сам подход вычисления нового id как (max(id) + 1) может быть иногда оправдан.
UFO just landed and posted this here
А если у пользователя базы права SELECT, INSERT, UPDATE?
фантазировать можно до бесконечности, но это уже совсем фантастика: чтобы админ оказался одновременно умным для ограничения прав на мускуль и тупым, чтобы не дать девелоперу нормальных прав, плюс настолько недоступным, что для девелопера оказалось проще написать свою имплементацию прекрасно работающего авто_инкремента

учитывая то, что реализован-то этот костыль и то криво, можно с 99% вероятностью утверждать, что девелоперу просто неведом автоинкремент
Мне кажется, что программист (или архитектор приложения) должен сам разрабатывать структуру БД и затем передавать ее админам на внедрение и сопровождение.
UFO just landed and posted this here
Получение айдишника тупо сделали
UFO just landed and posted this here
Смотря когда это было. Думаю да, сравнительно тупого были... но не настолько... я постоянно даю код на оценки и такие вещи находили :)

У меня тупость была скорее в неоптимальности кода, а тут действительно тупость :)
Помню у меня была такая-же проблемма (нужно было получить айди след записи). Потратил тогда 3 часа, перебрал все возможности и выбрал mysql_insert_id :) Но потом понял что это всё херня и переписал код так, чтобы айдишник вообще был ненужен )
масс ошибки, пойду спать, mozg offline ^^
UFO just landed and posted this here
гы) Ну я у индусов код тоже ужасный видел.

Кстати это видимо показатели счётчика посещений))) лучше бы они туда рандом пихнули. Видимо им проще каждый день вручную приписывать)))
>>P.S. Программист индус

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

Индусы они смешные :)
Мда. Индусы пишут много и криво. Но все же это работает. Иногда даже говорят - хорошо написано то, что работает...
Сразу вспоминаю:

if ($flag == false) {
# на вский случай
if (false == true)
exit;
include "execute.php";

или проверку булевых значений:

if (b.ToString().length < 5){...}
В том-то и проблема, что это работает пока тестируешь на локальной машине и при маленьком потоке пользователей. А потом время от времени будет ломаться, чем больше нагрузка тем чаще.
Все из-за того, что среда многопользовательская и может придти два запроса с маленькой разницей по времени и будет конфликт ID.
if (false == true)
exit;
Защищает от подъебов в стиле #define true false
т.к. речь о php - это бесмысленная проверка. попробуйте переопределить)
Могу предположить, что код нужен. Для систем с возможностью удаления пользователей это гарантирует, что у нового пользователя не будет ID от какого-нить старого.
Соответственно следы в базе, относящиеся к старому ID не навредят новому пользователю.

Автоинкремент не гарантирует постоянное увеличение.

Хотя в любом случае - это защита от того, что надо самому же в базе подчищать или обходить иначе.
как это? автоинкремент именно это и гарантирует :)
Если ничего не поменяли, то при переходе максимально возможного ID он пойдёт заполнять "дырки", начиная с 0. И кажется я видел, что было, что и не обязательно после перехода максимума...
испугался, ибо кое-где на это завязывался. Сделал тест:
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 ()

удалил пару строчек из середины, результат - тот же.

так что не заполняет он дырки.
Значит пофиксили. Я это видел в 3.дремучем мускуле или раньше.
А установить счетчик на таблице вручную что даёт?
если на отсутствующий ID - вставляет, пока не наткнется на существующий. И все, дальше не пойдет, т.к. не может вставить
Хочу заметить, что у InnoDB значение для автоинкремента генерируется при старте БД. То есть при старте базы данных выполняется поиск максимального значения поля.
А попробуйте удалить последнюю запись и добавить новую - она получит номер уже удаленной! Это тоже неправильно, т.к. может нарушить сслочную логику.
точно :)
с другой стороны, ситуация переполненного типа сама по себе ошибочная.
Ну да :)
Но с переполнением проще бороться - можно установить integer или bigint - тогда переполнения придется долго ждать :)
Ссылочную логику нужно другими средствами беречь.
Это внутри базы, а за ее пределами?
Сейчас как раз разрабатываю систему синхронизации данных с партнерами. Недавно один объект стал лишним, его удалили, и партнеры предложили создать новый с тем же id - чтобы дырку заполнить.
Чуть не убил на месте! Битый час объяснял почему нельзя так делать!
Представьте, на первый объект накопилась информация, а дальше инфа начинает поступать для другого, но вы об этом еще не знаете. Что в итоге? Полный бред вместо информации.
Нельзя ничего вставлять в таблицу, если мы удалили запись и остались ссылки на эту запись. Ибо целостность нарушена.
В таких случаях помогает правильная проектировка базы, с ON DELETE CASCADE http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html - система сама удалит все ссылающиеся записи.
Все так. Внутри базы мы можем контролировать, но после того как система разрастется и ее надо будет интегрировать с другими системами, начнутся проблемы.
Представьте, что в других системах есть ссылки на ваши объекты (неважно какие http, по id или еще как-то). Затем объект был удален и вместо него добавлен новый с тем же id. Внешняя система начинает работать с этим объектом - вот отличный источник «веселых» ошибок.
Автоинкремент как раз гарантирует постоянное увеличение. в MyISAM БД точно.
походу я зажрался в оракле со всякими там сиквенсами...
Да, тоже хотел предложить. Но зажрался таки постгресом )
Вот меня как раз стал тут интересовать вопрос сиквенсов, не подскажите где об этом можно хорошо почитать?
автор и с наличием секвенций в субд написал бы так же %)
вот вы пишете про фиговый код, написали бы правильный вариант, чтобы новичкам понятно было, как не следует делать...
эх... были врермена писал что-то вроде этого опуса :)) стыдно :)) Но с чего-то нужно начинать. Человек просто не знает об autoincrement :)
он есть не везде, посмотрите на тот же sqlite2, в sqlite3 чтоб сделать автоинкремент и то надо поплясать с бубном
извиняюсь, только ща увидел что юзается именно mysql_query :)
Я программер. В коде вижу косяк с >=0
Других моментов, которых можно назвать косяками - не вижу. Все остальное может быть объяснено.
Автор, плиз, скажи, а где здесь бред?
Напиши код, который не использует автоинкримент (по разным причинам это может быть нужно), как-то отработает в случае, если в запросе вывалится в исключение (нет таблицы, прав или соединения с базой данных), если запрос вернет пустое количество строк или действительно вернет значение.
Может в PHP есть это все одной командой?
Я вижу 2 косяка:
1) при большом кол-ве запросов возникнут глюки вставки, когда второй запрос придет между взятием max и записью max+1 в базу
2) при удалении последней записи нарушается ссылочная целостность.

Честно говоря, я ни разу не сталкивался с ситуацией, когда нельзя было использовать автоинкрементое поле. И всегда это было самое надежное решение. Поделитесь, пожалуйста, информацией когда оно не подходит.
Поддерживаю!
Если есть какие-то сложности можно сделать в БД таблицу со счетчиками и увеличивать ее используя update. Написать хранимку в конце концов. Или триггер. ;-) Сейчас пятый мускуль уже не редкость.
Нужно помнить, что в innodb значение автоинкремента вычисляется при каждом запуске сервера БД. И после удаления последних записей из таблицы с последующим рестартом сервера опять же можем получить нарушение ссылочной целостности.
Как вариант, но, думаю, тут придется лочить таблицу или использовать транзакции, чтобы избежать все той же проблемы с двойной вставкой.
Насчет поведения автоинкрмента в innodb не знал (последнее время чаще работаю с другой БД). Это всегда так? Или можно как-то этого избежать?
Судя по всему никак.
http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html#innodb-auto-increment-traditional
Вот здесь вот подробно написано как это работает.
Я вот видел такую. Программа требовала заполнения других таблиц с ссылками на эту запись до добавления самой записи. Хотя это скорее ошибка проектирования.
+1
то что работает - написано правильно (до тех пор, пока не перестанет работать)
Единственное, что надо ответственно относиться к проектированию БД и кода, а то потом поддерживать зае...шся
В очередной раз заставило взгрустнуть о том, когда же наконец в mysql сделают sequence
Кароч. Единственное, что ясно из этого, что автор кода не читал доки по мускулу до конца и не задумывался, что перед созданием базы надо хотя бы продумать ее структуру, спросить бывалых.

ЗЫ: В данном случае автоинкремент решает все проблемы.
Еще было бы интересно увидеть каким образом индус использует эту функцию. Может там какой медитативный код, с предсказанием ID пользователя, который еще не зарегистрировался :-)
При использовании LINQ to SQL в .Net, при добавлении объекта пользователя в базу, id заполнится сам.
Dim newUser = New User() With {.Name = "Name"}
db.Users.InsertOnSubmit(newUser)
db.SubmitChanges()
return newUser.id
А ведь мог взять все записи, написать функцию сортировки массива, и взять последний элемент ;)
Кстати - подход с MAX(id) идеален для возрастающих ID, где выпады критичны. auto_increment при удалении последней записи не уменьшается.

а в остальном - wtf))
где могут быть критичны "выпады"?
ремарка: субд реляционная
вполне возможны, когда требуется строгий порядок ID, в ТЗ всё бывает

причем это логично только в том случае, если удаляются последнии записи, а не в середине.
>> в ТЗ всё бывает
да уж... ТЗ должно регламентировать результат, а не реализацию

так или иначе - конкретный жизненный пример приведёте или нет? :-)
лично в моих некоторых проектах такое требование есть - чтобы у новой записи был строго следующий идентификатор.
рациональная причина так делать будет озвучена или нет?
(прошу уже в третий раз)
строго порядковый идентификатор
это не задача, это реализация. я спрашивал о первопричинах
четвёртый раз: зачем в реляционных субд могут требоваться инкрементные поля без пробелов?
дело не в БД, а в том чем ею пользуются.
интересный поворот событий :-)
я очень удивлён, честно :-)

ps: "порядковый номер" записи в mysql можно получить и без "залатывания окон" автоинкремента, хотя и это - тоже очень странное желание :-)

впрочем, не хотите рассказывать, не надо :-Р
"кто как играет..."
Подскажите вот здесь ..$record[0]+1.. "+1" зачем? Нехватает фантазии? )
мой мозг
какие каменты
бл%дь
бл%дь
бл%дь
ребята
это
жесточайший
пи%дец
может, вы ещё и минусуете топик, потому что не можете понять, где тут бред?
Ааа... я прослезился. Когда стажером писал программку в MS Access, приблизительно так же регистрировал новые записи фильмов и компаний в БД. Зато работало! :)

Жалко ее код я уже давно потерял, сейчас было бы ржачно наверно.
Sign up to leave a comment.

Articles