#1 06.07.12 23:23
PHP + mysqli + bigint
Использую mysqli, prepared statement, ибо дофига однотипных запросов вставки. Прирост это дает реально на порядок.
Но столкнулся с проблемой.
У меня есть поле UNSIGNED BIGINT (2^64, 0-18446744073709551615)
PHP нормально переваривает эти числа, а так же математические операции с ними
MySQL в общем-то тоже, если писать запрос вида "INSERT INTO t1(data1) VALUES('18446744073709551614')"
А если тоже самое делать через mysqli, то там есть только тип данных integer
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packet
и при вставке чего-то типа 3000000000 получаем преобразование в знаковое int, потом опять в беззнаковое longlong и на выходе вместо 3млн будет ~1.8Е+19 (с точностью до знака конечно, влом считать сколько)
$insert=$mysqli->prepare("INSERT INTO t1 (data1) VALUES(?)");
$insert->bind_param("i",$data);
можно ли как-то это обойти лучше, чем разбить на несколько INSERT-ов вида:
$data1=floor($data/2000000000);
$data2=$data%2000000000;
$insert=$mysqli->prepare("INSERT INTO t1 (data1) VALUES(?*2000000000)");
$insert->bind_param("i",$data1);
$insert=$mysqli->prepare("UPDATE t1 SET data1=data1+? WHERE предположим тут ключ от предыдущей вставки");
$insert->bind_param("i",$data2);
Мне уже кажется что на обычные запросы лучше откатиться, чем mysqli, если решения с 64бит целыми не будет
Offline
#2 07.07.12 10:44
Re: PHP + mysqli + bigint
Макс,
1. если математически преобразования целиком на уровень php перенести,
2. если кроме приложения никто руками не пишет в базу
то храни в базе числа как строчки.
при выборке, преобразуешь в числа.
Но это все равно костыль. Некий прогиб по перформансу точно будет, да и если выбрать в сортированном виде, то строки не как числа сравниваются.
Предыдущее решение оч. плохое решение по перформансу. Операции деления и взятия остатка - одни из самых медленных.
Если есть возможность, лучше выбрать базу, которая удовлетворяет требованиям по типам.
Offline
#3 07.07.12 22:43
Re: PHP + mysqli + bigint
sav написал(а):
то храни в базе числа как строчки.
не вариант, потом с ними делается куча выборок с суммированием
по перфомансу не знаю.. числа 64 бит, архитектура 32бит (исторически, железо конечно поддерживает 64). Будет ли прирост, если переехать на 64бит архитектуру? а может и бага исчезнет? может кто проверить?
sav написал(а):
Операции деления и взятия остатка - одни из самых медленных
можно в принципе сделать сдвиг на 16 разрядов к примеру
ну и из общего количества инсертов тех, что с большими числами - меньше 0.1%, так что в принципе можно себе такое позволить
я сделал: if (большое число) {2 prepared инсерта частями} else {обычный prepared инсерт }
ну или как решение, if (число большое) {обычный НЕ prepared инсерт} else {обычный prepared инсерт }
и наверное это лучший вариант
Offline

