1.9.5 Известные ошибки и недостатки проектирования в 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 известны следующие ошибки:
В отношении ошибок, связанных со спецификой различных платформ, см. разделы
о компилировании и переносе.
Add your own comment.