Известные ошибки и недостатки проектирования в MySQL
Устранение следующих из выявленных проблем относится к числу
первоочередных задач:
Следующие проблемы также известны и будут устранены в свое время:
-
При использовании функции RPAD, или любой другой строковой функции,
добавляющией пробелы в правую часть строки, в запросе, для которого MySQL
будет создавать временные таблицы для его выполнения, все результирующие
строки будут в результате обработаны RTRIM'ом (RTRIM'ed). Вот пример запроса:
SELECT RPAD(t1.field1, 50, ' ') AS f2, RPAD(t2.field2, 50, '
') AS f1 FROM table1 as t1 LEFT JOIN table2 AS t2 ON
t1.record=t2.joinID ORDER BY t2.record;
В результате невозможно получить пробелы в правой части результирующего столбца.
Такое поведение присутствует во всех версиях MySQL.
Причина заключается в том, что HEAP-таблицы, которые в первую очередь используются для временных
таблиц, неспособны работать с VARCHAR-столбцами.
Такое поведение будет исправлено в одной из версий 4.1.
-
При использовании SET CHARACTER SET нельзя использовать
преобразованные символы в именах базы данных, таблицы и столбца.
-
Нельзя использовать _ или % с ESCAPE в LIKE
... ESCAPE.
-
-
Если в столбце DECIMAL число хранится в различных форматах (+01.00,
1.00, 01.00), то GROUP BY может рассматривать каждую величину как
самостоятельную.
-
DELETE FROM merge_table при использовании без WHERE будет очищать
только отображение для этой таблицы, а не удалять все данные в
отображенных таблицах.
-
При использовании потоков MIT-pthreads нельзя расположить сервер в
ином каталоге. Поскольку для решения данной проблемы требуются
изменения для потоков MIT-pthreads, маловероятно, что мы ее устраним
(see section 2.3.6 Замечания по потокам MIT-pthreads).
-
Не обеспечивается ``надежное'' применение величин BLOB в GROUP BY или
ORDER BY или DISTINCT. В этих случаях при сравнении величин BLOB
используются только первые max_sort_length байтов (по умолчанию 1024).
Это можно изменить с помощью опции -O max_sort_length для mysqld.
Обходной путь для большинства случаев заключается в использовании
подстроки: SELECT DISTINCT LEFT(blob,2048) FROM tbl_name.
-
В сервере MySQL вычисления производятся в форматах типов BIGINT или
DOUBLE (оба типа обычно имеют длину 64 бита). Это зависит от того,
какую точность обеспечивает применяемая функция. Общее правило состоит
в том, что битовые функции работают с точностью BIGINT, функции IF и
ELT() - с точностью BIGINT или DOUBLE, а остальные - с точностью
DOUBLE. Следует избегать применения беззнаковых величин двойной
точности, если они могут превысить 63 бита (9223372036854775807), для
каких-либо величин, кроме битовых полей! В версии сервера MySQL 4.0
реализована лучшая обработка BIGINT, чем в 3.23.
-
Во всех строковых столбцах, исключая BLOB и TEXT при извлечении
данных автоматически удаляются все концевые пробелы. Для типов CHAR
это хорошо и может рассматриваться как свойство, соответствующее ANSI
SQL92. Ошибка заключается в том, что в сервере MySQL столбцы VARCHAR
трактуются тем же самым образом.
-
В одной таблице может быть только до 255 столбцов типа ENUM и SET.
-
В MIN(), MAX() и других групповых функциях, MySQL сейчас
сравнивает ENUM и SET-столбцы по их строковому значению, а не по
относительной позиции строки в множестве.
-
При указании параметра safe_mysqld все сообщения из mysqld
направляются в журнал данного потока mysqld. Одна из проблем
заключается в том, что если вы исполняете mysqladmin refresh для того,
чтобы закрыть и заново открыть журнал, то stdout и stderr будут все
еще по-прежнему направлены в старый журнал. При активном использовании
--log следует отредактировать safe_mysqld, чтобы записи велись в
``hostname`.err', а не в ``hostname`.log', с тем, чтобы вы могли очищать
пространство, удаляя старые журналы и вызывая mysqladmin refresh.
-
При выполнении команды UPDATE столбцы обновляются слева направо. При
ссылке на обновленный столбец вместо исходной величины будет получена
обновленная величина. Например:
mysql> UPDATE tbl_name SET KEY=KEY+1,KEY=KEY+1;
Эта команда обновит KEY со значением 2 вместо значения 1.
-
В одном и том же запросе нельзя использовать временные таблицы более
чем один раз. Например, следующая команда выполнена не будет:
mysql> SELECT * FROM temporary_table, temporary_table AS t2;
-
RENAME не работает с временными таблицами или при использовании
таблицы MERGE.
-
Оптимизатор может обрабатывать DISTINCT по-разному, в зависимости от
того, используются или нет в объединении ``скрытые'' столбцы. В
объединении скрытые столбцы считаются частью результата (даже если они
не показываются), в то время как в обычных запросах скрытые столбцы не
участвуют в сравнении DISTINCT. Возможно, в будущем мы изменим это
правило таким образом, чтобы при выполнении DISTINCT скрытые столбцы
никогда не сравнивались. Например:
SELECT DISTINCT mp3id FROM band_downloads
WHERE userid = 9 ORDER BY id DESC;
и
SELECT DISTINCT band_downloads.mp3id
FROM band_downloads,band_mp3
WHERE band_downloads.userid = 9
AND band_mp3.id = band_downloads.mp3id
ORDER BY band_downloads.id DESC;
Во втором случае в версии сервера MySQL 3.23.x можно получить две
идентичных строки в результирующем наборе данных (поскольку скрытый
столбец id может варьироваться). Заметьте, что это случается только с
запросами, где в результате отсутствуют столбцы ORDER BY, что не
разрешается делать в ANSI SQL.
-
Поскольку сервер MySQL обеспечивает возможность работать с типами
таблиц, которые не поддерживают транзакции и, следовательно, не
допускают отката данных, то поведение сервера MySQL в некоторых
аспектах отличается от других серверов SQL. Это делается, чтобы
гарантировать, что сервер MySQL никогда не будет нуждаться в откате
SQL-команд. Такое поведение временами может быть несколько неудобным,
так как вследствие этого величины столбцов должны проверяться в
приложении. Однако благодаря такому решению вы получаете действительно
хорошее увеличение скорости, поскольку для сервера MySQL
обеспечивается возможность производить определенные оптимизации, что в
противном случае было бы очень трудно сделать. При попытке установить
столбец в некорректную величину сервер MySQL вместо выполнения отката
будет сохранять в данном столбце ``наиболее вероятную величину'':
-
При попытке сохранить в числовом столбце величину, выходящую за
допустимые пределы, сервер MySQL вместо нее будет сохранять в
этом столбце наименьшую или наибольшую допустимую величину.
-
При попытке сохранить в числовом столбце строку, которая
начинается не с числа, сервер MySQL будет сохранять в нем 0.
-
При попытке сохранить NULL в числовом столбце, который не
принимает значения величины NULL, сервер MySQL вместо NULL будет
сохранять 0 или '' (пустая строка) (однако это поведение можно
изменить с помощью опции компиляции -DDONT_USE_DEFAULT_FIELDS).
-
MySQL обеспечивает возможность сохранять некоторые ошибочные величины даты в
столбцах DATE и DATETIME (такие как 2000-02-31 или 2000-02-00).
Идея заключается в том, что задача проверки валидности даты не входит в круг
обязанностей сервера баз данных. Если MySQL может сохранить и корректно
воспроизвести какие-либо значение даты, пусть и неправильное - MySQL будет
сохранять такое значение. Если дата полностью неправильна, сервер MySQL будет
сохранять в этом столбце специальную величину даты 0000-00-00.
-
Если устанавливать столбец ENUM в неподдерживаемую величину, то
он будет устанавливаться в значение ошибки empty string с
числовым значением 0.
-
Если устанавливать столбец SET в неподдерживаемую величину, то
эта величина будет игнорироваться.
-
При выполнении PROCEDURE на запросе, возвращающем пустой набор, в
некоторых случаях PROCEDURE не будет преобразовывать столбцы.
-
При создании таблицы типа MERGE не происходит проверки, если лежащие в
ее основе таблицы имеют совместимые типы.
-
Сервер MySQL пока еще не может обрабатывать величины NaN, -Inf и Inf с
двойной точностью. Их использование вызовет проблемы при попытке
экспорта или импорта данных. В качестве промежуточного решения мы
должны изменить NaN на NULL (если возможно) и -Inf и Inf на
минимальную или, соответственно, максимально возможную величину
двойной точности.
-
LIMIT на отрицательных числах трактуются как большие положительные
числа.
-
Если ALTER TABLE используется для того, чтобы сначала добавить индекс
UNIQUE к таблице, которая входит в таблицу MERGE, а затем - чтобы
добавить обычный индекс к таблице MERGE, то в случае, если существовал
старый ключ, который не был уникальным в данной таблице, порядок
ключей для таблиц будет различным. Это обусловлено тем, что ALTER
TABLE помещает уникальные ключи перед обычными ключами, чтобы
обеспечить возможность определять дублирующиеся ключи как можно
раньше.
В более ранних версиях MySQL известны следующие ошибки:
В отношении ошибок, связанных со спецификой различных платформ, см. разделы
о компилировании и переносе.
Содержание раздела