XOOPS Brasil

 

1.8. Qual compatibilidade aos padrões o MySQL oferece ?

Esta seção descreve como o MySQL se relaciona aos padrões ANSI/ISO SQL. O Servidor MySQL tem muitas extensões aos padrões SQL, e aqui você descobrirá quais são elas, e como usá-las. Você irá também encontrar informação sobre falta de funcionalidade do Servidor MySQL, e como trabalhar com algumas diferenças.

Nosso objetivo é não restringir, sem um boa razão, a usabilidade do MySQL Server para qualquer uso. Mesmo se não tivermos os recursos para fazer o desenvolvimento para todos os usos possíveis, estamos sempre querendo ajudar e oferecer sugestões para pessoas que estão tentando usar o MySQL Server em novos territórios.

Um dos nossos principais objetivos com o produto é continuar a trabalhar em acordo com o padrão SQL-99, mas sem sacrificar velocidade e confiança. Não estamos receosos em adicionar extensões ao SQL ou suporte para recursos não SQL se ele aumentar extremamente a usabilidade do MySQL Server para uma grande parte de nossos utilizadores. (A nova interface HANDLER no MySQL Server 4.0 é um exeemplo desta estratégia. Veja mais informações sobre isto na Seção 6.4.9, “Sintaxe HANDLER.)

Continuaremos a suportar bancos de dados transacionais e não transacionais para satisfazer tanto o uso pesado na web quanto o uso de missão crítica 24/7.

O MySQL Server foi projetado inicialmente para trabalhar com bancos de dados de tamanho médio (10-100 milhões de registros ou cerca de 100 MB por tabela) em sistemas computacionais pequenos. Continuaremos a extender o MySQL Server para funcionar ainda melhor com banco de dados na ordem de terabytes, assim como tornar possível compilar uma versão reduzida do MySQL mais apropriadas para handhels e uso embutido. O design compacto do servidor MySQL tornam ambas as direções possíveis sem qualquer conflito na árvore fonte.

Atualmente não estamos buscando suporte em tempo real (mesmo se você já puder fazer muitas coisas com nossos serviços de replicação).

Suporte a banco de dados em cluster está planejado para 2004 pela implementação de um novo mecanismo de armazenamento.

Estamos buscando melhoras no fornecimento de suporte a XML no servidor de banco de dados.

1.8.1. Qual Padrão o MySQL Segue?

Entry-level SQL-92. ODBC levels 0-3.51.

We are aiming toward supporting the full SQL-99 standard, but without concessions to speed and quality of the code.

1.8.2. Executando o MySQL no modo ANSI

