INT хранит целые числа с абсолютной точностью, а FLOAT хранит числа с плавающей запятой приблизительно, жертвуя точностью ради возможности представлять очень большие или очень маленькие значения.
Ключевые аспекты
Точность — INT всегда точен, FLOAT может иметь погрешности округления
Диапазон — FLOAT может хранить числа до 10³⁸, INT ограничен миллиардами
Дробные числа — INT не может хранить дробную часть, FLOAT может
Сравнение — INT сравнивается точно, FLOAT требует учёта погрешности
Плюсы INT
Абсолютная точность вычислений
Быстрые операции сравнения и индексации
Предсказуемое поведение
Меньше места при малых значениях
Плюсы FLOAT
Хранение очень больших и очень малых чисел
Дробные значения (проценты, координаты)
Научные вычисления с экспоненциальной записью
Частые ошибки на собеседованиях
Используют FLOAT для денег — это критическая ошибка, нужен DECIMAL
Сравнивают FLOAT через = — из-за погрешности 0.1 + 0.2 != 0.3
Не понимают разницу между FLOAT и DOUBLE — DOUBLE имеет двойную точность
Путают FLOAT с DECIMAL — DECIMAL хранит точные десятичные дроби
Введение и проблематика
Выбор между INT и FLOAT — это не просто вопрос "целые vs дробные". Это фундаментальное решение о том, нужна ли вам абсолютная точность или возможность работать с очень большими/малыми числами.
🚫
Использование FLOAT для хранения денежных сумм — классическая ошибка, которая приводит к финансовым потерям из-за погрешностей округления.
Когда это важно?
Представьте: вы храните цену товара 19.99 в FLOAT. После нескольких вычислений получаете 19.989999999999998. При отображении это может округлиться неправильно, а при суммировании миллионов транзакций погрешность становится заметной.
Базовая теория
Как хранятся числа
graphTD A[Числовые типы]--> B[Целые - INT] A --> C[С плавающей точкой - FLOAT] A --> D[Фиксированная точность - DECIMAL] B --> E[Точное хранение] C --> F[Приблизительное хранение] D --> G[Точные десятичные дроби]
INT — целые числа
INT хранит целые числа в двоичном формате. Каждое значение представлено точно, без потери данных.
text
Число 42 в INT (32 бита):00000000 00000000 00000000 00101010
FLOAT — числа с плавающей запятой
FLOAT использует стандарт IEEE 754. Число разбивается на:
Знак (1 бит)
Экспонента (8 бит для FLOAT, 11 для DOUBLE)
Мантисса (23 бита для FLOAT, 52 для DOUBLE)
text
Число 0.1 в FLOAT:Не может быть представлено точно!Хранится как ≈ 0.100000001490116119384765625
Сравнение типов
Характеристика
INT
FLOAT
DOUBLE
DECIMAL
Размер
4 байта
4 байта
8 байт
Переменный
Точность
Абсолютная
~7 цифр
~15 цифр
Точная
Дробная часть
Нет
Да
Да
Да
Макс. значение
2.1×10⁹
3.4×10³⁸
1.8×10³⁰⁸
10⁶⁵
Для денег
Нет
❌ Нет
❌ Нет
✅ Да
Практические примеры
Проблема точности FLOAT
sql
-- Создаём таблицуCREATETABLEfloat_test (valueFLOAT);-- Вставляем "простое" числоINSERT INTO float_test VALUES (0.1);-- ПроверяемSELECTvalue, value*3AS multiplied FROM float_test;-- Ожидаем: 0.1 и 0.3-- Получаем: 0.10000000149... и 0.30000000447...
⚠️
Никогда не сравнивайте FLOAT через равенство! Используйте диапазон погрешности.
sql
-- ❌ НеправильноSELECT*FROM products WHERE price =19.99;-- ✅ Правильно для FLOATSELECT*FROM products WHEREABS(price -19.99) <0.001;-- ✅ Лучше — используйте DECIMAL для ценCREATETABLEproducts ( id INTPRIMARY KEY, price DECIMAL(10, 2) -- 10 цифр всего, 2 после запятой);
Когда использовать каждый тип
sql
-- INT: счётчики, ID, количествоCREATETABLEorders ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, user_id INT UNSIGNED NOT NULL, item_count SMALLINT UNSIGNED,statusTINYINT-- 0, 1, 2, 3...);-- Идеально для:-- • Идентификаторов-- • Количества (штук, людей)-- • Статусов и флагов-- • Возраста, года
Пограничные кейсы
Переполнение и потеря точности
sql
-- INT: переполнение при превышении диапазонаINSERT INTO test (int_col) VALUES (2147483648);-- Ошибка: Out of range value-- FLOAT: потеря точности при больших числахSELECTCAST(123456789ASFLOAT);-- Может вернуть: 123456792 (потеря младших разрядов!)-- FLOAT: накопление ошибокSELECT0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1;-- Ожидаем: 1.0-- Можем получить: 0.9999999999999999 или 1.0000000000000002
🚫
При работе с большими целыми числами (больше 16 777 216 для FLOAT) возможна потеря точности даже для целой части!
Индексирование
sql
-- INT индексируется эффективноCREATEINDEXidx_user_idON orders(user_id); -- Быстро-- FLOAT можно индексировать, но поиск по = работает плохоCREATEINDEXidx_priceON products(price);SELECT*FROM products WHERE price =19.99; -- Может не найти!-- Для FLOAT лучше использовать диапазоныSELECT*FROM products WHERE price BETWEEN19.98AND20.00;
Производительность
Операция
INT
FLOAT
Сравнение
Очень быстро
Быстро
Арифметика
Быстро
Быстро (FPU)
Индексация
Эффективно
Менее эффективно
Сортировка
Быстро
Быстро
Хранение
4 байта
4 байта
Плюсы и минусы
Тип
Плюсы
Минусы
INT
Точность, скорость, простота
Нет дробной части
FLOAT
Большой диапазон, дробные числа
Погрешности, сложности сравнения
DOUBLE
Больше точности чем FLOAT
8 байт, всё ещё не точен
DECIMAL
Абсолютная точность
Медленнее, больше места
Вопросы интервьюера
Q: Можно ли использовать FLOAT для хранения цен?
Категорически нет! Используйте DECIMAL. Погрешности FLOAT приводят к ошибкам в финансовых расчётах.
Q: Чем FLOAT отличается от DOUBLE?
DOUBLE имеет двойную точность: 8 байт вместо 4, ~15 значащих цифр вместо ~7. Используйте DOUBLE для координат и научных расчётов.
Q: Почему 0.1 + 0.2 != 0.3 в FLOAT?
0.1 и 0.2 не могут быть точно представлены в двоичной системе. Сумма их приблизительных представлений даёт приблизительный результат, не равный точно 0.3.
Q: Когда использовать INT вместо FLOAT?
Всегда, когда значения целые: ID, количество, статусы, возраст. INT быстрее, точнее и проще в использовании.