Задать вопрос
@ddakapoh

Разница в поведении FLOAT(M,D) в версиях 4.0 и 5.1?

Переношу базу с сервера на

4.0.24-standard-log (стоит на Red Hat 9.0)

на сервер

5.1.50-log FreeBSD port: mysql-server-5.1.50


И столкнулся с такой пепякой, что некоторые поля выгружаются как FLOAT[8,6], и при вставке все значений обрезаются до 100.000000. Хотя в старой версии там были и большие значения. Провел эксперимент:


В версии 4.0

mysql> create table test (amount float(8,6) NOT NULL default '0.000000');
Query OK, 0 rows affected (0.02 sec)

mysql>  insert into test values(1000);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+-------------+
| amount      |
+-------------+
| 1000.000000 |
+-------------+
1 row in set (0.00 sec)



в версии 5.1

mysql> create table test (amount float(8,6) NOT NULL default '0.000000');
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test values(1000);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from test;
+------------+
| amount     |
+------------+
| 100.000000 |
+------------+
1 row in set (0.00 sec)



тут видно, что генерится варнинг при вставке.


В документации по обоим версиям слово в слово,
dev.mysql.com/doc/refman/4.1/en/floating-point-typ...
dev.mysql.com/doc/refman/5.1/en/floating-point-typ...

и вроде как если D=6, то на целую часть остается 2 разряда и в версии 5.1 все правильно получается, но какого бага тогда в версии 4.0 оно работает иначе?


Видимо придется делить дамп на структуру и данные, дамп структуры править, убирая везде у FLOAT эти несчастные (8,6), и загружать по частям…


Есть ли другие предложения?

Может знаете другие подводные камни, на которые я еще не натолкнулся?


И еще вопрос по той же теме. В этой базе горе программисты использовали поля типа TIMESTAMP, и потом в коде юзали выборки типа
where SUBSTRING(timefrom,1,6)=201012

но беда в том, что в версии 4.0 эти даты отображаются в формате «20121203», а в версии 5.1 в формате «2012-12-03», поэтому вышеприведенный код нифига не работает. Пока решение вижу только менять в коде timefrom на timefrom+0, тогда работает корректно, но менять я заколебусь по всему коду, тем более что сложно организовать поиск всех таких мест. Может кто знает как попроще можно сделать? Может можно как-то изменить поведение TIMESTAMP для отдельной базы данных?
  • Вопрос задан
  • 3076 просмотров
Подписаться 3 Оценить Комментировать
Ответ пользователя KEKSOV К ответам на вопрос (4)
KEKSOV
@KEKSOV
Недавно столкнулся с похожей проблемой. Помогла вот эта статья. Если FLOAT в вашей базе используется для хранения «бизнес» значений (деньги и т.п.) то используйте тип DECIMAL. Во всех остальных случаях используйте DOUBLE.

FLOAT нужно всячески избегать, т.к. он в большей степени подвержен ошибкам вычисления. «Забавно» выглядит ситуация, когда после добавления в базу целого значения при выборке этой же записи получаешь какие-то единицы в девятом знаке.
Ответ написан