Se você inicializa o mysqld com a opção --ansi ou --sql-mode=ANSI, o seguinte comportamento é alterado no MySQL:

  • || é um oprador de concatenação de strings em vez de um sinônimo para OR.

  • "’ é tratado como um caracter identificados (com o caracter de aspasr ‘`’ do MySQL Server)e não um caracter de string. Você ainda pode usar ‘`’ para citar identificadores no modo ANSI. Uma implicação disto é que você não pode usar aspas duplas para citar um string literal, porque ela será intepretada como um identificador.

  • Você pode ter qualquer número de espaços entre um nome de função e o ‘(’. Isto faz com que todos nomes de funções sejam tratadas como palavras reservadas. Como resultado, se você quiser acessar qualquer banco de dados, tabelas ou coluna que é uma palavra reservada, você deve colocá-lo entre aspas. Por exemplo, por haver a função USER(), o nome da tabela user no banco de dados mysql e a coluna User nesta tabela se torna reservada, assim você deve colocá-la entre aspas:

    SELECT "User" FROM mysql."user";
    
  • REAL é um sinônimo para FLOAT no lugar de um sinônimo de DOUBLE.

  • O nível de isolamento padrão de um transação é SERIALIZABLE. Veja mais informações sobre isto na Seção 6.7.6, “Sintaxe SET TRANSACTION.

  • Você pode usar um campo/expressão em GROUP BY que não está na lista de campos.

Executando o servidor em modo ANSI é o mesmo que iniciá-lo com estas opções:

--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES, IGNORE_SPACE,ONLY_FULL_GROUP_BY --transaction-isolation=serializable

No MySQL 4.1, você pode conseguir o mesmo efeito com estas duas instruções:

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET GLOBAL sql_mode=
"REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY";

No MySQL 4.1.1 a última opção sql_mode também pode ser dada com:

SET GLOBAL sql_mode="ansi";

No caso acima o sql_mode estará configurado com todas as opções que são relevantes para o modo ANSI. Você pode verificar o resultado fazendo:

mysql> SET GLOBAL sql_mode="ansi";
mysql> SELECT @@GLOBAL.sql_mode;
-> "REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI"

1.8.3. Extensões do MySQL para o Padrão SQL-92

O MySQL fornece algumas extensões que você provavelmente não irá encontrar em alguns bancos de dados SQL. Fique avisado que se você usá-las, seu código pode não ser mais portável para outros servidores SQL. Em alguns casos, você pode escrever código que inclui extensões MySQL, mas continua portável, usando comentários da forma /*! ...*/. Neste caso, o MySQL irá analisar e executar o código com o comentário como irá fazer com qualquer outra instrução MySQL, mas outros servidores SQL irão ignorar as extensões. Por exemplo:

SELECT /*! STRAIGHT_JOIN */ nome_campo FROM table1,table2 WHERE ...

Se você adicionar um número de versão depois do '!', a sintaxe só será executada se a versão do MySQL é igual ou maior que o número de versão usado:

CREATE /*!32302 TEMPORARY */ TABLE t (a INT);

O exemplo acima significa que se você tiver uma versão do MySQL 3.23.02 ou mais nova, então o MySQL irá usar a palavra-chave TEMPORARY

Extensões MySQL são listadas abaixo:

  • Os tipos de campo MEDIUMINT, SET, ENUM e os diferentes tipos BLOB e TEXT.

  • Os atributos de campos AUTO_INCREMENT, BINARY, NULL, UNSIGNED e ZEROFILL.

  • Todas comparações de strings por padrão são caso insensitivo, com classificação ordenada determinada pelo conjunto de caracteres corrente (ISO-8859-1 Latin1 por padrão). Se você não gosta disso você deverá declarar suas colunas com o atributo BINARY ou usar o operador BINARY, que fazendo com que as comparações sejam feitas de acordo com a ordem ASCII usada na máquina servidora do MySQL.

  • O MySQL mapeia cada banco de dados em um diretório sob o diretório de dados do MySQL, e tabelas internamente num banco de dados para arquivos no diretório do banco de dados.

    Isto tem algumas implicações:

    • Nomes de bancos de dados e tabelas são caso sensitivoo no MySQL em sistemas operacionais que possuem o sistema de arquivos caso sensitivoo (como na maioria dos sistemas Unix). Veja mais informações sobre isto na Seção 6.1.3, “Caso Sensitivo nos Nomes”.

    • Nomes de Bancos de dados, tabelas, índices, campos ou apelidos pode começar com um dígito (porém não podem consistir somente de digitos).

    • Você pode usar comandos padrão do sistemas para fazer backups, renomear, apagar e copiar tabelas. Por exemplo, para renomear uma tabela, renomeie os arquivos .MYD, .MYI e .frm. para o nome da tabela correspondente.

  • Em algumas instruções SQL, você pode acessar tabelas de diferentes bancos de dados com a sintaxe nome_bd.nome_tbl. Alguns servidores SQL fornecem a mesma funcionalidade mas chamam isto de User space. O MySQL não suporta tablespaces como em: create table ralph.my_table...IN minha_tablespace.

  • LIKE é permitido em campos numéricos.

  • O uso de INTO OUTFILE e STRAIGHT_JOIN em uma instrução SELECT. Veja mais informações sobre isto na Seção 6.4.1, “Sintaxe SELECT.

  • A opção SQL_SMALL_RESULT em uma instrução SELECT.

  • EXPLAIN SELECT para obter uma descrição de como as tabelas são ligadas.

  • A utilização de nomes de índices, índices em um prefixo de um campo, e uso de INDEX ou KEY em uma instrução CREATE TABLE. Veja mais informações sobre isto na Seção 6.5.3, “Sintaxe CREATE TABLE.

  • O uso de TEMPORARY ou IF NOT EXISTS com CREATE TABLE.

  • O uso de COUNT(DISTINCT lista) onde 'lista' é maior que um elemento.

  • O uso de CHANGE nome_campo, DROP nome_campo, ou DROP INDEX, IGNORE ou RENAME em uma instrução ALTER TABLE. Veja mais informações sobre isto na Seção 6.5.4, “Sintaxe ALTER TABLE.

  • O uso de RENAME TABLE. Veja mais informações sobre isto na Seção 6.5.5, “Sintaxe RENAME TABLE.

  • Utilização de múltiplas cláusulas ADD, ALTER, DROP, ou CHANGE em uma instrução ALTER TABLE.

  • O uso de DROP TABLE com as palavras-chave IF EXISTS.

  • Você pode remover múltiplas tabelas com uma instrução única DROP TABLE.

  • As cláusulas ORDER BY e LIMIT das instruções UPDATE e DELETE.

  • Sintaxe INSERT INTO ... SET col_name = ....

  • A cláusula DELAYED das instruções INSERT e REPLACE.

  • A cláusula LOW_PRIORITY das instruções INSERT, REPLACE, DELETE e UPDATE.

  • O uso de LOAD DATA INFILE. Em alguns casos essa sintaxe é compatível com o Oracle LOAD DATA INFILE. Veja mais informações sobre isto na Seção 6.4.8, “Sintaxe LOAD DATA INFILE.

  • As intruções ANALYZE TABLE, CHECK TABLE, OPTIMIZE TABLE, e REPAIR TABLE.

  • A instrução SHOW. Veja mais informações sobre isto na Seção 4.6.8, “Sintaxe de SHOW.

  • Strings podem ser fechadas pelo ‘"’ ou ‘'’, não apenas pelo ‘'’.

  • O uso do meta-caractere de escape ‘\’.

  • A instrução SET OPTION. Veja mais informações sobre isto na Seção 5.5.6, “Sintaxe de SET.

  • Você não precisa nomear todos os campos selecionados na parte GROUP BY. Isto fornece melhor performance para algumas consultas específicas, mas muito comuns. Veja mais informações sobre isto na Seção 6.3.7, “Funções e Modificadores para Usar com Cláusulas GROUP BY.

  • Pode ser especificado ASC e DESC com o GROUP BY.

  • Para tornar mais fácil para utilizadores que venham de outros ambientes SQL, o MySQL suporta apelidos (aliases) para várias funções. Por exemplo, todas funções de string suportam as sintaxes ANSI SQL e ODBC.

  • O MySQL entende os operadores || e && como ou(OR) e e(AND) logicos, como na linguagem de programação C. No MySQL, || e OR são sinônimos, assim como && e AND. Devido a esta ótima sintaxe, o MySQL não suporta o operador ANSI SQL para concatenação de strings ||; em vez disso, use o CONCAT(). Como CONCAT() aceita vários argumentos, é fácil converter o uso do operador || para MySQL.

  • CREATE DATABASE or DROP DATABASE. Veja mais informações sobre isto na Seção 6.5.1, “Sintaxe CREATE DATABASE.

  • O operador % é um sinônimo para MOD(). Isto é, N % M é equivalente a MOD(N,M). % é suportado para programadores C e para compatibilidade com o PostgreSQL.

  • Os operadores =, <>, <= ,<, >=,>, <<, >>, <=>, AND, OR ou LIKE podem ser utilizados em comparações de campos a esquerda do FROM nas instruções SELECT. Por exemplo:

    mysql> SELECT col1=1 AND col2=2 FROM nome_tabela;
    
  • A função LAST_INSERT_ID(). Veja mais informações sobre isto na Seção 12.1.3.32, “mysql_insert_id().

  • Os operadores extendidos REGEXP e NOT REGEXP utilizados em expressões regulares.

  • CONCAT() ou CHAR() com um ou mais de dois argumentos. (No MySQL, estas funções receber qualquer número de argumentos.)

  • As funções BIT_COUNT(), CASE, ELT(), FROM_DAYS(), FORMAT(), IF(), PASSWORD(), ENCRYPT(), MD5(), ENCODE(), DECODE(), PERIOD_ADD(), PERIOD_DIFF(), TO_DAYS() ou WEEKDAY().

  • Uso de TRIM() para cortar substrings. o SQL-99 só suporta remoção de caracteres únicos.

  • As funções do GROUP BY: STD(), BIT_OR(), BIT_AND() e BIT_XOR() e GROUP_CONCAT(). Veja mais informações sobre isto na Seção 6.3.7, “Funções e Modificadores para Usar com Cláusulas GROUP BY.

  • Uso de REPLACE no lugar de DELETE + INSERT. Veja mais informações sobre isto na Seção 6.4.7, “Sintaxe REPLACE.

  • As instruções FLUSH, RESET e DO.

  • A possibilidade de configurar variáveis em uma instrução com :=:

    SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS media FROM tabela_teste;
    SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
    

1.8.4. Diferenças do MySQL em Comparação com o SQL-92

Nós tentamos fazer com que o MySQL siguisse os padrões ANSI SQL (SQL-92/SQL-99) e o ODBC SQL, mas em alguns casos, o MySQL realiza operações de forma diferente:

Para uma lista priorizada indicando quando novas extensões serão adicionadas ao MySQL você deve consultar lista TODO online do MySQL em http://www.mysql.com/doc/en/TODO.html. Esta é a última versão da lista TODO neste manual. Veja mais informações sobre isto na Seção 1.6, “MySQL e o Futuro (o TODO)”.

1.8.4.1. Subqueries

MySQL Version 4.1 supports subqueries and derived tables (unnamed views). Veja mais informações sobre isto na Seção 6.4.2, “Sintaxe de Subquery”.

For MySQL versions prior to 4.1, most subqueries can be successfully rewritten using joins and and other methods. Veja mais informações sobre isto na Seção 6.4.2.11, “Rewriting Subqueries for Earlier MySQL Versions”.

1.8.4.2. SELECT INTO TABLE

O MySQL ainda não suporta a extensão SQL do Sybase: SELECT ... INTO TABLE .... MySQL suporta a sintaxe ANSI SQL INSERT INTO ... SELECT ..., que é basicamente a mesma coisa. Veja mais informações sobre isto na Seção 6.4.3.1, “Sintaxe INSERT ... SELECT.

INSERT INTO tblTemp2 (fldID)
SELECT tblTemp1.fldOrder_ID
FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;

De maneira alternativa, você pode usar SELECT INTO OUTFILE... ou CREATE TABLE ... SELECT para resolver seu problema.

1.8.4.3. Transações e Operações Atômicas

O MySQL Server (versão 3.23-max e todas as versões 4.0 e acima) suportam transações com os mecanismos de armazenamento transacionais InnoDB e BDB. InnoDB fornece compatibilidade total com ACID. Veja mais informações sobre isto na Capítulo 7, Tipos de Tabela do MySQL.

Os outros tipos de tabelas não transacionais (tais como MyISAM) no MySQL Server seguem um paradigma diferente para integridade de dados chamado ``Operções Atômicas.'' Em termos de transação, tabelas MyISAM efetivamente sempre operam em modo AUTOCOMMIT=1. Operações atômicas geralmente oferecem integridade comparável com a mais alta performance.

Com o MySQL Server suportando ambos os paradigmas, o utilizador pode decidir se precisa da velocidade das operações atômicas ou se precisa usar recursos transacionais em seu aplicativo. Esta escolha pode ser feita em uma base por tabela.

Como notado, a comparação para tabelas transacionais vs. não transacionais As noted, the trade off for transactional vs. non-transactional table se encontra em grande parte no desempenho. Tabelas transacionais tem uma exigência de memória e espaço em disco significantemente maior e maior sobrecarga da CPU. Tipos de tabelas transacionais como InnoDB oferecem muitos recursos únicos. O projeto modular do MySQL Server permite o uso concorrente de todas estes mecanismos de armazenamento para servir a diferentes exigências e oferecer um ótimo desempenho em todas as situações.

Mas como fazer uso dos recursos do MySQL Server para manter uma integridade rigorosa mesmo com tabelas MyISAM não transacionais e como este recurso se compara com os tipos de tabelas transacionais?

  1. No paradigma transacional, se as suas aplicações são escritas de uma forma que é dependente na chamada de ROLLBACK em vez de COMMIT em situações críticas, então transações são mais convenientes. Além disso, transações asseguram que atualizações inacabadas ou atividades corrompidas não sejam executadas no banco de dados; o servidor oferece uma oportunidade para fazer um rollback automático e seu banco de dados é mantido.

    O MySQL Server, na maioria dos casos, permite a você resolver potenciais problemas incluindo simples conferências antes das atualizações e executando scripts simples que conferem inconsistências no banco de dados e, automaticamente, repara ou avisa caso isto ocorra. Perceba que apenas usando o log do MySQL ou mesmo adicionando um log extra, pode-se corrigir tabelas perfeitamente sem nenhuma perda de integridade.

  2. Mais do que nunco, atualizações transacionais fatais podem ser reescritas para serem atômicas. De fato podemos dizer que todos problemas de integridade que transações resolvem podem ser feitas com LOCK TABLES ou atualizações atômicas, assegurando que você nunca irá ter uma finalização automática da tabela, o que é um problema comum em bancos de dados transacionais.

  3. Nem mesmo transações podem prevenir todas as falhas se o servidor cair. Nestes casos mesmo um sistema transacional pode perder dados. A diferença entre sistemas diferentes é apenas em quão pequeno é o lapso de tempo em que eles podem perder dados. Nenhum sistema é 100% seguro, somente ``seguro o suficiente.'' Mesmo o Oracle, com reputação de ser o mais seguro bancos de dados transacionais, tem relatos de algumas vezes perder dados nestas situações.

    Para estar seguro com o MySQL Server, você apenas deve fazer backups e ter o log de atualizações ligado. Com isto você pode se recuperar de qualquer situação possível com bancos de dados transacionais. É sempre bom ter backups, independente de qual banco de dados você usa.

O paradigma transacional tem seus benefícios e suas desvantagens. Muitos utilizadores e desenvolvedores de aplicações dependem da facilidade com a qual eles podem codificar contornando problemas onde abortar parece ser, ou é necessário. No entanto, se você é novo no paradigma de operações atômicas ou tem mais familiaridade ou conforto com transações, considere o benefício da velocidade que as tabelas não transacionais podem oferece, na ordem de 3 a 5 vezes da velocidade que as tabelas transacionais mais rápidas e otimizadas.

Em situações onde integridade é de grande importância, as atuais características do MySQL permitem níveis transacionais ou melhor confiança e integridade. Se você bloquear tabelas com LOCK TABLES todos as atualizações irão ser adiadas até qualquer verificação de integridade ser feita. Se você só obter um bloqueio de leitura (oposto ao bloqueio de escrita), então leituras e inserções poderão ocorrer. Os novos registros inseridos não poderão ser visualizados por nenhum dos clientes que tiverem um bloqueio de LEITURA até eles liberarem estes bloqueios. Com INSERT DELAYED você pode enfileirar inserções em uma fila local, até os bloqueios serem liberados, sem que o cliente precise esperar atá a inserção completar. Veja mais informações sobre isto na Seção 6.4.3.2, “Sintaxe INSERT DELAYED.

``Atômico'', no sentido em que nós mencionamos, não é mágico. Significa apenas que você pode estar certo que enquanto cada atualização específica está sendo executada, nenhum outro utilizador pode interferir com ela, e nunca haverá um rollback automático (que pode acontecer em sistemas baseados em transações se você não tiver muito cuidado). O MySQL também assegura que nunca ocorrerá uma leitura suja.

A seguir estão algumas técnicas para trabalhar com tabelas não transacionais:

  • Loops que precisam de transações normalmente pode ser codificados com a ajuda de LOCK TABLES, e você não precisa de cursores para atualizar regitros imeditamente.

  • Para evitar o uso do ROLLBACK, você pode usar as seguintes estratégias:

    1. Use LOCK TABLES ... para fazer um lock todas as tabelas que você quer acessar.

    2. Condições de teste.

    3. Atualize se estiver tudo OK.

    4. Use UNLOCK TABLES para liberar seus locks.

    Isto é normalmente um método muito mais rápido que usar transações com possíveis ROLLBACKs, mas nem sempre. A única situação que esta solução não pode tratar é quando alguém mata a threads no meio de uma atualização. Neste caso, todas os locks serão liberados mas algumas das atualização podem não ter sido execuadas.

  • Você também pode usar funções para atualizar registros em uma única operação. Você pode conseguir uma aplicação muito eficiente usando as seguintes técnicas:

    • Modifique campos em relação ao seus valores atuais.

    • Atualize apenas aqueles campos que realmente tiveram alterações.

    Por exemplo, quando fazemos atualizações em alguma informação de cliente, atualizamoa apenas os dados do clientes que alteraram e testamos apenas aqueles com dados alterados ou dados que dependem dos dados alterados, mudaram em comparação com o registro original. O teste dos dados alterados é feito com a cláusula WHERE na instrução UPDATE. Se o registro não foi atualizado, mandamos ao cliente uma mensagem: ''Some of the data you have changed has been changed by another user.'' Então mostramos o registro antigo versus o novo em uma janela, assim o utilizador pode decidir qual versão do registro de cliente de ser usado.

    Isto nos dá algo similar a lock de colunas mas que, na verdade, é melhor porque apenas atualizamos algumas das colunas, usando valores relativos ao seu valor atual. Isto significa que instruções UPDATE comuns se parecem com estas:

    UPDATE nometabela SET pay_back=pay_back+125;
    UPDATE customer
    SET
    customer_date='current_date',
    address='new address',
    phone='new phone',
    money_he_owes_us=money_he_owes_us-125
    WHERE
    customer_id=id AND address='old address' AND phone='old phone';
    

    Como você pode ver, isto é muito eficiente e funciona mesmo se outro cliente alterar os valores nas colunas pay_back ou money_he_owes_us.

  • Em muitos casos, utilizadores querem fazer ROLLBACK e/ou LOCK TABLES com o propósito de gerenciarem identificadores únicos para algumas tabelas. Isto pode ser tratado muito mais eficientemente usando uma coluna AUTO_INCREMENT e também uma função SQL LAST_INSERT_ID() ou a função da API C mysql_insert_id(). Veja mais informações sobre isto na Seção 12.1.3.32, “mysql_insert_id().

    Geralmente você pode codificar evitando lock de registro. Algumas situações realmente precisam disto, e tabelas InnoDB suportam lock de regitstro. Comoo MyISAM, você pode usar uma coluna de flag na tabela e fazer algo como a seguir:

    UPDATE nome_tbl SET row_flag=1 WHERE id=ID;
    

    O MySQL retorna 1 para o número de linhas afetadas se as linhas foram encontradas e row_flag já não era 1 na linha original.

    Você pode pensar nisto como se o MySQL Server tivesse alterado a consulta anterior para:

    UPDATE nome_tbl SET row_flag=1 WHERE id=ID AND row_flag <> 1;
    

1.8.4.4. Stored Procedures e Triggers

Steored procedures estão sendo implementadas em nossa versão 5.0 na árvore de desenvolvimento. Veja mais informações sobre isto na Seção 2.3.4, “Instalando pela árvore de fontes do desenvolvimento”.

Este esforço é baseado no SQL-99, que têm uma sintaxe básica similar (mas não idêntica) ao Oracle PL/SQL. Em adição a isto, estamoas implementando o framework SQL-99 enganchar em linguagens externas.

Uma Stored Procedure é um conjunto de comandos SQL que podem ser compilados e armazenados no servidor. Uma fez feito isso, os clientes não necessitam reescrever toda a consulta mas podem fazer referência à stored procedure. Isto fornece melhor performance porque a query necessita ser analisada pelo servidor somente uma vez, e necessita menos informação para ser enviada entre o servidor e o cliente. Você também pode elevar o nível conceitual tendo bibliotecas de funções no servidor. No entanto, stored procedures aumentam a carga no servidor de banco de dados, já que grande parte do trabalho é feito do lado do servidor e menos do lado do cliente (aplicação).

Triggers estão programados para serem implementados no MySQL versão 5.1. Um trigger é um tipo de stored procedure que é chamado quando um evento em particular ocorre. Por exemplo, você poderia configurar uma stored procedure que é disparada toda vez que um registro for apagado de uma tabela transacional que automaticamente apaga o cliente correspondente de uma tabela de clientes quando todas as transações forem removidas.

1.8.4.5. Chaves Estrangeiras

No MySQL Server 3.23.44 e posterior, tabelas InnoDB suportam verificação de restrição de chaves estrangeiras, incluindo CASCADE, ON DELETE, e ON UPDATE. Veja mais informações sobre isto na Seção 7.5.5.2, “Restrições FOREIGN KEY.

Para outros tipos de tabela, o MySQL Server atualmente apenas analisa a sintaxe de FOREIGN KEY no comando CREATE TABLE, mas não usa/armazena esta informação. Em um futuro próximo esta implementação será estendida para que assim a informação seja armazenada num arquivo de especificação de tabela e possa ser recuperado por mysqldump e ODBC. Em um estágio posterior, restrições de chaves estrangeiras serão implementadas para tabelas MyISAM.

Note que as chaves estrangeiras no SQL não são usadas para ligar tabelas, mas são usadas para verificar a integridade referencial. Se você deseja obter resultados de múltiplas tabelas de uma instrução SELECT, você pode fazer isto ligando tabelas:

SELECT * FROM table1,table2 WHERE table1.id = table2.id;

Veja mais informações sobre isto na Seção 6.4.1.1, “Sintaxe JOIN. Veja mais informações sobre isto na Seção 3.6.6, “Utilizando Chaves Estrangeiras”.

Quando usada como uma restrição, FOREIGN KEYs não precisa ser usado se a aplicação insere duas linhas em tabelas MyISAM na ordem apropriada.

Para tabelas MyISAM, você pode contornar a falta de ON DELETE adicionando a instrução DELETE apropriada a uma aplicação quando você deletar registros de uma tabela que tem uma chave estrangeira. Na prática isto é mais rápido e muito mais portável que utilizar chaves estrangeiras.

No MySQL Server 4.0 você pode utilizar deleções multi-tabela para apagar linha de muitas tabelas com um comando. Veja mais informações sobre isto na Seção 6.4.5, “Sintaxe DELETE.

A sintaxe FOREIGN KEY sem ON DELETE ... é usada geralmente por aplicacões ODBC para produzir cláusulas WHERE automáticas.

Note que chaves estrangeiras são mal usadas com frequência, o que pode causar graves problemas. Mesmo quando usado apropriadamente, o suporte a chaves estrangeiras não é uma solução mágica para o problema de integridade referêncial, embora possa ajudar.

Algumas vantagens das chaves estrangeiras:

  • Assumindo o projeto apropriado das relações, as restrições de chaves estrangeiras tornarão mais difícil para um programador introduzir uma inconsistência no banco de dados.

  • Usar atualizações e deleções em cascata pode simplificar o código do cliente.

  • Regras de chaves estrangeiras projetados apropriadamente ajudam ao documentar a relação entre as tabelas.

Desvantagens:

  • Erros, que são facéis de se ter ao projetar a relação das chaves, podem causar graves problemas¯por exemplo, regras circulares ou a combinação errada de uma deleção em cascata.

  • Verificação adicional no banco de dados afeta o desempenho, por esta razão algumas das principais aplicações comerciais codificam sua lógica no nível da aplicação.

  • Não é incomum para um DBA fazer uma topologia complexa de relações que torna muito difícl, e em alguns casos impossível, fazer backup ou restaurar tabelas individuais.

1.8.4.6. Views

Views estão senda implementadas atualmente e aparecerão na versão 5.0 e 5.1 do MySQL Server.

Historicamente o MySQL Server tem sido mais usado em aplicações e sistemas web onde o desenvolvedor da aplicação tem total controle sobre o uso do banco de dados. É claro que o uso aumentou em várias vezes e então descobrimos que um crescente números de utilizadores consideram views como um importante aspecto.

Unnamed views (derived tables, uma seubquery na cláusula FROM de uma SELECT) já estão implementadas na versão 4.1.

Views geralmente são muito úteis para permitir aos utilizadores acessar uma série de relações (tabelas) como uma tabela, e limitar o acesso a apenas estas relações. Views também podem ser usadas para restringir o acesso aos registros (um subconjunto de uma tabela em particular). Mas views não são necessárias para restringir o acesso a registros já que o MySQL Server tem um sofisticado sistema de privilégios. Veja mais informações sobre isto na Seção 4.3, “Detalhes Gerais de Segurança e o Sistema de Privilégio de Acesso do MySQL”.

Muitos SGBD não permitem atualizar nenhum registro em uma view, mas você tem que fazer as atualizações em tabelas separadas.

Em nosso projeto de implemtação de views, nós buscamos (tanto quanto for possível dentro do SQL) compatibilidade com ``Codd's Rule #6'' para sistemas de banco de dados relacionais: todos os views que são teoricamente atualizáveis, devem se atualizados também na prática.

1.8.4.7. '--' como Início de Comentário

Outros bancos de dados SQL usam '--' para iniciar comentários. O MySQL usa ‘#’ como o caractere para início de comentário, mesmo se a ferramenta de linha de comando mysql remover todas linhas que começam com '--'. Você também pode usar o comentário no estilo C /*isto é um comentário*/ com o MySQL Server. Veja mais informações sobre isto na Seção 6.1.6, “Sintaxe de Comentários”.

O MySQL Server versão 3.23.3 e superior suporta o estilo de comentário '--' somente se o comentário for seguido por um caractere de espaço (ou por um caracter de controle como uma nova linha). Isto ocorre porque este estilo de comentário causou muitos problemas com queries SQL geradas automaticamente que usavam algo como o código seguinte, onde automaticamente erá inserido o valor do pagamento para !pagamento!:

UPDATE nome_tabela SET credito=credito-!pagamento!

O que você acha que irá acontecer quando o valor de pagamento for negativo? Como 1--1 é legal no SQL, nós achamos terrível que '--' signifique início de comentário.

Usando a nossa implementação deste método de comentário no MySQL Server Version 3.23.3 e posterior, 1-- Isto é um comentário é atualmente seguro.

Outro recurso seguro é que o cliente de linha de comando mysql remove todas as linhas que iniciam com '--'.

A seguinte discussão somente interessa se você estiver executando uma versão do MySQL inferior a versão 3.23:

Se você tem um programa SQL em um arquivo texto que contêm comentários '--' você deverá usar:

shell> replace " --" " #" < arquivo-texto-com-comentário.sql \
| mysql banco-de-dados

No lugar de:

shell> mysql banco-de-dados < arquivo-texto-com-comentario.sql

Você também pode editar o próprio arquivo de comandos alterando os comentários '--' para ‘#’:

shell> replace " --" " #" -- arquivo-texto-com-comentario.sql

Desfaça utilizando este comando:

shell> replace " #" " --" -- arquivo-texto-com-comentario.sql

1.8.5. Como o MySQL Lida com Restrições

Como o MySQL lhe permite trabalhar com tabelas transacionais e não transacionais (que não permitem rollback), o tratamento de restrições é um pouco diferente no MySQL que em outros bancos de dados.

Temos que tratar o caso quando você atualiza diversos registros com uma tabela não transacional que não pode fazer rollback em erros.

A filosofia básica é tentar obter um erro para qualquer coisa que possamos detectar em temp de compilação mas tentar recuperar de qualquer erro que abtemos em tempo de execução. Fazemos isto na maiorioa dos casos, mas não para todos ainda. Veja mais informações sobre isto na Seção 1.6.4, “Novos Recursos Planejados Para a Versão em um Futuro Próximo”.

A opção básica que o MySQL tem é parar a instrução no meio ou fazer o melhor para se recuperar do problema e continuar.

A seguir mostramos o que acontece com diferentes tipos de restrições.

1.8.5.1. Restrições de PRIMARY KEY / UNIQUE

Normalmente você receberá um erro quando tentar fazer um INSERT / UPDATE de um registro que cause uma violação de uma chave primária, chave única ou chave estrangeira. Se você estiver usando um mecanismo de armazenamento transacional, como InnoDB, o MySQL automaticamente fará um rollback da transação. Se você estiver usando mecanismos de armazenemento não transacionais o MySQL irá para no registro errado e deiar o resto dos registros se processamento.

Para tornar a vida mais fácil o MySQL adicionou suporte a diretiva IGNORE para a maioria dos comandos que podem causar uma violação de chave (como INSERT IGNORE ...). Neste caso o MySQL irá ignorar qualquer violação de chave e continuará com o processamento do próximo registro. Você pode obter informação sobre o que o MySQL fez com a função da API mysql_info() API function e em versões posteriores do MySQL 4.1 com o comando SHOW WARNINGS. Veja mais informações sobre isto na Seção 12.1.3.30, “mysql_info(). Veja mais informações sobre isto na Seção 4.6.8.9, “SHOW WARNINGS | ERRORS.

Note que no momento apenas as tabelas InnoDB suportam chaves estrangeiras. Veja mais informações sobre isto na Seção 7.5.5.2, “Restrições FOREIGN KEY.

O suporte a chaves estrangeiras nas tabelas MyISAM está programado para ser incluída na arvoré de fonte do MySQL 5.0.

1.8.5.2. Restrições de NOT NULL

Para poder suportar um fácil tratamento de tabelas não transacionais todos os campos no MySQL têm valores padrão.

Se você inserir um valor 'errado' em uma coluna como um NULL em uma coluna NOT NULL ou um valor numérico muito grande em um campo numérico, o MySQL irá atribuir a coluna o 'melhor valor possível' em vez de dar uma mensagem de erro. Para strings este valor é uma string vazia ou a maior string possível que possa estar na coluna.

Isto significa que se você tentar armazenar NULL em uma coluna que não aceita valores NULL, o MySQL Server armazenará 0 ou '' (strig vazia) nela. Este último comportamento pode, para uma simples inserção de registro, ser alterado com a opção de compilação -DDONT_USE_DEFAULT_FIELDS.) Veja mais informações sobre isto na Seção 2.3.3, “Opções típicas do configure. Isto faz com que as instruções INSERT gerem um erro a menos que você explicite valores específicos para todas as colunas que exigem um valor diferente de NULL.

