Как стать автором
Обновить

Комментарии 24

Дефективные там лонги. Ибо только со знаком. Некоторые айдишники не влезают в диапазон.
Только что проверил… Да, при вставке 0xFFFFFFFFFFFFFFFF в базу через MongoInt64 оно обрезается до 0x7FFFFFFFFFFFFFFF.
Возможно, при вставке из 64-битной версии PHP с native_long=1 ситуация будет иная. Не могу сейчас проверить.
Не будет. В самом BSON не предусмотренные беззнаковые целые.
Битовое представление 0xFFFFFFFFFFFFFFFF и -0x8000000000000000 идентично.
Поэтому если драйвер просто передает 0xFFFFFFFFFFFFFFFF как есть (а драйвер, насколько я знаю, формирует для передачи в базу сразу BSON), то и проблем быть не должно.
Ждем результатов тестов. С руби такой фокус не прокатывает.
<?php
  $x = -0x7FFFFFFFFFFFFFFF;
  $m = new Mongo();
  $c = $m->selectCollection("test", "test64");
  echo $x."\n";
  $c->remove();
  $c->insert(array("var" => $x));
  $r = $c->findOne();
  var_dump($r["var"]);
?>


Результат:

-9223372036854775807
int(-9223372036854775807)
Я думаю понятно, что -0x7FFFFFFFFFFFFFFF = 0x8000000000000000
Нее, чувак, так не пойдет. Тебе же придет огроменный айдишник без знака. Вот его ка вставь.
Ну начнем с того что этот ID даже PHP не сможет переварить — он не поддерживает беззнаковые целые.
Поэтому для работы с ним придется после получения этого ID оформить его как раз таки в знаковое.
Ну тогда либо строки, либо этот онанизм с конвертацией. Как по мне, то лучше строки. Хоть узнать айдишник можно будет глазами. Да и возможностей зафакапить меньше.
В принципе да.
У меня просто ситуация немного другая, мне именно числа нужны ))
Хотел использовать монго в своём проекте, но то, что оно не поддерживает unsigned int/long, просто выводит меня из себя. Что, если мне нужно хранить большие числа, и затем сортировать результат по ним? Если я запишу 18446744073709551616 (0xFFFFFFFFFFFFFFFF), а в базе останется -9223372036854775808 (-0x8000000000000000), то и сортировка будет происходить по signed long, т.е. неправильно. Наверное буду искать другую бд.
Почему бы для таких целей не использовать бинарную строку MongoBinData, они отлично индексируются, следовательно и сортируются…
скажите, а не логичнее ли длинные числа, над которыми не надо проводить арифметические операции, и которые берутся с внешних сервисов (а значит в какой-то момент времени могут стать к примеру 12-ти байтовыми, или вовсе не числами) хранить в строке?
Ну, с числами вроде как быстрее работает. Индексы меньше весят. И другие мелкие приятности.
У меня ситуация иная, чем у автора оригинала.
Мне нужно хранить в базе некоторую статистику, значения которой могут не помещаться в 32 бита.
И арифметические операции производить над ней надо)
Простите, но позвольте полюбопытствовать, что это за статистика?)
Не могу раскрывать подробностей.

В общих чертах: в базе хранятся результаты некоторых операций, которые имеют несколько числовых параметров.
По некоторым критериям записи из базы надо агрегировать, считая сумму некоторых из параметров. Сумма легко может вылезти за границы 32 бит.
Масштабируйте тогда значения.
И вообще, работая с такими суммами — как вы переполнения контролируете?
Или вы числа в отсортированном порядке складываете?
Есть задачка из универского курса вычислительной математики: что будет точнее —
j1 = 1:1:10000000;
a1 = sum( 1./ (j1.^2) );
j2 = 10000000:-1:1;
a2 = sum( 1./ (j2.^2) );

a1 = 1.64493396684726
a2 = 1.64493396684823
это я к тому что порядок суммирования — важная штука.
В моем примере работа с малыми числами, а в случае больших, как у вас — это еще актуальнее.
Порядок суммирования имеет значение при сложении чисел с плавающей запятой из-за изначальной неточности этих чисел.
У меня все числа целые.
Далее, у меня сумма чисел будет заведомо укладываться в 64 бита. А вот в 32 не всегда. Поэтому мою проблему статья решает на 100%, осталось дождаться переезда на новый сервер с установкой 64-битной системы (сейчас на 32-битной фре сижу).
Хммм, а если использовать не десятичную систему счисления? Операций добавится, но по размерам влезете однозначно.
Я наверное не понимаю чего то, но как от смены системы счисления изменится максимальная вместимость фиксированного количества бит?
Далеко не всегда. Ну вот я использую MongoInt64 для хранения ID пользователя в соцсети, с которой работает наше приложение. Естественно, по этому полю нужен уникальный ключ и очень много выборок из базы по этому ключу. А индекс по такому полю построить намного дешевле, чем по строке.
мы просто в своём приложении используем авторизацию через 5 соцсетей, и использовать строку приходится в любом случае для определения через какую соцсеть входит пользователь.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории