Преобразование типов MySQL: почему число с плавающей точкой является наименьшим общим знаменателем? - PullRequest
1 голос
/ 20 мая 2009

Недавно я столкнулся с проблемой, когда запрос вызывал полное сканирование таблицы, и выяснилось, что столбец имеет другое определение, которое, как мне показалось, было VARCHAR, а не INT. При запросе «string_column = 17» запрос выполнялся, он просто не мог использовать индекс. Это действительно бросило меня в тупик.

Итак, я отправился на поиски и обнаружил, что произошло, поведение, которое я видел, соответствует тому, что Документация MySQL говорит:

Во всех других случаях аргументы сравниваются как действительные числа с плавающей точкой.

Итак, мой вопрос ... почему поплавок?

Я мог бы попытаться преобразовать числа в строки (хотя приведенные выше пункты на странице MySQL являются вескими причинами, чтобы этого не делать). Я также мог понять, что выбрасывает какую-то ошибку или генерирует предупреждение (мое предпочтение). Вместо этого он счастливо бежит.

Так зачем конвертировать все в число с плавающей точкой? Это из стандарта SQL или по какой-то другой причине? Кто-нибудь может пролить свет на этот выбор для меня?

Ответы [ 2 ]

2 голосов
/ 20 мая 2009

Я чувствую твою боль. У нас есть столбец в нашей БД, который содержит то, что в компании известно как «номер заказа». Но это не всегда число, в определенных обстоятельствах оно может иметь и других символов, поэтому мы храним его в varchar. В SQL Server 2000 это означает, что выбор по "order_number = 123456" плох. SQL Server эффективно переписывает предикат как "CAST(order_number, INT) = 123456", что имеет два нежелательных эффекта:

  1. индекс включен order_number как varchar, поэтому он запускает полное сканирование
  2. эти нечисловые порядковые номера в конечном итоге приводят к возникновению ошибки преобразования для пользователя с довольно бесполезным сообщением.

В некотором смысле, хорошо, что у нас есть эти нечисловые «числа», поскольку по крайней мере плохо написанные запросы, которые передают параметр в виде числа, попадают в ловушку, а не просто поглощают ресурсы.

Я не думаю, что есть стандарт. Кажется, я помню, что PostgreSQL 8.3 отбросил некоторые приведения по умолчанию между числовым и текстовым типами, чтобы такая ситуация приводила к ошибке при планировании запроса.

Предположительно, "float" считается самым широким числовым типом и, следовательно, тем, к которому все числа могут быть беззвучно повышены?

Да, и аналогичные проблемы (но без ошибок преобразования) для случаев, когда у вас есть столбцы varchar и приложение Java, которое передает все строковые литералы как nvarchar ... внезапно ваши индексы varchar больше не используются, удачи в поиске случаев этого происходит. Конечно, вы можете сказать Java-приложению отправлять строки как varchar, но теперь мы застряли с использованием только символов в windows-1252, потому что это то, для чего БД была создана 5-6 лет назад, когда она была просто «решением для временной остановки». ах-ха.

0 голосов
/ 20 мая 2009

Ну, это легко понять: float может хранить самый большой диапазон чисел.

Если базовый тип данных, например, datetime, его можно просто преобразовать в число с плавающей точкой, имеющее то же внутреннее значение.

Если тип данных - string, его легко разобрать в число с плавающей запятой, что не может не сказаться на производительности.

Так что тип данных с плавающей точкой лучше использовать в качестве запасного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...