A razão para as regras acima é que não podemos verificar estas condições antes da consulta começar a executar. Se encontrarmos um problema depois de atualizar algumas linahs, não podemos fazer um rollback já que o tipo de tabela não suporta isto. A opção de parar não é tão boa como no caso em que a atualização esteja feita pela metade que é provavelmente o pior cenário possível. Neste caso é melhor 'fazer o possível' e então continuar como se nada tivesse acontecido. No MySQL 5.0 plenejamos melhorar into forncendo avisos para conversões automáticas de campo, mais uma opção para deixar você fazer um rollback das instruções que usam apenas tabelas transacionais no caso de tal instrução fizer uma definição de campo não permitida.

O mostrado acima significa que não se deve usar o MySQL para verificar o conteúdo dos campos, mas deve se fazê-lo por meio da aplicação.

1.8.5.3. Restrições de ENUM e SET

No MySQL 4.x ENUM não é uma restrição real, mas um modo mauis eficiente de armazenar campos que possam apenas conter um conjunto de valores dados. Isto é devido as mesmas razões pelas quais NOT NULL não é respeitado. Veja mais informações sobre isto na Seção 1.8.5.2, “Restrições de NOT NULL.

Se você inserir um valor errado em um campo ENUM, ele será configurado com uma string vazia em um contexto string. Veja mais informações sobre isto na Seção 6.2.3.3, “O Tipo ENUM.

Se você inserir uma opção errada em um campo SET, o valor errado será ignorado. Veja mais informações sobre isto na Seção 6.2.3.4, “O Tipo SET.

1.8.6. Erros Conhecidos e Deficiências de Projetos no MySQL

1.8.6.1. Erros da Versão 3.23 Corrigidos em Versões Posteriores do MySQL

Os seguintes erros/bugs conhecidos não estão corrigidos no MySQL 3.23 porque corrigí-los involveria a mudança de muito código, o que poderia introduzir outros erros, talvez piores. Os erros são também classificados como 'não fatal' ou 'tolerável'.

  • Pode se obter um deadlock ao fazer LOCK TABLE em multiplas tabelas e então na mesma conexão fizer um DROP TABLE em uma delas enquanto outra thread está tentando bloquear a tabela. Pode-se no entanto fazer um KILL em qualquer uma das threads envolvidas para resolver isto. Corrigido na versão 4.0.12

  • SELECT MAX(campo_chave) FROM t1,t2,t3... onde uma das três tabelas está vazia não retorna NULL, mas sim o valor máximo da coluna. Corrigido na versão 4.0.11.

  • DELETE FROM heap_table sem um WHERE não funcionam em tabelas HEAP com lock.

1.8.6.2. Open Bugs / Deficiências de Projeto no MySQL

Os seguintes problemas são conhecidos e tem prioridade muito alta para serem corrigidos:

  • FLUSH TABLES WITH READ LOCK não bloqueia CREATE TABLE ou COMMIT, que pode criar um problema com a posição do log binário ao se fazer um backup completo de tabelas e do log binário.

  • ANALYZE TABLE em uma tabela BDB pode, em alguns, casos inutilizar a tabela até que se reinicie o servidor mysqld. Quando isto acontecer você irá ver o seguinte tipo de erro no arquivo de erros do MySQL.

    001207 22:07:56 bdb: log_flush: LSN past current end-of-log
    
  • O MySQL aceita parenteses na parte FROM, mas os ignora sem aviso. A razão pela qual não são retornados erros é que muitos clientes que geram consultas automaticamente adicionam parentesis na parte FROM mesmo onde eles não são necessários.

  • Concatenar muitos RIGHT JOINS ou combinar joins LEFT e RIGHT na mesma consulta podem dar uma resposta incorreta ja que o MySQL só gera registros NULL para tabelas que precedem um join LEFT ou antes de um join RIGHT. Isto será corrigido na versão 5.0 junto com o suporte a parentesis na parte FROM.

  • Não execute ALTER TABLE em uma tabela BDB em que você estiver executando transações multi-instruções não completadas. (A transação provavelmente será ignorada).

  • ANALYZE TABLE, OPTIMIZE TABLE e REPAIR TABLE podem causar problemas em tabelas para as quais você estiver usando INSERT DELAYED.

  • Fazendo um LOCK TABLE .. e FLUSH TABLES .. não garante que não existem transações não terminadas em progresso na tabela.

  • Tabelas BDB são um pouco lentas para abrir. Se você tiver várias tabelas BDB em um banco de dados, gastará muito tempo para usar o cliente mysql no banco de dados se você não estiver usando a opção -A ou se você estiver usando rehash. Isto é percebido principalmente quando você tiver um cache de tabelas grandes.

  • A replicação utiliza o log a nivel de consulta: o master grava a consulta no log binário. Isto é um rápido, compacto e eficiente método de registro o que funciona perfeitamente na maioria dos casos. Embora nunca tenhamos ouvido sobre um caso ocorrido, há uma chance teórica que o dado no master e slave sejam diferente se uma consulta é feita de tal modo que a modificação do dado é não determinística, isto é, deixar ao desejo do otimizador de consultas (o que geralmente não é uma boa prática, mesmo fora da replicação!). Por exemplo:

    • CREATE ... SELECT ou INSERT ... SELECT que preenchem com zeros ou NULL uma coluna auto_increment.

    • DELETE se você estiver apagando registros de uma tabela que tem chaves estrangeiras com a propriedade ON DELETE CASCADE.

    • REPLACE ... SELECT, INSERT IGNORE ... SELECT se você tiver valores de chaves duplicados nos dados inseridos.

    Se e somente se todos estas consultas NÃO tiverem cláusulas ORDER BY garantindo uma ordem determinística.

    Na verdade, por exemplo para INSERT ... SELECT sem ORDER BY, o SELECT pode retornar registros em uma ordem diferente (no qual resultará em um registro tendo diferentes posições, obtendo um número diferente na coluna auto_increment), dependendo da escolhe feita pelo otimizador no master e slave. Uma consulta será otimizada deiferentemente no master e slave apenas se:

    • Os arquivos usados pelas duas consultas não são exatamente a mesma; por exemplo OPTIMIZE TABLE foi executado nas tabelas master e não nas nas tabelas slave (para corrigir isto, desde o MySQL 4.1.1, OPTIMIZE, ANALYZE e REPAIR são escritos no log binário).

    • A tabela está armazenada em um mecanismo de armazenamento diferente no master e no slave (pode se executar diferentes mecanismos de armazenamento no metre e no slave: por exemplo, InnoDB ne master e MyISAM no slave, se o slave possuir menos espaço dispponível em disco).

    • The MySQL buffers' sizes (key_buffer_size etc) are different on the master and slave.

    • O master e slave executam versões diferentes do MySQL, e o código do toimizador é diferente entre estas versões.

    Este problema também pode afetar a restauração de um banco de dados usando mysqlbinlog|mysql.

    O modo mais fácil de evitar este problema em todos os casos é adicionar uma cláusula ORDER BY para tal consulta não determinística assegure que os registros são sempre armazenados/modificados na mesma ordem. Nas versões futuras do MySQL adicionaremos automaticamente uma cláusula ORDER BY quando necessário.

Os seguintes problemas são conhecidos e serão corrigidos na hora certa:

  • Ao usar funções RPAD, ou qualquer outra função string que termina adicionando espaços em branco a direita, em uma consulta que preisa usar tabelas temporárias para ser rsolvida, todas as strings resultantes serão cortadas a direita (como em RTRIM). Este é um exemplo de uma consulta:

    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;

    O resultado final deste erro é que o utilizador não conseguira espaços em branco do lado direito do campo resultante.

    O comportamento anterior existe em todas as versões do MySQL.

    A razão disto é devido ao fato de tabelas HEAP, que são usadas primeiro para tabelas temporárias, não são capazes de tratar colunas VARCHAR.

    Este comportamento será corrigido em uma das distribuições da série 4.1.

  • Devido ao modo como os arquvos de definições de tabelas são armazenados não se pode usar 255 caracteres (CHAR(255)) em nomes de tabelas, nomes de colunas e enum. Isto está programado para ser corrigido na versão 5.1 quando temos novos arquivos de formatos de definição de tabelas.

  • Quando estiver usando SET CHARACTER SET, não é permitido usar caracteres especias no nome do banco de dados, tabelas ou campos.

  • Pode-se usar _ ou % com ESCAPE em LIKE ... ESCAPE.

  • se você tiver uma coluna DECIMAL com um número armazenado em diferentes formatos (+01.00, 1.00, 01.00), GROUP BY pode considerar cada valor como um valor diferente.

  • DELETE FROM merge_table usado sem WHERE irá apenas apagar o mapeamento para a tabela, não apagando tudo nas tabelas mapeadas.

  • Você não pode construir em outro diretório quando estiver utilizando MIT-pthreads. Como isto necessitaria de alterações na MIT-pthreads, nós não estamos aptos a corrigí-la.

  • BLOB valores não podem ser usados com confiança em GROUP BY, ORDER BY ou DISTINCT. Somente os primeiros bytes (padrão 1024) max_sort_length são usados quando estiver comparando BLOBs nestes casos. Isto pode ser alterado com a opção -0 max_sort_lenght para mysqld. Uma forma de contornar este problema para a maioria dos casos é usar a substring: SELECT DISTINCT LEFT(blob,2048) FROM nome_tabela.

  • Cálculos são feitos com BIGINT ou DOUBLE (normalmente, ambos tem o tamanho de 64 bits). Depende da precisão utilizada na função. A regra geral é que funções binárias são feitas com precisão BIGINT, IF e ELT() com precisão BIGINT ou DOUBLE e o resto com precisão DOUBLE. Devemos evitar o uso de valores sem sinal maiores que 63 bits (9223372036854775807) para qualquer outra coisa além de campos binários!

  • Todas os campos string, exceto campos do tipo BLOB e TEXTO tem, automaticamente, todos os espaços extras removidos quando recuperados. Para tipos CHAR, isto não tem problema, e pode ser considerado como um recurso de acordo com o ANSI SQL92. O problema é que no MySQL, campos VARCHAR são tratados desta mesma forma.

  • Você só pode ter até 255 colunas ENUM e SET em uma tabela.

  • Em MIN(), MAX() e outras funções de agrupamente, o MySQL atualmente compara as colunas ENUM e SET pelo valor de suas strings ao invés da posição relativa da string no conjunto.

  • mysqld_safe redireciona todas as mensagens de mysqld para o log mysqld. Um problema com isto é que se você executar o mysqladmin refresh para fechar e reabrir o log, a stdout e a stderr continuam redirecionadas para o log antigo. Se você utiliza --log extensivamente, deverá editar o mysqld_safe para logar em 'hostname'.err em vez de 'hostname'.log; assim você pode facilmente utilizar o espaço do log antigo apagando-o e executando mysqladmin refresh.

  • Em instruções UPDATE, colunas são atualizadas da esquerda para a direita. Se você referenciar a uma coluna atualizada, você irá obter o valor atualizado em vez do valor original, por exemplo:

    mysql> UPDATE nome_tabela SET KEY=KEY+1,KEY=KEY+1;
    

    Isto atualiza KEY com 2 no lugar de 1.

  • Você pode se referir a múltiplas tabelas em uma mesma consulta, mas você não pode se referir a qualquer tabelas temporárias dada mais de uma vez. Por exemplo, a seguinte instrução não funciona.

    mysql> SELECT * FROM temporary_table, temporary_table AS t2;
    
  • RENAME não funciona com tabelas temporárias (TEMPORARY) ou tabelas usadas em uma tabelas MERGE.

  • O otimizador pode lidar com o DISTINCT de forma diferente se você estiver usando colunas 'escondidas' em uma join ou não. Em uma join, colunas escondidas são contadas como parte do resultado (mesmo se elas não são mostradas) enquanto que em queries normais colunas escondidas não participam na comparação DISTINCT. Nós provavelmente iremos alterar isto no futuro para nunca comparar as colunas escondidas quando executando DISTINCT.

    um exemplo disto é:

    SELECT DISTINCT mp3id FROM band_downloads
    WHERE userid = 9 ORDER BY id DESC;
    

    and

    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;
    

    No segundo caso, você pode obter duas linhas idênticas no MySQL 3.23.x na série do resultado (porque o campo escondido 'id' pode variar).

    Perceba que isto somente acontece em consultas onde você não tem colunas ORDER BY no resultado, algo não permitido no SQL-92.

  • Como o MySQL permite trabalhar com tipos de tabelas que não suportam transações (e assim não pode fazer rollback em dados) algumas coisas funcionam um pouco diferentes de outros servidores SQL em MySQL (Isto serve para garantir que o MySQL nunca necessitará de um rollback para um comando SQL). Porém isto pode ser um pouco estranho em casos que os valores dos campos devem ser verificados na aplicação, mas isto ira fornacer um ótimo ganho de velocidade assim como permite ao MySQL fazer algumas otimizações que de outro modo seriam muito difíceis para serem feitas.

    Se você informar um valor incorreto em uma coluna, o MySQL, em vez de fazer um rollback, aramzenará o melhor valor possível no campo.

    • Se tentar armazenar um valor fora da faixa em uma coluna numérico, o MySQL irá armazenar o menor ou maior valor possível no campo.

    • Se tentar armazenar uma string que não comece com um número em uma coluna numérica, o MySQL irá armazenar 0 na coluna.

    • Se você tentar armazenar NULL em uma coluna que não aceita valores nulos, MySQL irá armazenar 0 ou '' (string vazia) na coluna. (Este comportamento pode, entretanto, ser alterado com a opção de compilação -DDONT_USE_DEFAULT_FIELDS).

    • O MySQL permite o armazenamento de alguns valores errados de data em campos do tipo DATE e DATETIME. (Como 2000-02-31 ou 2000-02-00). A idéia é que não é serviço do servidor SQL validar datas. Se o MySQL pode armazenar uma data e recuperar extamente a mesma data, então o MySQL armazenará a data. Se a data estiver totalmente errada, o MySQL irá armazenar a data 0000-00-00 no campo.

    • Se você especificar um valor não suportado para um campo do tipo enum, ele será alterado para o valor de erro 'empty string', com valor numérico 0.

    • Se você definir uma coluna SET com um valor não suportado, o valor será ignorado.

  • Se você executar uma PROCEDURE em uma pesquisa que retorna uma série vazia, em alguns casos a instrução PROCEDURE não irá transformar as colunas.

  • Criação da tabela do tipo MERGE não verifiva se as tabelas envolvidas são de tipos compatíveis.

  • O MySQL ainda não pode lidar com valores NaN, -Inf e Inf em tipos double. Usá-los causará problemas na exportação e importação de dados. Uma solução intermediária é alterar NaN para NULL (se for possível) e -Inf e Inf para o valor double mínimo ou máximo respectivo possível.

  • Se você usar ALTER TABLE para primeiro adicionar um índice UNIQUE a uma tabela usada em uma tabela MERGE e então usar ALTER TABLE para adicionar um índice normal na tabela MERGE, a ordem das chaves será diferente para as tabelas se existir uma chave antiga não única na tabela. Isto é porque o ALTER TABLE coloca chaves UNIQUE antes de chaves normais para ser possível detectar chaves duplicadas o mais cedo o possível.

