Comments 95
Первый пример просто убил. Сразу видно: автор долго сидел над оптимизацией
+6
А мне, представьте, пришлось менять разбросанные от 1 до 10 000 000 айдишки на упорядоченные в основной и связанных таблицах (благо, структура ДБ не блистает оригинальностью).
+2
Я, конечно, представлял, что новички могут ошибаться… Но чтобы рабочий проект, да так…
Однако неплохая база, в которой 10 000 000 записей, значит и проект не просто хомяк :)
Уверен, тяжело вам пришлось!
Однако неплохая база, в которой 10 000 000 записей, значит и проект не просто хомяк :)
Уверен, тяжело вам пришлось!
+1
И не дай боже foreign keys (me вздрагивает)
0
Вполне себе адекватный код. Возможно, поолезно, когда злоумышленник можетчто-то сделать при добавлении в базу, зная id который получится. Или, например, чтобы максимальный id реально не соответствовал количству чего-то(например, вы не хотите показывать количество сообщений на форуме, однако, запостив одно сообщение, злоумышленник сможет приблизительно узнать их количество)
-1
Тем боле, из кода не ясно, что id это message_real_id а не message_fake_id, например.
-1
Опасный тип этот злоумышленник — знает количество сообщений на форуме! =)
(кстати, на вышеупомянутом сайте было написано сколько элементов в этой таблице).
Если кто-то может что-то нехорошее сделать зная id, то нужно удалить весь код и писать заново.
(кстати, на вышеупомянутом сайте было написано сколько элементов в этой таблице).
Если кто-то может что-то нехорошее сделать зная id, то нужно удалить весь код и писать заново.
+3
Это адекватный код? Генерировать десяток, а то и сотню ошибок базы на ровном месте… это как-то очень неадекватно. А в тех случаях, когда не нужно, чтобы пользователи знали количество, делается просто дополнительный столбец id, выборка по которому идет на сайте. К PK это иметь отношение не должно. Такое бывает, например, с количеством интернет-заказов в магазине.
+1
кто мешает сделать нормальный id по auto_increment и второе поле с id или словами или даже с хэшами, которые будут видеть пользователи?
+1
Это называется security through obscurity и является абсолютным бредом.
+1
мне это показалось банальной диверсией
+1
Интересно еще, что в случае достаточно старой версии PHP (до 4.2.0) и забытого srand() в первом примере каждый раз одна и та же цепочка «случайных» чисел будет генерироваться.
+1
А в новом думаете не будет? mt_rand должен дать немного больше чисел в последовательности, но в любом случае БД может хранить больше :)
0
Пожалуй смешнее всего будет, если это запустят под Windows, где очень маленькая длинна последовательности.
0
Не будет. srand() и mt_srand() делаются автоматически с 4.2.0.
mt_rand в состоянии давать равномерно распределенные псевдо-случайные числа от 1 до 231 — 1, период у нее вообще огромен, короче, для целей генерации уникального INT id более чем подходит.
mt_rand в состоянии давать равномерно распределенные псевдо-случайные числа от 1 до 231 — 1, период у нее вообще огромен, короче, для целей генерации уникального INT id более чем подходит.
+1
Тут дело не в качестве псевдослучайной последовательности. Просто если цепочка будет повторятся каждый раз, то этот кусок кода будет проверять сначала все числа, которые уже содержаться в БД, и только после этого находить псевдослучайное число, отсутствующие в БД. Соответственно если мы добавим 100000-ную запись в БД, то и цикл поиска свободного id тоже прокрутиться 100000 раз, и столько же будет попыток INSERT'а.
+1
ну я буквально вчера вычислял число по модулю воттак: y=x*((x>0)-0,5)*2 эта привычка(логику в вычисления писать) еще со времен спектрума меня по сей день преследует.
Иногда такие размашистые формулы получались :)
Иногда такие размашистые формулы получались :)
+4
>С математической точки зрения, условие «sqrt(x) = x/sqrt(x)» выполняется всегда,
0
Ой, случайно отправил.
>С математической точки зрения, условие «sqrt(x) = x/sqrt(x)» выполняется всегда.
Я зануда — при x=0 не выполняется.
>С математической точки зрения, условие «sqrt(x) = x/sqrt(x)» выполняется всегда.
Я зануда — при x=0 не выполняется.
+2
В копилку:
if 1 == 2: # блин, этот участок кода никогда не выполняется :(
Причина: 1 не равен 2-м
Совет: используйте «if 1 == 1: ...»
if 1 == 2: # блин, этот участок кода никогда не выполняется :(
Причина: 1 не равен 2-м
Совет: используйте «if 1 == 1: ...»
+3
Да это просто такой способ закомментировать кусок кода. Не знаю, почему его используют, но я частенько встречал такое.
Могу предположить, что там изначально стояло другое, осмысленное условие, но в процессе отладки оно многократно менялось, и/или автор не захотел вымарывать большой кусок кода полностью, а закомментировать было лень, и/или в этом блоке используется альтернативный вариант алгоритма или неиспользуемая на данный момент недописанная функциональность и автор хотел сохранить его на будущее (а если закомментируешь, то другой программист или даже сам можешь случайно стереть закомментированный код, как ненужный), вот и оставил такое.
После рефакторинга, скорее всего, этот кусок был бы удалён, но когда проект уже работает, может быть не до рефакторинга — работает, значнит ничего не трогай :)
Сам я часто использовал такой кусок:
a = 1
if a == 2 call somefunction
и т.д.
чтобы иметь возможность в режиме отладки вызвать какую-нибудь функцию, которая в нормальном режиме работы программы не нужна.например, просмотреть статус какого-нибудь объекта, записать что-нибудь в лог и т.п.
потому что изменить значение переменной «а» в отладчике легко, а вот вызвать какую-нибудь произвольную функцию скорей всего невозможно (в firebug возможно всё, потому я больше не пользуюсь таким приёмом :)
Могу предположить, что там изначально стояло другое, осмысленное условие, но в процессе отладки оно многократно менялось, и/или автор не захотел вымарывать большой кусок кода полностью, а закомментировать было лень, и/или в этом блоке используется альтернативный вариант алгоритма или неиспользуемая на данный момент недописанная функциональность и автор хотел сохранить его на будущее (а если закомментируешь, то другой программист или даже сам можешь случайно стереть закомментированный код, как ненужный), вот и оставил такое.
После рефакторинга, скорее всего, этот кусок был бы удалён, но когда проект уже работает, может быть не до рефакторинга — работает, значнит ничего не трогай :)
Сам я часто использовал такой кусок:
a = 1
if a == 2 call somefunction
и т.д.
чтобы иметь возможность в режиме отладки вызвать какую-нибудь функцию, которая в нормальном режиме работы программы не нужна.например, просмотреть статус какого-нибудь объекта, записать что-нибудь в лог и т.п.
потому что изменить значение переменной «а» в отладчике легко, а вот вызвать какую-нибудь произвольную функцию скорей всего невозможно (в firebug возможно всё, потому я больше не пользуюсь таким приёмом :)
+4
меня спасает добавочная "|| 0" ;-)
0
Ну, в Си очень удачно можно пользоваться макросами для получения «кроссплатформенного» кода.
#ifdef SOME_FLAG
…
#else
…
#endif
#ifdef SOME_FLAG
…
#else
…
#endif
0
Такое комментирование встречается (правда, в форме #if 0) в случае, когда внутри фрагмента уже есть нормальные языковые комментарии и обернуть их стандартно уже нельзя.
Некоторые редакторы, кстати, помечают блок между #if 0 и #endif как комментарий.
Некоторые редакторы, кстати, помечают блок между #if 0 и #endif как комментарий.
+1
В существование первого примера просто не верится. Это уже не кодобред, а КодоПЦ какой то… что ж у него там будет когда 10 млн достаточно плотно наполнятся, ужос…
+1
Чесное слово, так и было! Я бы сам не поверил, наверное.
0
Как уже писали выше, сам подход вставления рандомного id может быть оправдан (у самого возникала иногда потребность).
Код же как он написан, является бомбой замедленного действия, как потому, что будет прогрессирующий апокалипсис при количестве записей, приближающемся к 10 млн, так и потому, что забивается на то, почему собственно был mysql_error() — может база отключилась.
Код же как он написан, является бомбой замедленного действия, как потому, что будет прогрессирующий апокалипсис при количестве записей, приближающемся к 10 млн, так и потому, что забивается на то, почему собственно был mysql_error() — может база отключилась.
0
Из любопытности, в каком случае случайный идентификатор может быть оправдан?
+1
Ну, например, чтобы скрыть (или сделать менее предсказуемыми) связи в системе.
У Дурова id в контакте 1, сразу интересно, у кого 2, 3 и т.д., т.е. можно делать какие-то выводы о том, как стартовал проект, о личных связях г-на Дурова, например.
В конце концов, это доп. звено в цепи security through obscurity: если злоумышленник не может предсказать идентификаторы внутри вашей системы, ломать ему будет сложней.
У Дурова id в контакте 1, сразу интересно, у кого 2, 3 и т.д., т.е. можно делать какие-то выводы о том, как стартовал проект, о личных связях г-на Дурова, например.
В конце концов, это доп. звено в цепи security through obscurity: если злоумышленник не может предсказать идентификаторы внутри вашей системы, ломать ему будет сложней.
0
Мне кажется для таких целей проще сделать еще одно поле в таблице, куда писать уникальную строку (UNIQUE).
Использование же праймари ключ таким образом…
Я наверное сегодня ночью не усну, после увиденого кода…
Использование же праймари ключ таким образом…
Я наверное сегодня ночью не усну, после увиденого кода…
+3
Непонятно, почему проще. Ваша строка просто будет вторым праймари ключом, который точно так же надо будет заполнять уникальными значениями.
-1
Проще в том плане, что в этой строке вы сможете использовать не только цифры, но и буквы, и к примеру работать уже с 16-тиричными числами (правда что-то я не припомню генератора случайных HEX чисел), а это означает, что сгенерировать такое же число которое есть становится в разы тяжелей. Это только одна из причин.
0
Как вариант — табличка сообщений в базе для JMS. сообщений может вставляться в табличку сотни в секунду, но время жизни у них короткое.
+1
Ох… Даже продолжать не хочется. Тема древна, как Мир. Программирования, понятно. Где-то слышал — программирование, как культура.
Что же делать — давайте двигаться к этой культуре.
Кстати, по первой незадаче — можно же max(id)+1. Если в транзакции.
Что же делать — давайте двигаться к этой культуре.
Кстати, по первой незадаче — можно же max(id)+1. Если в транзакции.
+1
Ну транзакции-то они вроде не существуют в MySQL?
-2
Почему? InnoDB пока никто не отменял…
0
Да существуют они там давно. Вот только вложенных транзакций вроде еще нет. Далековато в этом смысле еще до Оракла.
0
По первой задаче лучше все-таки чтобы поле id было auto_increment и тогда так:
INSERT INTO `table` SET login='my_login' AND ...→
SELECT LAST_INSERT_ID()
+1
max(id)+1 — это лишний поиск в индексе…
0
Исправьте операцию присваивания на сравнение, во втором примере:
if sqrt(x) = x/sqrt(x)
+1
Паскаль не позволил бы вам выстрелить себе в ногу перенести сегмент стека :)
Хочется верить, что на ассемблере пишут только профессионалы. Страшно представить, что бы творилось, будь он проще для освоения/популярнее.
Хочется верить, что на ассемблере пишут только профессионалы. Страшно представить, что бы творилось, будь он проще для освоения/популярнее.
+2
Видимо при написании ассемблерного кода человек не знал, что ss это не регистр общего назначения, и дергать его без особой надобности не стоит.
0
Насчет первого примера я сам видел кусок типа crc32(microtime()) и обрезанием -. Очень замечательный код, который на 100000 запросах уже давал 5% повторных ид.
0
Во всех случаях заказчики просили скрыть или заменить id,
вопервых потому что слишком маленький или по другой причине.
Нельзя брать кусок кода и сразу делать выводы.
К моменту разработки такое решение могло оказаться максимально приемлемым!
А тут пытаются…
Корме того есть понятие application lifetime по истечении которого надо делать
refactoring.
Что Вы судя по всему успешно и сделали.
вопервых потому что слишком маленький или по другой причине.
Нельзя брать кусок кода и сразу делать выводы.
К моменту разработки такое решение могло оказаться максимально приемлемым!
А тут пытаются…
Корме того есть понятие application lifetime по истечении которого надо делать
refactoring.
Что Вы судя по всему успешно и сделали.
0
Ну а как же классика?
Проверка на true:
bool value;
…
if (value.ToString().Length == 4)
{
…
}
Проверка на true:
bool value;
…
if (value.ToString().Length == 4)
{
…
}
+2
да, машинная точность это тема. Попробуйте например в питоне вот это:
0.3==1-0.7
0
> Совет. Понять свой код. Убедиться в том, что в программе протекают задуманные процессы.
Совет. Чтобы понять свой код нужно написать тест к этому коду.
Совет. Чтобы понять свой код нужно написать тест к этому коду.
+1
UFO just landed and posted this here
Есть у меня один приятель. Писал он логгер для одной большой системы, который скидывал различные записи в файл.
так вот алгоритм открытия файла у него выглядел следующим образом:
// Псевдокод:
while(!file.Open())
{
// Подождем еще немножко
thread.Sleep(1000);
}
P.S. Комментарий в коде выглядел именно так, как привел его я :)
так вот алгоритм открытия файла у него выглядел следующим образом:
// Псевдокод:
while(!file.Open())
{
// Подождем еще немножко
thread.Sleep(1000);
}
P.S. Комментарий в коде выглядел именно так, как привел его я :)
0
> upd: Ввиду появления большого количества защитников «случайных» идентификаторов в таблицах БД,
> отвечу всем сразу: если необходимо скрыть реальные ID, нужно использовать mod_rewrite, а не коверкать БД.
В данном случае можно задействовать линейное преобразование:
externalID = ((internalID + Q1) * Q2) mod Q3
Q2 и Q3 должны быть взаимно простыми, тогда соответствие гарантированно будет однозначным. Максимальное количество пользователей будет равно Q3 (internalID от 0 до Q3-1).
internalID может быть auto_increment, а externalID вычислимым полем (вроде, поддерживаются они в MySQL?)
Ну а в MS SQL можно использовать uniqueidentifier (GUID).
> отвечу всем сразу: если необходимо скрыть реальные ID, нужно использовать mod_rewrite, а не коверкать БД.
В данном случае можно задействовать линейное преобразование:
externalID = ((internalID + Q1) * Q2) mod Q3
Q2 и Q3 должны быть взаимно простыми, тогда соответствие гарантированно будет однозначным. Максимальное количество пользователей будет равно Q3 (internalID от 0 до Q3-1).
internalID может быть auto_increment, а externalID вычислимым полем (вроде, поддерживаются они в MySQL?)
Ну а в MS SQL можно использовать uniqueidentifier (GUID).
+1
Ввиду появления большого количества защитников «случайных» идентификаторов в таблицах БД, отвечу всем сразу: если необходимо скрыть реальные ID, нужно использовать mod_rewrite, а не коверкать БД.
А тормоза учитывали? — тут вам не простой регэксп написать. А если не апач и вообще не веб?
Я и сам могу выдумать много способов, как скрыть реальные ID, и мне даже больше о душе «не коверкать БД», но дело-то не в этом. Дело в том, что «защитники», в частности, я, утверждают, что такой подход имеет смысл и право на существование, вы же упорно списываете его в кодобред.
0
К слову о #define true false
karbas@arc|~$ python --version
Python 2.5.1
karbas@arc|~$ python -c 'print 1==1
True = False
print True'
True
False
karbas@arc|~$ python --version
Python 2.5.1
karbas@arc|~$ python -c 'print 1==1
True = False
print True'
True
False
0
еще о #define true false — в Javascript волшебные последствия может иметь строчка наподобие
Нет гарантий, что некий не слишком эрудированный кодер не выберет для своей переменной такое говорящее имя, а последовать могут всякие странности типа обращений к несуществующим полям и объектам там, где всё, казалось бы, проверяется, в чужих, сторонних, «взрослых» библиотеках. Кстати, и защита от этой пакости тоже есть: если ваша библиотека изолирована в функцию (так обычно делают всякие «приватные» поля и методы, см. классиков), можно объявить в ней
undefined = true;
. Нет гарантий, что некий не слишком эрудированный кодер не выберет для своей переменной такое говорящее имя, а последовать могут всякие странности типа обращений к несуществующим полям и объектам там, где всё, казалось бы, проверяется, в чужих, сторонних, «взрослых» библиотеках. Кстати, и защита от этой пакости тоже есть: если ваша библиотека изолирована в функцию (так обычно делают всякие «приватные» поля и методы, см. классиков), можно объявить в ней
var undefined;
и жить спокойно.+1
Sign up to leave a comment.
Причины и следствия