Os seguintes erros são conhecidos em versões mais antigas do MySQL:

  • Você pode pendurar um processo se você fizer um DROP TABLE em uma tabela entre outras que esteja travada com LOCK TABLES.

  • No caso seguinte você pode obter um descarrego de memória para o arquivo core:

    • Tratamento de inserções com atraso tem deixado inserções pendentes na tabela.

    • LOCK table com WRITE

    • FLUSH TABLES

  • Antes da versão 3.23.2 do MySQL um UPDATE que atualizava uma chave com um WHERE na mesma chave podia falhar porque a chave era usada para procurar por registros e a mesma linha poderia ter encontrado vários itens:

    UPDATE nome_tabela SET KEY=KEY+1 WHERE KEY > 100;
    

    Um modo de contornar este erro é utilizar:

    mysql> UPDATE nome_tabela SET KEY=KEY+1 WHERE KEY+0 > 100;
    

    Isto funcionará porque MySQL não utilizará indices em expressões com a cláusula WHERE.

  • Antes da versão 3.23 do MySQL, todos os tipos numéricos tratados como campos de pontos fixos. Isto significa que você tem que especificar quantas casas decimais um campo de ponto flutuante deve ter. Todos os resultados eram retornados com o número correto de casas decimais.

Para erros específicos na plataforma, vejas as seções sobre compilação e portabilidade. Veja mais informações sobre isto na Seção 2.3, “Instalando uma distribuição com fontes do MySQL”. Veja mais informações sobre isto na Apêndice E, Portando para Outros Sistemas.