Índice
SELECT
e WHERE
SELECT
, INSERT
, UPDATE
e DELETE
CREATE
, DROP
e ALTER
O MySQL possui uma interface SQL muito complexa mas intuitiva e fácil de aprender. Este capítulo descreve os vários comandos, tipos e funções que você precisa conhecer para usar o MySQL de maneira eficiente e efetiva. Este capítulo também serve como referência para todas as funcionalidades incluídas no MySQL. Para poder utilizar este capítulo eficientemente, você deve achar útil fazer referência aos vários índices.
Esta seção descreve as diversas maneiras para gravar strings e números no MySQL. Ela também cobre as várias nuances e ``pegadinhas'' pelas quais você pode passar ao lidar com estes tipos básicos no MySQL.
Uma string é uma sequência de caracteres, cercada por
caracteres de aspas simples
(‘'
’) ou duplas
(‘"
’) (Se você utiliza o modo
ANSI deve utilizar somente as aspas simples). Exemplos:
'uma string' "outra string"
Em uma string, certas sequências tem um significado especial.
Cada uma destas sequências começam com uma barra invertida
(‘\
’), conhecida como
caracter de escape. O MySQL reconhece a
seguinte sequência de escape:
\0
Um caracter ASCII 0 (NUL
).
\'
Um caracter de aspas simples
(‘'
’).
\"
Um caracter de aspas duplas
(‘"
’).
\b
Um caracter de backspace.
\n
Um caracter de nova linha.
\r
Um caracter de retorno de carro.
\t
Um caracter de tabulação.
\z
ASCII(26) (Control-Z). Este caracter pode ser codificado
para permitir que você contorne o problema que o
ASCII(26) possui comoEND-OF-FILE ou EOF (Fim do arquivo)
no Windows. (ASCII(26) irá causar problemas se você
tentar usar mysql banco_dados <
nome_arquivo
).
\\
O caracter de barra invertida
(‘\
’) character.
\%
Um caracter ‘%
’. Ele pode
ser usado para pesquisar por instâncias literais de
‘%
’ em contextos onde
‘%
’ deve, de outra maneira,
ser interpretado como um meta caracter. See
Secção 6.3.2.1, “Funções de Comparação de Strings”.
\_
Um caracter ‘_
’. Ele é
usado para pesquisar por instâncias literais de
‘_
’ em contextos onde
‘_
’ deve, de outra maneira,
ser intrerpretado como um meta caracter. See
Secção 6.3.2.1, “Funções de Comparação de Strings”.
Note que se você utilizar '\%
' ou
'\_
' em alguns contextos de strings, eles
retornarão as strings '\%
' e
'\_
' e não
‘%
’ e
‘_
’.
Estas são as várias maneiras de incluir aspas com uma string:
Um ‘'
’ dentro de uma string
com ‘'
’ pode ser escrita
como '''
'.
Um ‘"
’ dentro de uma string
com ‘"
’ pode ser escrita
como '""
'.
Você pode preceder o caracter de aspas com um caracter de
escape (‘\
’).
Um ‘'
’ dentro de uma string
com ‘"
’ não precisa de
tratamento especial e não precisa ser duplicada ou
utilizada com caracter de escape. Da mesma maneira,
‘"
’ dentro de uma string
com ‘'
’ não necessita de
tratamento especial.
As instruções SELECT
exibidas abaixo
demonstram como citações e escapes funcionam:
mysql>SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+ | hello | "hello" | ""hello"" | hel'lo | 'hello | +-------+---------+-----------+--------+--------+ mysql>SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+ | hello | 'hello' | ''hello'' | hel"lo | "hello | +-------+---------+-----------+--------+--------+ mysql>SELECT "This\nIs\nFour\nlines";
+--------------------+ | This Is Four lines | +--------------------+
Se você deseja inserir dados binários em uma coluna
BLOB
, os caracteres a seguir devem ser
representados por sequências de espace:
NUL
ASCII 0. Você deve representá-lo como
'\0
' (uma barra invertida e um
caractere ‘0
’).
\
ASCII 92, barra invertida. Representado como
'\\
'.
'
ASCII 39, aspas simples. Representado como
'\'
'.
"
ASCII 34, aspas duplas. Representado como
'\"
'.
Se você escreve código C, você pode utilizar a função da
API C mysql_escape_string()
para
caracteres de escape para a instrução
INSERT
. See
Secção 12.1.2, “Visão Geral das Função da API C”. No Perl, pode ser
utilizado o método quote
do pacote
DBI
para converter caracteres especiais
para as sequências de escape corretas. See
Secção 12.5.2, “A interface DBI
”.
Deve ser utilizada uma função de escape em qualquer string que contêm qualquer um dos caracteres especiais listados acima!
Alternativamente, muitas APIs do MySQL fornecem algumas da capacidades de placeholder que permitem que você insira marcadores especiais em um string de consulta e então ligar os valores dos dados a eles quando você executa a consulta. Neste caso, a API inclui, automaticamente, os caracteres especiais de escape nos valores para você.
Inteiros são representados como uma sequência de dígitos.
Números de ponto flutuante utilizam
‘.
’ como um separador decimal.
Ambos os tipos devem ser precedidos por
‘-
’ para indicar um valor
negativo.
Exemplos de inteiros válidos:
1221 0 -32
Exemplo de números de ponto flutuante válidos:
294.42 -32032.6809e+10 148.00
Um inteiro pode ser usado em um contexto de ponto flutuante; ele é interpretado como o de ponto flutuante equivalente.
A partir da versão 4.1.0, a constante TRUE
é avaliada com 1
e
FALSE
é avaliada com 0
.
O MySQL suporta valores hexadecimais. No contexto numérico estes atuam como um inteiro (precisão de 64-bits). No contexto de strings, atuam como uma string binária onde cada par de dígitos hexadecimais é convertido para um caracter:
mysql>SELECT x'4D7953514C';
-> MySQL mysql>SELECT 0xa+0;
-> 10 mysql>SELECT 0x5061756c;
-> Paul
No MySQL 4.1 (e no MySQL 4.0 quando usado com a opçõa
--new
) o tipo padrão de um valor hexadecimal
é uma string. Se você deseja estar certo que a string é
tratado como um número, você pode usar CAST( ... AS
UNSIGNED)
no valor hexadecimal.
A sintaxe x'stringhexa'
(nova na versão
4.0) é baseada no padrão SQL e a sintaxe
0x
é baseada no ODBC. Strings hexadecimeis
são frequentemente usadas pelo ODBC para suprir valores para
colunas BLOB
. Você pode converter uma
string ou um número no formato hexadecimal com a função
HEX()
.
O valor NULL
significa ``sem dados'' e é
diferente de valores como 0
para tipos
numéricos ou strings vazias para tipos string. See
Secção A.5.3, “Problemas com Valores NULL
”.
NULL
pode ser representado por
\N
ao usar o formato de arquivo texto para
importação ou exportação (LOAD DATA
INFILE
, SELECT ... INTO OUTFILE
).
See Secção 6.4.8, “Sintaxe LOAD DATA INFILE
”.
Nomes de banco de dados, tabela, índice, coluna e apelidos seguem todos as mesmas regras no MySQL.
Note que as regras foram alteradas a partir do MySQL versão
3.23.6, quando introduzimos aspas em identificadores (nomes
banco de dados, tabela e coluna) com
‘`
’.
‘"
’ funcionará também para
citar identificadores se você executar no modo ANSI. See
Secção 1.8.2, “Executando o MySQL no modo ANSI”.
Identificador | Tamanho máximo (bytes) | Caracteres permitidos |
Banco de dados | 64 | Qualquer caractere que é permitido em um nome de diretório exceto
‘/ ’ ou
‘. ’. |
Tabela | 64 | Qualquer caractere permitido em um nome de arquivo, exceto
‘/ ’ ou
‘. ’. |
Coluna | 64 | Todos os caracteres. |
Alias | 255 | Todos os caracteres. |
Note que em adição ao mostrado acima, você não pode ter ASCII(0) ou ASCII(255) ou o caracter de citação (aspas) em um identificador.
Se o identificador é uma palavra restrita ou contêm caracteres
especiais você deve sempre colocá-lo entre
`
ao usá-lo:
mysql> SELECT * FROM `select` WHERE `select`.id > 100;
See Secção 6.1.7, “Tratamento de Palavras Reservadas no MySQL”.
Se você estiver executando o MySQL no modo
MAXDB
ou ANSI_QUOTES
, ele
também pode citar identificadores com aspas duplas:
mysql>CREATE TABLE "test" (col INT);
ERROR 1064: You have an error in your SQL syntax. (...) mysql>SET SQL_MODE="ANSI_QUOTES";
mysql>CREATE TABLE "test" (col INT);
Query OK, 0 rows affected (0.00 sec)
See Secção 4.1.1, “Opções de Linha de Comando do mysqld
”.
Em versões do MySQL anteriores a 3.23.6, as regras se nomes eram as seguintes:
Um nome pode consistir de caracteres alfanuméricos do
conjunto atual de caractres e também
‘_
’ e
‘$
’. O conjunto de caracteres
padrão é o ISO-8859-1 Latin1; e pode ser alterado com a
opção --default-character-set
no
mysqld
. See
Secção 4.7.1, “O Conjunto de Caracteres Utilizado para Dados e Ordenação”.
Um nome pode iniciar com qualquer caractere que é legal no nome. Em particular, pode iniciar com um número (isto difere de vários outros sistemas de bancos de dados!). Entretanto um nome não pode consistir somente de números.
O caractere ‘.
’ não pode ser
utilizado em nomes porque ele é usado para extender o
formato pelo qual você pode fazer referências a colunas
(veja abaixo).
É recomendado que você não utilize nomes como
1e
, porque uma expressão como
1e+1
é ambígua. Ela pode ser interpretada
como a expressão 1e + 1
ou como o número
1e+1
.
No MySQL você pode se referir a uma coluna utilizando uma das formas seguintes:
Coluna de referência | Significado |
nome_campo | Coluna nome_campo de qualquer tabela usada na
consulta contendo uma coluna com aquele nome. |
nome_tabela.nome_campo | Coluna nome_campo da tabela
nome_tabela do banco de dados atual. |
nome_bd.nome_tabela.nome_campo | Coluna nome_campo da tabela
nome_tabela do banco de dados
nome_bd . Esta forma é disponível no
MySQL Versão 3.22 ou posterior. |
`nome_coluna` | Uma coluna que é uma palavra chave ou contem caracteres especiais. |
Você não precisa especificar um prefixo de
nome_tabela
ou
nome_bd.nome_tabela
para uma referência de
coluna em uma instrução, a menos que a referência seja
ambígua. Por exemplo, suponha que cada tabela
t1
e t2
contenham uma
coluna c
, e você deve recuperar
c
em uma instrução
SELECT
que utiliza ambas tabelas
t1
e t2
. Neste caso,
c
é ambíguo porque ele não é único entre
as tabelas usadas na instrução, portanto deve ser indicado
qual é a tabela que se deseja escrever, t1.c
ou t2.c
. De mesma forma, se você for
recuperar de uma tabela t
em um banco de
dados db1
e uma tabela t
em um banco de dados db2
, você deve se
refererir às colunas nestas tabelas como
db1.t.nome_campo
e
db2.t.nome_campo
.
A sintaxe .nome_tabela
indica a tabela
nome_tabela
no banco de dados atual. Esta
sintaxe é aceitada para compatibilidade ODBC, porque alguns
programas ODBC prefixam os nomes das tabelas com um caracter
‘.
’.
No MySQL, bancos de dados e tabelas correspondem a diretórios e arquivos em seus diretórios. Consequentemente, o caso sensitivo no sistema operacional irá determinar o caso sensitivo nos nomes de bancos de dados e tabelas. Isto significa que nomes de bancos de dados e tabelas são caso sensitivo na maioria dos Unix e caso insensitivo no Windows. Uma exceção proeminente aqui é o Mac OS X, quando o o sistema de arquivos padrão HPS+ está sendo usado. No entanto o Mac OS X também suporta volumes UFS, esle são caso sensitivo no Mac OS X assim como são no Unix. See Secção 1.8.3, “Extensões do MySQL para o Padrão SQL-92”.
NOTA: Apesar de nomes de bancos
e tabelas serem caso insensitivo no Windows, você não deve
fazer referência a um certo banco de dados ou tabela utilizando
casos diferentes na mesma consulta. A consulta a seguir não
deve funcionar porque ela chama uma tabela como
minha_tabela
e outra como
MINHA_TABELA
.
mysql> SELECT * FROM minha_tabela WHERE MINHA_TABELA.col=1;
Nomes de colunas não são caso sensitivo em todas as circunstâncias.
Aliases nas tabelas são caso sensitivo. A consulta seguinte
não deve funcionar porque ela faz referência ao alias como
a
e como A
.
mysql> SELECT nome_campo FROM nome_tabela AS a
WHERE a.nome_campo = 1 OR A.nome_campo = 2;
Se você tem um problema para lembrar o caso usado para os nomes de tabelas, adote uma convenção consistente, como sempre criar bancos de dados e tabelas utilizando nomes em minúsculas.
Uma maneira para evitar este problema é iniciar o
mysqld
com -O
lower_case_nome_tabelas=1
. Por padrão esta opção é
1 no Windows e 0 no Unix.
Se lower_case_nome_tabelas
for 1, o MySQL
irá converte todos os nomes de tabelas para minúsculo no
armazenamento e pesquisa. (A partir da versão 4.0.2, esta
opção também se aplica ao nome do banco de dados. A partir da
4.1.1 isto também se aplica a alias de tabelas). Perceba que se
você alterar esta opção, será necessário converter
primeiramente seus nomes de tabelas antigos para minúsculo
antes de iniciar o mysqld
.
Se você mover os arquivos MyISAM
do Windows
pare o Unix, você pode, em alguns casos, precisar usar a
ferramenta mysql_fix_extensions
para
corrigir o caso ad extensão do arquivo em cada diretório de
banco de dados específico (.frm
em letra
minúscula, .MYI
e
.MYD
em letras maiúsculas).
mysql_fix_extensions
pode ser encontado no
subdiretório scripts
.
O MySQL suporta variáveis específicas da conexão com a
sintaxe @nomevariável
. Um nome de variável
pode consiste de caracteres alfanuméricos do conjunto de
caracteres atual e também ‘_
’,
‘$
’ e
‘.
’. O conjunto de caracteres
padrão é ISO-8859-1 Latin1; ele pode ser alterado com a
opção --default-character-set
do
mysqld
. See Secção 4.7.1, “O Conjunto de Caracteres Utilizado para Dados e Ordenação”.
Os nomes das variáveis de usuários são caso insensitivo nas
versão >= 5.0 e caso sensitivo nas versões < 5.0.
As variáveis não precisam ser inicializadas. Elas contém
NULL
por padrão e podem armazenar um valor
inteiro, real ou uma string. Todas as variáveis de uma thread
são automaticamente liberadas quando uma thread termina.
Você pode configurar uma variavel com a syntaxe
SET
.
SET @variável= { expressao inteira | expressao real | expressao string } [,@variável= ...].
Você também pode atribuir um valor a uma variável em outras
instruções diferentes de SET
. No entanto,
neste caso o operador de atribuição é :=
em vez de =
, porque =
é
reservado para comparações em instruções diferentes de
SET
:
mysql>SET @t1=0, @t2=0, @t3=0;
mysql>SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
+----------------------+------+------+------+ | @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 | +----------------------+------+------+------+ | 5 | 5 | 1 | 4 | +----------------------+------+------+------+
Variáveis de usuários devem ser utilizadas em expressões onde
são permitidas. Isto não inclui utiliza-las em contextos onde
um número é explicitamente necessário, assim como na
cláusula LIMIT
de uma instrução
SELECT
ou a clausula IGNORE number
LINES
de uma instrução LOAD DATA
.
NOTE: Em uma instrução
SELECT
, cada expressão só é avaliada
quando enviada ao cliente. Isto significa que nas cláusula
HAVING
, GROUP BY
, ou
ORDER BY
, você não pode fazer referência a
uma expreesão que envolve variáveis que são configuradas na
instrução SELECT
. Por examplo, a seguinte
instrução NÃO funcionará como o esperado:
SELECT (@aa:=id) AS a, (@aa+3) AS b FROM nome_tabela HAVING b=5;
A razão é que o @aa
não irá conter o
valor da linha atual, mas o valor da id
da
linha previamente aceita.
A regra geral é nunca atribuir e usar a mesma variável na mesma instrução.
Outra questão com configurar uma variável e usá-la na mesma
instrução é que o tipo do resultado padrão de uma variável
é baseada no tipo da variável no início da instrução.
(Assume-se que uma variável não atribuída possui o valor
NULL
e é do tipo STRING). O seguitne exemplo
ilustra isto:
mysql>SET @a="test";
mysql>SELECT @a,(@a:=20) FROM table_name;
Neste caso o MySQL relatará ao cliente que a coluna 1 é uma
string e converte todos os acessos de @a
a
strings, mesmo que @a seja configurada com um número para a
segunda linha. Depois que a instrução é executada
@a
será considerado como um número.
Se você tiver qualquer problema com isto, evite tanto configurar e usar a mesma variável na mesma instrução ou configurar a variável com 0, 0.0 ou "" antes de usá-la.
A partir do MySQL 4.0.3 fornecemos melhor acesso a diversas variáveis de sistema e conexão. Pode-se alterar a maioria dele ser ter de desligar o servidor.
Exite dois tipos de variáveis de sistema: Específica de threads (ou específica da conexão), variáveis que estão apenas na conexão atual e variáveis globais que são usadas para conigurqar eventos globais. Variáveis globais também são usadas para configurar os valores iniciais da variável específica da thread correspondente a nova conexão.
Quando o mysqld
inicia, todas as variáveis
globais são inicialisadas a partir dos argumentos de linha de
comando e arquivos de opção. Você pode alterar o valor com o
comando SET GLOBAL
command. Quando uma nova
thread é criada, a variável específica da thread é iniciada
a partir das variáveis globais e não alteram mesmo se você
executar um novo comando SET GLOBAL
.
Para definir os valor de uma variável
GLOBAL
, você deve usar uma das seguintes
sintaxes: (Aqui usamos sort_buffer_size
como
uma variável exemplo).
SET GLOBAL sort_buffer_size=valor; SET @@global.sort_buffer_size=valor;
Para definir o valor de uma variável
SESSION
, você pode usar uma das seguintes
sintaxes:
SET SESSION sort_buffer_size=valor; SET @@session.sort_buffer_size=valor; SET sort_buffer_size=valor;
Se você não especificar GLOBAL
ou
SESSION
então será usado
SESSION
. See Secção 5.5.6, “Sintaxe de SET
”.
LOCAL
é um sinônimo para
SESSION
.
Para recuperar o valor de uma variável
GLOBAL
você pode usar um dos seguintes
comandos:
SELECT @@global.sort_buffer_size; SHOW GLOBAL VARIABLES like 'sort_buffer_size';
Para retornar o valor de uma variável
SESSION
você pode usar um dos seguintes
comandos:
SELECT @@session.sort_buffer_size; SHOW SESSION VARIABLES like 'sort_buffer_size';
Quando você retorna o valor de
uma cariável com a sintaxe @@nome_variável
e você não especificar GLOBAL
ou
SESSION
então o MySQL retornará o valor
específico da thread (SESSION
), se ele
existir. Se não, o MySQL retornará o valor global.
A razão da exigência de GLOBAL
apenas para
definir a variável GLOBAL
, mas não para
recuperá-la e assegurar que não criemos problemas
posteriormente ao introduzirmos um variável específica da
thread com o mesmo nome ou remover uma variável específica da
thread. Neste caso, você pode acidentalmente alterar o estado
do servidor como um todo, e não apenas em sua conexão.
A seguir apresentamos uma lista completa de todas as variáveis
que altera e recupera se você pode usar
GLOBAL
ou SESSION
com
elas.
Nome Variável | Tipo Valor | Tipo |
autocommit | bool | SESSION |
big_tables | bool | SESSION |
binlog_cache_size | num | GLOBAL |
bulk_insert_buffer_size | num | GLOBAL | SESSION |
concurrent_insert | bool | GLOBAL |
connect_timeout | num | GLOBAL |
convert_character_set | string | SESSION |
delay_key_write | OFF | ON | ALL | GLOBAL |
delayed_insert_limit | num | GLOBAL |
delayed_insert_timeout | num | GLOBAL |
delayed_queue_size | num | GLOBAL |
error_count | num | SESSION |
flush | bool | GLOBAL |
flush_time | num | GLOBAL |
foreign_key_checks | bool | SESSION |
identity | num | SESSION |
insert_id | bool | SESSION |
interactive_timeout | num | GLOBAL | SESSION |
join_buffer_size | num | GLOBAL | SESSION |
key_buffer_size | num | GLOBAL |
last_insert_id | bool | SESSION |
local_infile | bool | GLOBAL |
log_warnings | bool | GLOBAL |
long_query_time | num | GLOBAL | SESSION |
low_priority_updates | bool | GLOBAL | SESSION |
max_allowed_packet | num | GLOBAL | SESSION |
max_binlog_cache_size | num | GLOBAL |
max_binlog_size | num | GLOBAL |
max_connect_errors | num | GLOBAL |
max_connections | num | GLOBAL |
max_error_count | num | GLOBAL | SESSION |
max_delayed_threads | num | GLOBAL |
max_heap_table_size | num | GLOBAL | SESSION |
max_join_size | num | GLOBAL | SESSION |
max_relay_log_size | num | GLOBAL |
max_sort_length | num | GLOBAL | SESSION |
max_tmp_tables | num | GLOBAL |
max_user_connections | num | GLOBAL |
max_write_lock_count | num | GLOBAL |
myisam_max_extra_sort_file_size | num | GLOBAL | SESSION |
myisam_repair_threads | num | GLOBAL | SESSION |
myisam_max_sort_file_size | num | GLOBAL | SESSION |
myisam_sort_buffer_size | num | GLOBAL | SESSION |
net_buffer_length | num | GLOBAL | SESSION |
net_read_timeout | num | GLOBAL | SESSION |
net_retry_count | num | GLOBAL | SESSION |
net_write_timeout | num | GLOBAL | SESSION |
query_cache_limit | num | GLOBAL |
query_cache_size | num | GLOBAL |
query_cache_type | enum | GLOBAL |
read_buffer_size | num | GLOBAL | SESSION |
read_rnd_buffer_size | num | GLOBAL | SESSION |
rpl_recovery_rank | num | GLOBAL |
safe_show_database | bool | GLOBAL |
server_id | num | GLOBAL |
slave_compressed_protocol | bool | GLOBAL |
slave_net_timeout | num | GLOBAL |
slow_launch_time | num | GLOBAL |
sort_buffer_size | num | GLOBAL | SESSION |
sql_auto_is_null | bool | SESSION |
sql_big_selects | bool | SESSION |
sql_big_tables | bool | SESSION |
sql_buffer_result | bool | SESSION |
sql_log_binlog | bool | SESSION |
sql_log_off | bool | SESSION |
sql_log_update | bool | SESSION |
sql_low_priority_updates | bool | GLOBAL | SESSION |
sql_max_join_size | num | GLOBAL | SESSION |
sql_quote_show_create | bool | SESSION |
sql_safe_updates | bool | SESSION |
sql_select_limit | bool | SESSION |
sql_slave_skip_counter | num | GLOBAL |
sql_warnings | bool | SESSION |
table_cache | num | GLOBAL |
table_type | enum | GLOBAL | SESSION |
thread_cache_size | num | GLOBAL |
timestamp | bool | SESSION |
tmp_table_size | enum | GLOBAL | SESSION |
tx_isolation | enum | GLOBAL | SESSION |
wait_timeout | num | GLOBAL | SESSION |
warning_count | num | SESSION |
unique_checks | bool | SESSION |
Variáveis marcadas com num
podem ter um
valor numérico. Variáveis marcadas com bool
podem ser definidas com 0, 1, ON
ou
OFF
. Variáveis do tipo
enum
devem, normalmente, ser atribuídas com
um dos valores disponíveis para a variável, mas podem também
ser definidas com o número correspondente ao valor enum. (O
primeiro valor enum é 0).
Aqui está uma descrição de algumas das variáveis:
Variáveis | Descrição |
identity | Alias para last_insert_id (compatibilidade com Sybase) |
sql_low_priority_updates | Alias para low_priority_updates |
sql_max_join_size | Alias para max_join_size |
version | Alias para VERSION() (compatibilidade com Sybase (?)) |
Uma descrição da outra definição de tabela pode ser
encontrada na seção de opções de inicialização, na
descrição de SHOW VARIABLES
e na seção
SET
. See
Secção 4.1.1, “Opções de Linha de Comando do mysqld
”. See
Secção 4.6.8.4, “SHOW VARIABLES
”. See
Secção 5.5.6, “Sintaxe de SET
”.
O servidor MySQL suporta os estilos de comentário # no
fim da linha
, -- no fim da linha
e
/* na linha ou em multiplas linhas */
mysql>select 1+1; # Este comentário continua até o fim da linha
mysql>select 1+1; -- Este comnetário continua até o fim da linha
mysql>select 1 /* Este é um comentário de linha */ + 1;
mysql>select 1+
/* Este é um comentário de múltiplas linhas */ 1;
Note que o estilo de comentário --
requer que
pelo menos um espaço após o código --
!
Embora o servidor entenda as sintaxes de comentários aqui
descritas, existem algumas limitções no modo que o cliente
mysql
analisa o comentário /* ...
*/
:
Caracteres de aspas simples e aspas duplas são utilizados
para indicar o início de uma string com aspas, mesmo dentro
de um comentário. Se as aspas não coincidirem com uma
segunda aspas dentro do comentário, o analisador não
percebe que o comentário tem um fim. Se você estiver
executando o mysql
interativamente, você
pode perceber a confusão ocorrida por causa da mudança do
prompt de mysql>
para
'>
ou ">
.
Um ponto e vírgula é utilizado para indicar o fim de uma instrução SQL e qualquer coisa que venha após ele indica o início da próxima instrução.
Estas limitações se aplicam tanto a quando se executa
mysql
interativamente quanto quando se coloca
oos comandos em um arquivo e pede para que
mysql
leia as entradas deste arquivo com o
comando mysql < some-file
.
MySQL suporta o estilo de comentário SQL-99
'--
' apenas se o segundo traço for seguido de
espaço See Secção 1.8.4.7, “'--
' como Início de Comentário”.
Um problema comum ocorre quando tentamos criar tabelas com nome
de campo que usam nomes de tipos de dados ou funções criadas
no MySQL, com TIMESTAMP
ou
GROUP
, Você poderá fazer isso (por exemplo,
ABS
é um nome de campo permitido). No
entanto espaços não são permitidos entre o nome da função e
o caracter ‘(
’, assim a função
pode ser distinguida de uma referência a um nome de coluna.
Se você iniciar o servidor com a opção
--ansi
ou
--sql-mode=IGNORE_SPACE
, o servidor permite que
a chamada da função tenha um espaço entre um nome de função
e o caracter ‘(
’ seguinte. Isto
faz com que o nome da funçao seja tratado como uma palavra
reservada; como um resultadom nomes de coluna que são o mesmo
que o nome de uma função devem ser colocada entre aspas como
descrito em Secção 6.1.2, “Nomes de Banco de dados, Tabela, Índice, Coluna e Alias”.
As seguintes palavras são explicitamente reservadas em MySQL.
Muitas delas são proibidas pelo ANSI SQL92 como nomes de campos
e/ou tabelas. (por examplo, group
). Algumas
poucas são reservadasporque o MySQL precisa delas e está
usando (atualmente) um analisador yacc
:
ADD | ALL | ALTER |
ANALYZE | AND | AS |
ASC | BEFORE | BETWEEN |
BIGINT | BINARY | BLOB |
BOTH | BY | CASCADE |
CASE | CHANGE | CHAR |
CHARACTER | CHECK | COLLATE |
COLUMN | COLUMNS | CONSTRAINT |
CONVERT | CREATE | CROSS |
CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP |
CURRENT_USER | DATABASE | DATABASES |
DAY_HOUR | DAY_MICROSECOND | DAY_MINUTE |
DAY_SECOND | DEC | DECIMAL |
DEFAULT | DELAYED | DELETE |
DESC | DESCRIBE | DISTINCT |
DISTINCTROW | DIV | DOUBLE |
DROP | DUAL | ELSE |
ENCLOSED | ESCAPED | EXISTS |
EXPLAIN | FALSE | FIELDS |
FLOAT | FLOAT4 | FLOAT8 |
FOR | FORCE | FOREIGN |
FROM | FULLTEXT | GRANT |
GROUP | HAVING | HIGH_PRIORITY |
HOUR_MICROSECOND | HOUR_MINUTE | HOUR_SECOND |
IF | IGNORE | IN |
INDEX | INFILE | INNER |
INSERT | INT | INT1 |
INT2 | INT3 | INT4 |
INT8 | INTEGER | INTERVAL |
INTO | IS | JOIN |
KEY | KEYS | KILL |
LEADING | LEFT | LIKE |
LIMIT | LINES | LOAD |
LOCALTIME | LOCALTIMESTAMP | LOCK |
LONG | LONGBLOB | LONGTEXT |
LOW_PRIORITY | MATCH | MEDIUMBLOB |
MEDIUMINT | MEDIUMTEXT | MIDDLEINT |
MINUTE_MICROSECOND | MINUTE_SECOND | MOD |
NATURAL | NOT | NO_WRITE_TO_BINLOG |
NULL | NUMERIC | ON |
OPTIMIZE | OPTION | OPTIONALLY |
OR | ORDER | OUTER |
OUTFILE | PRECISION | PRIMARY |
PRIVILEGES | PROCEDURE | PURGE |
RAID0 | READ | REAL |
REFERENCES | REGEXP | RENAME |
REPLACE | REQUIRE | RESTRICT |
REVOKE | RIGHT | RLIKE |
SECOND_MICROSECOND | SELECT | SEPARATOR |
SET | SHOW | SMALLINT |
SONAME | SPATIAL | SQL_BIG_RESULT |
SQL_CALC_FOUND_ROWS | SQL_SMALL_RESULT | SSL |
STARTING | STRAIGHT_JOIN | TABLE |
TABLES | TERMINATED | THEN |
TINYBLOB | TINYINT | TINYTEXT |
TO | TRAILING | TRUE |
UNION | UNIQUE | UNLOCK |
UNSIGNED | UPDATE | USAGE |
USE | USING | UTC_DATE |
UTC_TIME | UTC_TIMESTAMP | VALUES |
VARBINARY | VARCHAR | VARCHARACTER |
VARYING | WHEN | WHERE |
WITH | WRITE | X509 |
XOR | YEAR_MONTH | ZEROFILL |
São as seguintes as novas palavras reservadas do MySQL 4.0:
CHECK | FORCE | LOCALTIME |
LOCALTIMESTAMP | REQUIRE | SQL_CALC_FOUND_ROWS |
SSL | X509 | XOR |
São as seguintes as novas palavras reservadas do MySQL 4.1:
BEFORE | COLLATE | CONVERT |
CURRENT_USER | DAY_MICROSECOND | DIV |
DUAL | FALSE | HOUR_MICROSECOND |
MINUTE_MICROSECOND | MOD | NO_WRITE_TO_BINLOG |
SECOND_MICROSECOND | SEPARATOR | SPATIAL |
TRUE | UTC_DATE | UTC_TIME |
UTC_TIMESTAMP | VARCHARACTER |
Os simbolos seguintes (da tabela acima) não são permitidos pelo SQL-99 mas permitidos pelo MySQL como nome de campos/tabelas. Isto ocorre porque alguns destes nomes são muito naturais e vários pessoas já o utilizaram.
ACTION
BIT
DATE
ENUM
NO
TEXT
TIME
TIMESTAMP
MySQL suporta um certo números de tipos de campos que podem ser agrupaos em três categorias: tipos numéricos, tipos de data e hora, e tipos string (caracteres). Esta seção primeiro lhe dá uma visão geral dos tipos disponíveis e resume as exigencias de armazenamento em cada tipo de coluna, também fornece uma descrição mais detalhada da propriedade dos tipos em cada categoria. A visão dada é propositalmente breve. As descrições mais detalhdas devem ser consultadas para informações adicionais sobre tipos de campo particulares como os formatos permitidos nos quais você pode especificar valores.
Os tipos de campos suportados pelo MySQL estão listados abaixo: As seguintes letras são usadas como código nas descrições:
M
Indica o tamanho máximo do display. O tamanho máximo oficial do display é 255.
D
Aplica aos tipos de ponto flutuante e indica o número de
digitos após o ponto decimal. O maior valor possível é 30,
mas não pode ser maior que M
-2.
Colchetes (‘[
’ and
‘]
’) indicam partes de tipos
específicos que são opicionais
Note que se você especificar ZEROFILL
para um
campo MySQL automaticamente irá adicionar o atributo
UNSIGNED
ao campo.
Aviso: você deve estar ciente de
que quando fizer uma subtração entre valores inteiros, onde um
deles é do tipo UNSIGNED
, o resultado será
sem sinal! See Secção 6.3.5, “Funções de Conversão”.
TINYINT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro muito pequeno. A faixa deste inteiro com sinal é
de -128
até 127
. A
faixa sem sinal é de 0
até
255
.
BIT
, BOOL
,
BOOLEAN
Estes são sinônimos para TINYINT(1)
.
O sinônimo BOOLEAN
foi adicionado na
versão 4.1.0.
Um tipo boolean verdadeiro será introduzido de acordo com o SQL-99.
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro pequeno. A faixa do inteiro com sinal é de
-32768
até 32767
. A
faixa sem sinal é de 0
a
65535
.
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro de tamanho médio. A faica com sinal é de
-8388608
a 8388607
. A
faixa sem sinal é de 0
to
16777215
.
INT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro de tamanho normal. A faixa com sinal é de
-2147483648
a
2147483647
. A faixa sem sinal é de
0
a 4294967295
.
INTEGER[(M)] [UNSIGNED] [ZEROFILL]
Este é um sinônimo para INT
.
BIGINT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro grande. A faixa com sinal é de
-9223372036854775808
a
9223372036854775807
. A faixa sem sinal é
de 0
a
18446744073709551615
.
Existem algumas coisas sobre campos BIGINT
sobre as quias você deve estar ciente:
Todas as operações aritiméticas são feitas usando
valores BIGINT
ou
DOUBLE
com sinal, não devemos
utilçizar inteiros sem sinal maiores que
9223372036854775807
(63 bits) exceto
com funções ded bit! Se você fizer isto, alguns dos
últimos digitos no resultado podem estar errados por
causa de erros de arredondamento na conversão de
BIGINT
para
DOUBLE
.
O MySQL 4.0 pode tratar BIGINT
nos
seguintes casos:
Usar inteiros para armazenar grandes valores sem
sinais em uma coluna BIGINT
.
Em MIN(big_int_column)
e
MAX(big_int_column)
.
Quando usar operadores (+
,
-
, *
, etc.)
onde ambos os operandos são inteiros.
Você pode armazenar valores inteiro exatos em um campo
BIGINT
aramzenando-os como string,
como ocorre nestes casos não haverá nenhuma
representação intermediaria dupla.
‘-
’,
‘+
’, e
‘*
’ serão utilizados em
cálculos aritiméticos BIGINT
quando
ambos os argumentos forem valores do tipo
INTEGER
! Isto significa que se você
multilicar dois inteiros grandes (ou obter resultados de
funções que retornam inteiros) você pode obter
resultados inesperados quando o resultado for maior que
9223372036854775807
.
FLOAT(precisão) [UNSIGNED] [ZEROFILL]
Um número de ponto flutuante. Não pode ser sem sinal.
precisão
pode ser
<=24
para um número de ponto flutuante
de precisão simples e entre 25 e 53 para um número de ponto
flutuante de dupla-precisão. Estes tipos são como os tipos
FLOAT
e DOUBLE
descritos
logo abaixo. FLOAT(X)
tem o mesma faixa que
os tipos correspondentes FLOAT
e
DOUBLE
, mas o tamanho do display e número
de casas decimais é indefinido.
Na versão 3.23 do MySQL, este é um verdadeiro valor de ponto
flutuante. Em versões anteriores ,
FLOAT(precisão)
sempre tem 2 casas
decimais.
Note que o uso de FLOAT
pode trazer alguns
problemas inesperados como nos cálculos já que em MySQL
todos são feitos com dupla-precisão. See
Secção A.5.6, “Resolvendo Problemas Com Registros Não Encontrados”.
FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
Um número de ponto flutuante pequeno (precisão simples). Os
valores permitidos estão entre
-3.402823466E+38
e
-1.175494351E-38
, 0
e
entre 1.175494351E-38
e
3.402823466E+38
. Se
UNSIGNED
for especificado, valores
negativos não são permitidos O M
é a
largura do display e o D
é o número de
casas decimais. FLOAT
sem um argumento ou
FLOAT(X)
onde X
<=24
tende a um número de ponto flutuante de precisão simples.
DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
Um número de ponto flutuante de tamanho normal
(dupla-precisão). Valores permitidos estão entre
-1.7976931348623157E+308
e
-2.2250738585072014E-308
,
0
e entre
2.2250738585072014E-308
e
1.7976931348623157E+308
. Se
UNSIGNED
for especificado, valores
negativos não são permitidos. O M
é a
largura do display e o D
é número de casa
decimais. DOUBLE
sem argumento ou
FLOAT(X)
onde 25 <= X <= 53 são
números de ponto flutuante de dupla-precisão.
DOUBLE PRECISION[(M,D)] [UNSIGNED]
[ZEROFILL]
, REAL[(M,D)] [UNSIGNED]
[ZEROFILL]
Estes são sinônimos para DOUBLE
.
DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
Um número de ponto flutuante não empacotado. Se comporta
como um campo CHAR
: ``não empacotado''
significa que o número é armazenado como uma string, usando
um caracter para cada digito do valor. O ponto decimal e, para
números negativos, o sinal de menos
(‘-
’), não são contados em M
(mas é reservado espaço para isto). Se D
for 0, os valores não terão ponto decimal ou parte
fracionária. A faixa máxima do valor
DECIMAL
é a mesma do
DOUBLE
, mas a faixa atual para um campo
DECIMAL
dado pode ser limitado pela escolha
de M
e D
. Se
UNSIGNED
é especificado, valores negativos
não são permitidos.
Se D
não for definido será considerado
como 0. Se M
não for definido é
considerado como 10.
Note que antes da versão 3.23 do MySQL o argumento
M
deve incluir o espaço necessário para o
sinal é o ponto decimal.
DEC[(M[,D])] [UNSIGNED] [ZEROFILL]
,
NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL]
,
FIXED[(M[,D])] [UNSIGNED] [ZEROFILL]
Este é um sinônimo para DECIMAL
.
O alias FIXED
foi adicionado na versão
4.1.0 para compatibilidade com outros servidores.
DATE
Uma data. A faixa suportada é entre
'1000-01-01'
e
'9999-12-31'
. MySQL mostra valores
DATE
no formato
'AAAA-MM-DD'
, mas permite a você a
atribuir valores a campos DATE
utilizando
tanto strings quanto números. See Secção 6.2.2.2, “Os Tipos DATETIME
, DATE
e TIMESTAMP
”.
DATETIME
Um combinação de hora e data. A faixa suportada é entre
'1000-01-01 00:00:00'
e
'9999-12-31 23:59:59'
. MySQL mostra valores
DATETIME
no formato 'AAAA-MM-DD
HH:MM:SS'
, mas permite a você que atribuir valores
a campos DATETIME
utilizado strings ou
números. See Secção 6.2.2.2, “Os Tipos DATETIME
, DATE
e TIMESTAMP
”.
TIMESTAMP[(M)]
Um timestamp. A faixa é entre '1970-01-01
00:00:00'
e algum momento no ano
2037
.
No MySQL 4.0 ou anteriores, os valores
TIMESTAMP
são exibidos nos formatos
YYYYMMDDHHMMSS
,
YYMMDDHHMMSS
, YYYYMMDD
,
ou YYMMDD
, dependendo se
M
é 14
(ou não
definido), 12
, 8
ou
6
, mas permite a você atribuir valores ao
campo TIMESTAMP
usando strings ou números.
Um campo TIMESTAMP
é util para gravar a
data e a hora em uma operação de INSERT
or UPDATE
porque é automaticamente
definido a data e a hora da operação mais recente se você
próprio não especificar um valor. Você também pode definir
a data e a hora atual atribuindo ao campo um valor
NULL
. See
Secção 6.2.2, “Tipos de Data e Hora”.
Desde o MySQL 4.1, TIMESTAMP
é retornado
com um string com o formato 'YYYY-MM-DD
HH:MM:SS'
. Se você deseja tê-lo como um número
você deve adcionar +0 a coluna timestamp. Teimestamp de
tamanhos diferentes não são supoortados. Desde a versão
4.0.12, a opção --new
pode ser usada para
fazer o servidor se comportar como na versào 4.1.
Um TIMESTAMP
sempre é armazenado em 4
bytes. O argumento M
só afeta como a
coluna TIMESTAMP
é exibida.
Note que colunas do tipo TIMESTAMP(M)
columns onde M é 8 ou 14 são apresentadas como números
enquanto as outras colunas TIMESTAMP(M)
são strings. Isto é apenas para assegurar que podemos
eliminar e restaurar com segurança tabelas com estes tipos!
See Secção 6.2.2.2, “Os Tipos DATETIME
, DATE
e TIMESTAMP
”.
TIME
Uma hora. A faixa é entre '-838:59:59'
e
'838:59:59'
. MySQL mostra valores
TIME
no formato
'HH:MM:SS'
, mas permite a você atribuir
valores para as colunas TIME
usando strings
ou números. See Secção 6.2.2.3, “O Tipo TIME
”.
YEAR[(2|4)]
Um ano no formato de 2 ou 4 digitos (padrão são 4 digitos).
Os valores permitidos estão entre 1901
e
2155
, 0000
no formato de
4 digitos, e 1970-2069 se você estiver usando o formato de 2
digitos (70-69). MySQL mostra valores YEAR
no formato YYYY
, mas permie atribuir
valores aos campos do tipo YEAR
usando
strings ou números. (O tipo YEAR
é novo
na versão 3.22 do MySL). See Secção 6.2.2.4, “O Tipo YEAR
”.
[NATIONAL] CHAR(M) [BINARY | ASCII |
UNICODE]
Uma string de tamanho fixo que é sempre preenchida a direita
com espaços até o tamanho especificado quando armazenado. A
faixa de M
é de 1 a 255 caracteres.
Espaços extras são removidos quando o valor é recuperado.
Valores CHAR
são ordenados e comparados no
modo caso insensitivo de acordo com o conjunto de caracteres
padrão, a menos que a palavra chave BINARY
seja utilizada.
A partir da versão 4.1.0, se o valor M
especificado é maio que 255, o tipo de coluna é convertido
para TEXT
. Este é um recurso de
compatibilidade.
NATIONAL CHAR
(ou em sua forma reduzida
NCHAR
) é o modo SQL-99 de definir que um
campo CHAR
deve usar o conjunto CHARACTER
padrão. Este é o padrão no MySQL.
CHAR
é uma simplificação para
CHARACTER
.
A partir da versão 4.1.0, o atributo ASCII
pode ser especificado o que atribui o conjunto de caracteres
latin1
a coluna CHAR
.
A partir da versão 4.1.1, o atributo
UNICODE
pode ser especificado o que atribui
o conjunto de caracteres ucs2
a coluna
CHAR
.
O MySQL lhe permite criar um campo do tipo
CHAR(0)
.Isto é muito útil quando você
precisa de comptibilidade com aplicativos antigos que dependem
da existência de uma coluna, mas que, na verdade, não
utiliza um valor. Isto também é muito bom quando você
precisa de uma coluna que só pode receber 2 valores. Um
CHAR(0)
, que não é definido como um
NOT NULL
, só irá ocupar um bit e pode
assumir 2 valores: NULL
or
""
. See Secção 6.2.3.1, “Os Tipos CHAR
e VARCHAR
”.
BIT
, BOOL
,
CHAR
This is a synonym for CHAR(1)
.
[NATIONAL] VARCHAR(M) [BINARY]
Uma string de tamanho variável.
NOTA: Espaços extras são
removidos quando o caracter é armazenado (o que difere da
especificação ANSI SQL). A faixa de M
é
de 1 a 255 characters. Valores VARCHAR
são
ordenados e comparados no modo caso insensitivo a menos que a
palavra chave BINARY
seja utilizada. See
Secção 6.5.3.1, “Alteração de Especificações de Colunas”.
A partir da versão 4.1.0, se o valor M
especificado é maio que 255, o tipo de coluna é convertido
para TEXT
. Este é um recurso de
compatibilidade.
VARCHAR
é uma simplificação para
CHARACTER VARYING
. See
Secção 6.2.3.1, “Os Tipos CHAR
e VARCHAR
”.
TINYBLOB
, TINYTEXT
Um campo BLOB
ou TEXT
com tamanho máximo de 255 (2^8 - 1) caracteres. See
Secção 6.5.3.1, “Alteração de Especificações de Colunas”. See
Secção 6.2.3.2, “Os Tipos BLOB
e TEXT
”.
BLOB
, TEXT
Um campo BLOB
ou TEXT
com tamanho máximo de 65535 (2^16 - 1) caracteres. See
Secção 6.5.3.1, “Alteração de Especificações de Colunas”. See
Secção 6.2.3.2, “Os Tipos BLOB
e TEXT
”.
MEDIUMBLOB
, MEDIUMTEXT
Um campo BLOB
ou TEXT
com tamanho máximo de 16777215 (2^24 - 1) caracteres. See
Secção 6.5.3.1, “Alteração de Especificações de Colunas”. See
Secção 6.2.3.2, “Os Tipos BLOB
e TEXT
”.
LONGBLOB
, LONGTEXT
Um campo BLOB
ou TEXT
com tamanho máximo de 4294967295 ou 4G (2^32 - 1) caracteres.
See Secção 6.5.3.1, “Alteração de Especificações de Colunas”. See
Secção 6.2.3.2, “Os Tipos BLOB
e TEXT
”. Até a versão 3.23 o protocolo
cliente/servidor e tabelas MyISAM tinham um limite de 16M por
pacote de transmissão/registro de tabela, a partir da versão
4.x o tamanho máximo permitido das colunas
LONGTEXT
ou LONGBLOB
depende do tamanho máximo configurado para o pacote no
protocolo cliente/servidor e da memória disponível. See
Secção 6.2.3.2, “Os Tipos BLOB
e TEXT
”.
ENUM('valor1','valor2',...)
Uma enumeração. Um objeto string que só pode ter um valor,
selecionado da lista de valores 'valor1'
,
'valor2'
, ...
,
NULL
ou valor especial de erro
""
. Um ENUM
pode ter um
máximo de 65535 valores diferentes. See
Secção 6.2.3.3, “O Tipo ENUM
”.
SET('valor1','valor2',...)
Um conjunto. Um objeto string que pode ter zero ou mais
valores, cada um deve ser selecionado da lista de valores
'valor1'
, 'valor2'
,
...
. Um SET
pode ter
até 64 membros. See Secção 6.2.3.4, “O Tipo SET
”.
MySQL suporta todos os tipos numéricos da ANSI/ISO SQL92. Estes
tipos incluem o tipos de dados numéricos exatos
(NUMERIC
, DECIMAL
,
INTEGER
, e SMALLINT
),
assim como o tipos de dados numéricos aproximados
(FLOAT
, REAL
, e
DOUBLE PRECISION
). A palavra-chave
INT
é um sinônimo para
INTEGER
, e a palavra-chave
DEC
é um sinônimo para
DECIMAL
.
Os tipos NUMERIC
e DECIMAL
são implementados como o mesmo tipo pelo MySQL, como permitido
pelo padrão SQL92. Eles são usados por valores para os quais
é importante preservar a exatidão como, por exemplo, dados
monetários. Quando é declarado um campo de algum desses tipos
a precisão e a escala podem ser (e normalmente é)
especificadas; por exemplo:
salario DECIMAL(5,2)
Neste exemplo, 5
(precisão
) representa o número de digitos
decimais significantes que serão armazenados no valor, e
2
(escala
) representa o
número de dígitos que serão armazenados após o ponto
decimal. Neste caso, no entanto, a faixa de valores que podem
ser armazendos na coluna salario
é de
-99.99
a 99.99
. (MySQL
pode, na verdade, armazenar numeros acima de
999.99
neste campo porque ele não precisa
armazenar o sinal para números positivos).
Em ANSI/ISO SQL92, a sintaxe DECIMAL(p)
é
equivalente a DECIMAL(p,0)
. Da mesma forma, a
sintaxe DECIMAL
é equivalente a
DECIMAL(p,0)
, onde a implementação permite
decidir o valor de p
. MySQL ainda não
suporta nenhuma dessas duas formas variantes dos tipos de dados
DECIMAL
/NUMERIC
. Este,
geralmente, não é um problema sério, já que os principais
benefícios destes tipos derivam da habilidade de controlar
precisão e escala explicitamente.
Valores DECIMAL
e NUMERIC
são armazenados como strings, ao invés de um número de
ponto-flutuante binário, para preservar o precisão decimal
destes valores. Um caracter é usado para cada digito, para o
ponto decimal (se escala
> 0), e para o
sinal ‘-
’ (para números
negativos). Se escala
é 0, valores
DECIMAL
e NUMERIC
não
contém ponto decimal ou parte fracionária.
A faixa máxima dos valores DECIMAL
e
NUMERIC
é o mesmo do
DOUBLE
, mas a faixa real para um campo
DECIMAL
or NUMERIC
pode
ser limitado pela precisão
ou pela
escala
para uma dada coluna. Quando é
atribuído a uma coluna um valor com mais digitos após o ponto
decimal do que o permitido especificado na
escala
, o valor é arredondado para aquela
escala
. Quando é atribuido um valor a uma
coluna DECIMAL
ou NUMERIC
o qual excede a faixa determinada pelas
precisão
e escala
especificada (ou padrão), MySQL armazena o valor correspondente
ao final daquela faixa.
Como uma extensão do padrão ANSI/ISO SQL92, MySQL também
suporta os tipos integrais TINYINT
,
MEDIUMINT
, e BIGINT
como
listado nas tabelas abaixo. Outra extensão suportada pelo MySQL
é especificar, opcionalmente, o tamanho do display de um valor
inteiro entre parenteses seguindo o nome do tipo (por exemplo,
INT(4)
). Esta especificação opcional do
tamanho é usada para preenchimento a esquerda do display de
valores cujo tamanho é menor que o especificado para a coluna,
mas não limita a faixa de valores que podem ser armazendos na
coluna, nem o número de dígitos que serão mostrados para
valores que excederem o tamanho especificado na coluna. Quando
usados em conjunto com o atributo opcional de extensão
ZEROFILL
, o padrão do preenchimento de
espaços é a substituição por zeros. Por exemplo, para uma
coluna declarada com INT(5) ZEROFILL
, o valor
4
é retornado como 00004
.
Note que se você armazenar valores maiores que a largura do
display em um coluna do tipo inteiro, você pode ter problemas
quando o MySQL gerar tabelas temporárias para algum join
complicado, já que nestes casos o MySQL acredita que os dados
cabem na largura original da coluna.
Todos os tipos inteiros podem ter um atributo opcional
(não-padrão) UNSIGNED
. Valores sem sinal
podem ser usados quando você permite apenas números positivos
em uma coluna e você precisa de uma faixa de valores um pouco
maior para a coluna.
Desde o MySQL 4.0.2, tipos de ponto flutuante também podem ser
sem sinal (UNSIGNED
). Como no tipos inteiros,
este atributoprevine que valores negativos sejam armazenados na
coluna. Ao contrário dos tipos negativos, o valor máximo da
faixa permitida permanece o mesmo.
O tipo FLOAT
é usado para representar tipos
de dados numéricos aproximados. O padrão SQL-92 permite uma
especificação opcional da precisão (mas não da faixa do
expoente) em bits, após a a palavra FLOAT
e
entre parenteses. A implementação MySQL também suporta esta
especificação opcional de precisão. Quando
FLOAT
é usada para uma tipo de coluna sem
especificação de precisão, MySQL utiliza quatro bytes para
armazenar os valores. Uma sintaxe variante também é suportada,
com dois numeros entre parenteses após a palavra
FLOAT
. Com esta opção, o primeiro número
continua a representar a quantidade de bytes necessária para
armazenar o valor, e o segundo número especifica o número de
dígitos a serem armazenados e mostrados após o ponto decimal
(como com DECIMAL
e
NUMERIC
). Quando é pedido ao MySQL para
armazenar um número em uma coluna com mais digitos decimais
após o ponto decimal que o especificado para esta coluna, o
valor é arredondado eliminando os digitos extras quando
armazenado.
Os tipos REAL
e DOUBLE
PRECISION
não aceitam especificações de precisão.
Como uma extensão do padrão SQL-92, o MySQL reconhece
DOUBLE
como um sinônimo para o tipo
DOUBLE PRECISION
. Em constraste com a
exigencia do padrão de que a precisão do tipo
REAL
seja menor que aquele usado pelo
DOUBLE PRECISION
, MySQL implementa ambos como
valores de ponto flutuante de 8 bits de dupla precisão (quando
não estiver executando em ``modo ANSI''). Para uma
portabilidade máxima, códigos que requerem armazenamento de
valores de dados numéricos aproximados usam
FLOAT
ou DOUBLE PRECISION
sem especificação de precisão ou de numeros decimais.
Quando solicitado a armazenar um valor em uma coluna numérica que está fora da faixa permitida pelo tipo da coluna, o MySQL ajusta o valor ao limite da faixa permitida mais apropriado e armazena este valor.
Por exemplo, a faixa de uma coluna INT
é de
-2147483648
a 2147483647
.
Se você tentar inserir -9999999999
em uma
coluna INT
, o valor é ajustado para o limite
mais baixo da faixa de valores e -2147483648
é armazenado. Da mesma forma, se você tentar inserir
9999999999
, 2147483647
será armazenado.
Se o campo INT
é
UNSIGNED
, o tamanho da faixa do campo é o
mesmo mas o limite passa a ser de 0
a
4294967295
. Se você tentar armazenar
-9999999999
e 9999999999
,
os valores armazenados na coluna serão 0
e
4294967296
.
Conversões que ocorrem devido a ajustes são relatados como
``avisos'' para ALTER TABLE
, LOAD
DATA INFILE
, UPDATE
, e instruções
INSERT
multi-registros.
Tipo | Bytes | De | Até |
TINYINT | 1 | -128 | 127 |
SMALLINT | 2 | -32768 | 32767 |
MEDIUMINT | 3 | -8388608 | 8388607 |
INT | 4 | -2147483648 | 2147483647 |
BIGINT | 8 | -9223372036854775808 | 9223372036854775807 |
Os tipos de data e hora são DATETIME
,
DATE
, TIMESTAMP
,
TIME
, e YEAR
. Cada um
desses tipos tem uma faixa de valores legais, assim com um valor
``zero'' que é usado quando você especifica um valor ilegal.
Note que o MySQL permite que você armazene certos valores de
datas inexistentes, como 1999-11-31
. A razão
para isto é que pensamos que é responsabilidade do aplicativo
tratar das verificações de data, não do servidor SQL. Para
fazer uma verificação 'rápida' de data, MySQL só checa se o
mês está na faixa de 0-12 e o dia está na faixa de 0-31. As
faixas acima são definidas desta forma porque MySQL lhe permite
armazenar, em um campo DATE
ou
DATETIME
, datas onde o dia ou o dia/mês são
zero. Isto é extremamente útil para aplicativos que precisam
armazenar uma data de nascimento na qual você não sabe a data
exata. Nestes casos você simplesmente armazena a data como
1999-00-00
ou 1999-01-00
.
(Você não pode esperar obter um valor correto para funções
como DATE_SUB()
ou
DATE_ADD
para datas como estas.)
Aqui estão algumas considerações para ter em mente quando estiver trabalhando com tipos de data e hora.
MySQL recupera valores para um tipo de data ou hora dado em um formato padrão, mas ele tenta interpretar uma variedade de formatos para os valores fornecidos (por exemplo, quando você especifica um valor a ser atribuido ou comparado a um tipo de data ou hora). No entanto, só os formatos descritos na seção seguinte são suportados. É esperado que você forneça valores permitidos. Resultados imprevisiveis podem ocorrer se você usar outros formatos.
Embora o MySQL tente interpretar valores em diversos
formatos, ele sempre espera que a parte da data referente ao
ano esteja mais a esquerda do valor. Datas devem ser dadas
na ordem ano-mês-dia (por exemplo,
'98-09-04'
), ao invés das ordens mais usadas
mês-dia-ano ou dia-mês-ano (por exemplo:
'09-04-98'
,
'04-09-98'
).
MySQL converte automaticamente um tipo de data ou hora em um número se o valor é usado em um contexto numérico, e vice-versa.
Quando o MySQL encontra um valor para um tipo de data ou
hora que está fora da faixa permitida ou é ilegal neste
tipo (veja o início desta seção), ele converte o valor
para ``zero''. (A exceção ocorre no campo
TIME
, onde o valor fora da faixa é
ajustado para o valor limite apropriado na faixa de valores
deste tipo.) A tabela abaixo mostra o formato do valor
``zero'' para cada tipo:
Tipo de Coluna | Valor ``Zero'' |
DATETIME | '0000-00-00 00:00:00' |
DATE | '0000-00-00' |
TIMESTAMP | 00000000000000 (tamanho depende do tamanho do
display) |
TIME | '00:00:00' |
YEAR | 0000 |
Os valores ``zero'' são especiais, mas você pode armazenar
ou fazer referência a eles explicitamente usando os valores
mostrados na tabela. Você também pode fazer into usando
'0'
ou 0
, o que é
mais fácil de escrever.
Valores ``zero'' para data ou hora usados em
MyODBC são convertidos
automaticamente para NULL
na versão
2.50.12 MyODBC e acima,
porque ODBC não pode tratar tais valores.
O MySQL tem sua própria segurança para o ano 2000 (see Secção 1.2.5, “Compatibilidade Com o Ano 2000 (Y2K)”), mas os dados entrados no MySQL podem não ter. Qualquer entrada contendo valores de ano de 2 digitos é ambíguo, porque o século é desconhecido. Tais valores devem ser interpretados na forma de 4 digitos já que o MySQL armazena anos internamente utilizando 4 digitos.
Para tipos DATETIME
,
DATE
, TIMESTAMP
e
YEAR
, MySQL interpreta datas com valores
ambíguos para o ano usando as seguintes regras:
Valores de ano na faixa 00-69
são
convertidos para 2000-2069
.
Valores de anos na faixa 70-99
são
convertidos para 1970-1999
.
Lembre-se de que essas regras fornecem apenas palpites razoáveis sobre o que a sua data significa. Se a heurística usada pelo MySQL não produz o valor você deve fornecer entre sem ambiguidade contendo valores de ano de 4 digitos.
ORDER BY
irá ordenar tipos
YEAR/DATE/DATETIME
de 2 digitos
apropriadamente.
Note tembém que algumas funções com
MIN()
e MAX()
irão
converter TIMESTAMP/DATE
para um número.
Isto significa que um timestamp com ano de 2 digitos não irá
funcionar corretamente com estas funções. A solução neste
caso é converter o TIMESTAMP/DATE
para um
formato de ano de 4 digitos ou usar algo como
MIN(DATE_ADD(timestamp,INTERVAL 0 DAYS))
.
Os tipos DATETIME
, DATE
,
e TIMESTAMP
são relacionados. Esta seção
descreve suas características, como eles se assemelham ou
como se diferem.
O tipo DATETIME
é usado quando você
precisa de valores que contém informações sobre data e a a
hora. MySQL recupera e mostra valores
DATETIME
no formato 'YYYY-MM-DD
HH:MM:SS'
. A faixa suportada é de
'1000-01-01 00:00:00'
até
'9999-12-31 23:59:59'
. (``Suportada''
significa que embora valores anteriores possam funcionar, não
há nenhura garantia de disto.)
O tipo DATA
é usado quando se necessita
apenas do valor da data, sem a parte da hora. MySQL recupera e
mostra valores do tipo DATA
no formato
'YYYY-MM-DD'
. A faixa suportada é de
'1000-01-01'
até
'9999-12-31'
.
A coluna do tipo TIMESTAMP
possui
comportamento e propriedade variado, dependendo da versão do
MySQL e do modo SQL que o servidor está executando.
Comportamento do
TIMESTAMP
ao executar no modo
MAXDB
Quando o MySQL está executando no modo
SQPDB
, o TIMESTAMP
comporta como DATETIME
. Nenhuma
atualização automática da coluna
TIMESTAMP
ocorre, como descrito no
parágrafo seguinte. O MySQL pode ser executado no modo
MAXDB
a partir da versão 4.1.1. See
Secção 4.1.1, “Opções de Linha de Comando do mysqld
”.
Comportamento do
TIMESTAMP
quando não está executando no
modo MAXDB
O tipo de campo TIMESTAMP
fornece um tipo
que pode ser usado para, automaticamente, marcar operações
INSERT
or UPDATE
com a
data e hora atual. Se você tiver multiplas colunas
TIMESTAMP
, só a primeira é atualizada
automaticamente.
Atualizações automaticas da primeira coluna
TIMESTAMP
ocorrem sob qualquer uma das
seguintes condições:
A coluna não é explicitamente especificada em uma
instrução INSERT
ou LOAD
DATA INFILE
.
A coluna não é explicitamente especificada em uma
instrução UPDATE
e e alguma outra
coluna muda o valor. (Note que um
UPDATE
que coloca em uma coluna o mesmo
valor que ele já possui não irá causar a atualização
da coluna TIMESTAMP
, porque se você
atribui a uma coluna o seu valor atual, MySQL ignora a
atualização para maior eficiência).
Você define explicitamente a uma coluna
TIMESTAMP
o valor
NULL
.
Outras colunas TIMESTAMP
, além da primeira
podem ser definidas com a data e hora atuais. Basta defini-las
com NULL
ou NOW()
Você pode definir colunas TIMESTAMP
com um
valor diferente da data e hora atuais colocando explicitamente
o valor desejado. Isto é verdade mesmo para a primeira coluna
TIMESTAMP
. Você pode usar esta propriedade
se, por exemplo, você quiser que um
TIMESTAMP
tenha seu valor definido como a
data e hora atuais na criação de registros, mas não quer
alterá-los quando o registro for atualizado mais tarde:
Deixe o MySQL definir a coluna quando o registro é criado. Isto irá inicializa-la com a data e hora atuais.
Quando você realizar subsequentes atualizações em
outras colunas do registro, defina explicitamente a coluna
TIMESTAMP
com o valor atual.
Por outro lado, você pode achar que é mais fácil usar uma
coluan DATETIME
que você inicializa com
NOW()
quando o registro for criado e deixa
como está em atualizações subsequentes.
Propriedades
TIMESTAMP
quando executando no modo
MAXDB
Quando o MySQL está executando no modo
MAXDB
, TIMESTAMP
é
idêntico ao DATETIME
. Ele usa o mesmo
formato para armazenar e mostrar valores, e ele tem a mesma
faixa. O MySQL pode ser executado no modo
MAXDB
a partir da versão 4.1.1. See
Secção 4.1.1, “Opções de Linha de Comando do mysqld
”.
Propriedades
TIMESTAMP
a partir do MySQL 4.1 quando não
executado no modo MAXDB
No MySQL 4.1.0, colunas TIMESTAMP
são
armazenadas e mostradas no mesmo formato que colunas
DATETIME
. Isto também significa que ele
não podem ser estreitados ou alargados nos modos descritos no
parágrafo seguinte. Em outras palavras, você não pode usar
TIMESTAMP(2)
,
TIMESTAMP(4)
, etc. Em outros casos, as
propriedades são as mesmas de versões MySQL anteriores.
Propriedades
TIMESTAMP
antes do MySQL 4.1
Valores TIMESTAMP
podem ter valores do
incio de 1970 até algum momento do ano 2037, com a
resolução de um segundo. Valores são mostrados como
números
O formato no qual o MySQL recupera e mostra valores
TIMESTAMP
depende do tamanho do display,
como ilustrado pela tabela que se segue: O formato `cheio'
TIMESTAMP
é de 14 digitos, mas colunas
TIMESTAMP
podem ser criadas com tamanho de
display menores:
Tipo da Coluna | Formato do Display |
TIMESTAMP(14) | YYYYMMDDHHMMSS |
TIMESTAMP(12) | YYMMDDHHMMSS |
TIMESTAMP(10) | YYMMDDHHMM |
TIMESTAMP(8) | YYYYMMDD |
TIMESTAMP(6) | YYMMDD |
TIMESTAMP(4) | YYMM |
TIMESTAMP(2) | YY |
Todas as colunas TIMESTAMP
tem o mesmo
tamanho de armazenamento, independente do tamanho de display.
Os tamanhos de display mais comuns são 6, 8, 12, e 14. Você
pode especificar um tamanho de display arbitrario na hora da
criação da tabela, mas valores de 0 ou maiores que 14 são
mudados para 14. Valores ímpares de tamanho na faixa de 1 a
13 são mudados para o maior número par mais próximo.
Nota: Na versão 4.1,
TIMESTAMP
é retornado com uma string com o
formato 'YYYY-MM-DD HH:MM:SS'
, e timestamp
de diferentes tamamnhos não são mais suportados.
Você pode especificar calores DATETIME
,
DATE
e TIMESTAMP
usando
qualquer conjunto de formatos comum:
Como uma string nos formatos 'YYYY-MM-DD
HH:MM:SS'
ou 'YY-MM-DD
HH:MM:SS'
. Uma sintaxe ``relaxada'' é
permitida---nenhum caracter de pontuação pode ser usado
como um delimitador entre parte de data ou hora. Por
exemplo, '98-12-31 11:30:45'
,
'98.12.31 11+30+45'
, '98/12/31
11*30*45'
, e '98@12@31
11^30^45'
são equivalentes.
Como uma string nos formatos
'YYYY-MM-DD'
ou
'YY-MM-DD'
. Uma sintaxe ``relaxada'' é
permitida aqui também. Por exemplo,
'98-12-31'
,
'98.12.31'
,
'98/12/31'
, e
'98@12@31'
são equivalentes.
Como uma string sem delimitadores nos formatos
'YYYYMMDDHHMMSS'
ou
'YYMMDDHHMMSS'
, desde que a string
faça sentido como data. Por example,
'19970523091528'
e
'970523091528'
são interpretadas com
'1997-05-23 09:15:28'
, mas
'971122129015'
é ilegal (tem uma parte
de minutos sem sentido) e se torna '0000-00-00
00:00:00'
.
Como uma string sem delimitadores nos formatos
'YYYYMMDD'
ou
'YYMMDD'
, desde que a string tenha
sentido com data. Por exemplo,
'19970523'
e
'970523'
são interpretedas como
'1997-05-23'
, mas
'971332'
é ilegal (tem uma parte de
mês sem sentido) e se torna
'0000-00-00'
.
Como um número nos formatos
YYYYMMDDHHMMSS
ou
YYMMDDHHMMSS
, desde que o número faça
sentido como uma data. Por exemplo,
19830905132800
e
830905132800
são interpretedos como
'1983-09-05 13:28:00'
.
Como um número nos formatos YYYYMMDD
ou YYMMDD
, desde que o número faça
sentido como data. Por exemplo,
19830905
e 830905
são interpretedos como '1983-09-05'
.
Como o resultado de uma função que retorne uma valor
aceitavel em um contexto DATETIME
,
DATE
ou TIMESTAMP
,
tal como NOW()
ou
CURRENT_DATE
.
Valores DATETIME
, DATE
,
ou TIMESTAMP
ilegais são convertidos para
o valor ``zero'' do tipo apropriado ('0000-00-00
00:00:00'
, '0000-00-00'
, ou
00000000000000
).
Para valores especificados com strings que incluem
delimitadores de data, não é necessário especificar dois
digitos para valores de mês ou dia qua são menores que
10
. '1979-6-9'
é o
mesmo que '1979-06-09'
. Similarmente, para
valores especificados como strings que incluem delimitadores
de hora, não é necessário especificar dois digitos para
valores de hora, minutos ou segundo que são menores que
10
. '1979-10-30 1:2:3'
Ré o mesmo que '1979-10-30 01:02:03'
.
Valores especificados como números devem ter 6, 8, 12, ou 14
digitos. Se o número é de 8 ou 14 digitos, ele assume estar
no formato YYYYMMDD
ou
YYYYMMDDHHMMSS
e que o ano é dado pelos 4
primeiros dígitos. Se o é de 6 ou 12 dígitos, ele assume
estar no formato YYMMDD
or
YYMMDDHHMMSS
e que o ano é dado pelos 2 primeiros
digitos. Números que não possua estes tamanho são
interpretados como calores preenchidos com zero até o tamanho
mais próximo.
Valores especificados como strings não delimitadas são
interpretados usando o seu tamanho como dado. Se a string
possui 8 ou 14 caracteres, o ano é assumido como os 4
primeiros caracteres. De outra forma o assume-se que o ano
são os 2 primeiros caracteres. A string é interpretadada
esquerda para direita para encontrar os valores do ano, mês,
dia, hora, minute e segundo, para as partes da string. Isto
significa que você não deve utilizar strings com menos de 6
caracteres. Por exemplo, se você especificar
'9903'
, pensando em representar Março de
1999, você perceberá que o MySQL insere uma data ``zero'' em
sua tabela. Isto ocorre porque os valores do ano e mês são
99
e 03
, mas a parte
contendo o dia não existe (zero), então o valor não é uma
data legal. No entanto, a partir do MySQL 3.23, você pode
especificar explicitamente um valor de zero para representar
dia ou mês faltantes. Por exemplo, você pode usar
'990300'
para inserir o valor
'1999-03-00'
.
Colunas TIMESTAMP
armazena valores legais
utilizando precisão total com a qual os valores foram
especificados, independente do tamanho do display. Isto tem
diversas implicações:
Sempre especifique o ano, mês e dia, mesmo se seus tipos
de coluna são TIMESTAMP(4)
ou
TIMESTAMP(2)
. De outra forma, os
valores não serão datas legais date e um
0
será armazenado.
Se você usa ALTER TABLE
para aumentar
uma coluna TIMESTAMP
, informações
serão mostradas como se antes estivessem ``escondidas''.
De forma similar, reduzindo o tamanho de uma coluna
TIMESTAMP
não causa perda de
informação, exceto no sentido de que menos informação
aparece quando os valores são mostrados.
Embora os valores TIMESTAMP
sejam
armazenados com precisão total, a única função que
opera diretamente com o valor armazenado é
UNIX_TIMESTAMP()
. OUtras funções
operam com o formato do valor recuperado Isto significa
que não se pode usar funções como
HOUR()
or SECOND()
a
menos que a parte relevante do valor
TIMESTAMP
esteja incluído no valor
formatado. POr exemplo, a parte HH
de
uma coluna TIMESTAMP
não é mostrada a
menos que o tamanho do display seja de pelo menos 10, logo
tentar usar HOUR()
em um valor
TIMESTAMP
menor produz um resultado sem
significado.
Você pode, algumas vezes, atribuir valores de um tipo de data para um objeto de um diferente tipo de data. No entanto pode haver algumas alterações de valores ou perda de informação
Se você atribuir um valor de DATE
value a um objeto DATETIME
ou
TIMESTAMP
, a parte da hora do valor
resultante é definido como '00:00:00'
,
porque o vlaor DATE
não contém
informações de hora.
Se você atribuir um valor DATETIME
ou
TIMESTAMP
para um objeto
DATE
, a parte da hora do valor
resultante é deletado, pois o tipo
DATE
não armazena informações de
hora.
Lembre-se de que embora todos os valores
DATETIME
, DATE
, e
TIMESTAMP
possam ser especificados
usando o mesmo conjunto de formatos, os tipos não tem a
mesa faixa de valores. Por exemplo, valores
TIMESTAMP
não podem ser anteriores a
1970
ou posteriores a
2037
. Isto significia que datas como
'1968-01-01'
, são permitidas como
valores DATETIME
ou
DATE
, mas não são válidas para
valores TIMESTAMP
e serão covertidas
para 0
se atribuidas para tais objetos.
Esteja ciente de certas dificuldades quando especificar valores de data:
A forma ``relaxada'' permitida em valores especificados
com strings podem causar certas confusões. Por exemplo,
um valor como '10:11:12'
pode parecer
com um valor de hora devido ao limitador
‘:
’, mas se usado em um
contexto de data será interpretado como o ano
'2010-11-12'
. O valor
'10:45:15'
será convertido para
'0000-00-00'
pois
'45'
não é um valor de mês
permitido.
O servidor MySQL funciona basicamente checando a validade
da data: dias entre 00-31
, mês entre
00-12
, anos entre
1000-9999
. Qualquer data que não
esteja nesta faixa será revetida para
0000-00-00
. Por favor, note que isto
ainda lhe permite armazenar datas invalidas tais como
2002-04-31
. Isto permite a aplicações
web armazenar dados de um formulário sem verificações
adicionais. Para assegurar que a data é valida, faça a
checagem em sua aplicação.
Valores de anos especificados com 2 digitos são ambíguos, pois o século não é conhecido. MySQL interpreta valores de anos com dois digitos usando as seguintes regras:
Valores de ano na faixa de 00-69
são convertidos para 2000-2069
.
Valores de ano na faixa de 70-99
são convertidos para 1970-1999
.
O MySQL recupera e mostra valores TIME
no
formato 'HH:MM:SS'
(ou no formato
'HHH:MM:SS'
para valores grandes). Volares
TIME
podem estar na faixa de
'-838:59:59'
até
'838:59:59'
. A razão para a parte da hora
ser tão grande é que o tipo TIME
pode ser
usado não apenas para representar a hora do dia (que deve ser
menor que 24 horas), mas também para tempo restante ou
intervalos de tempo entre dois eventos(que podem ser maior que
24 horas ou mesmo negativo).
Você pode especificar valores TIME
de
variadas formas:
Como uma string no formato 'D
HH:MM:SS.fração'
. (Note que o MySQL não
armazena ainda frações para a coluna time.) Pode-se
também utilizar uma das seguintes sintaxes ``relaxadas'':
HH:MM:SS.fração
,
HH:MM:SS
, HH:MM
,
D HH:MM:SS
, D HH:MM
,
D HH
ou SS
. Aqui
D
é um dia entre 0-33.
Como uma string sem delimitadores no formato
'HHMMSS'
, desde que ela tenha sentido
como uma hora. Por exemplo, '101112'
é
esntendido como '10:11:12'
, mas
'109712'
é ilegal (a parte dos minutos
não tem nenhum sentido) e se torna
'00:00:00'
.
Como um número no formato HHMMSS
,
desde que tenha sentido como uma hora. Por exemplo,
101112
é entendido com
'10:11:12'
. Os formatos alternativos
seguintes também são entendidos: SS
,
MMSS
, HHMMSS
e
HHMMSS.fração
. Note que o MySQL ainda
não armazena frações.
Como o resultado de uma função que retorne um valor que
é aceitável em um contexto do tipo
TIME
, tal como
CURRENT_TIME
.
Para valores TIME
especificados como uma
string que incluem delimitadores de hora, não é necessário
especificar dois dígitos para valores de hora, minutos ou
segundos que sejam menores que 10
.
'8:3:2'
é o mesmo que
'08:03:02'
.
Seja cuidadoso ao atribuir valores TIME
``pequenos'' para uma coluna TIME
. Sem dois
pontos, o MySQL interprete valores assumindo que os digitos
mais a direita representam segundos. (MySQL interpreta valores
TIME
como tempo decorrido ao invés de hora
do dia.) Por exemplo, você poderia pensar em
'1112'
e 1112
significam
'11:12:00'
(11 horas e 12 minutos), mas o
MySQL o intepreta como '00:11:12'
(onze
minutos e 12 segundos). De forma similar,
'12'
e 12
são
interpretados como '00:00:12'
. Valores
TIME
com dois pontos, em contrapartida,
são tratados como hora do dia. Isto é,
'11:12'
significará
'11:12:00'
, não
'00:11:12'
.
Valores que são legais mas que estão fora da faixa
permitidas são ajustados para o valor limita da faixa mais
apropriado. Por exemplo, '-850:00:00'
e
'850:00:00'
são convertidos para
'-838:59:59'
e
'838:59:59'
, respectivmente.
Valores TIME
ilegais são convertidos para
'00:00:00'
. Note que como
'00:00:00'
é um valor
TIME
, não temos com dizer, a partir de um
valor '00:00:00'
armazenado na tabela, se o
valor original armazenado foi especificado como
'00:00:00'
ou se foi ilegal.
O tipo YEAR
é um tipo de 1 byte usado para
representar anos.
O MySQL recupera e mostra valores YEAR
no
formato YYYY
. A faixa de valores é de
1901
até 2155
.
Você pode especificar valores YEAR
em uma
variedade de formatos:
Como uma string de 4 digitos na faixa de
'1901'
até '2155'
.
Como um número de 4 dígitos na faixa de
1901
até 2155
.
Como uma string de dis dígitos na faixa
'00'
até '99'
.
Valores na faixa de '00'
até
'69'
e '70'
até
'99'
são convetidas para valores
YEAR
na faixa de
2000
até 2069
e
1970
até 1999
.
Como um número de 2 digitos na faixa de
1
até 99
. Valores
na faixa de 1
até
69
e 70
até
99
são convertidos para valores
YEAR
na faixa de
2001
até 2069
e
1970
até 1999
. Note
que a faixa para números de dois dígitos é um pouco
diferente da faixa de strings de dois dígitos, pois não
se pode especificar zero diretamente como um número e
tê-lo interpretado com 2000
. Você
deve especificá-lo como
uma string '0'
ou
'00'
ou ele será interpretado com
0000
.
Como o resultado de uma função que retorna um valor que
é aceitável em um contexto do tipo
YEAR
, tal como
NOW()
.
Valores YEAR
ilegais são convertidos para
0000
.
Os tipos strings são CHAR
,
VARCHAR
, BLOB
,
TEXT
, ENUM
, e
SET
. Esta seção descreve como este tipos
funcionam, suas exigências de armazenamento e como usá-los em
suas consultas.
Tipo | Tam.maxímo | Bytes |
TINYTEXT ou TINYBLOB | 2^8-1 | 255 |
TEXT ou BLOB | 2^16-1 (64K-1) | 65535 |
MEDIUMTEXT ou MEDIUMBLOB | 2^24-1 (16M-1) | 16777215 |
LONGBLOB | 2^32-1 (4G-1) | 4294967295 |
Os tipos CHAR
e VARCHAR
são parecidos, mas diferem no modo como são armazenados e
recuperados.
O tamanho de um campo CHAR
é fixado pelo
tamanho declarado na criação da tabela. O tamanho pode ser
qualquer valor entre 1 e 255 (Como na versão 3.23 do MySQL, o
tamanho pode ser de 0 a 255). Quando valores
CHAR
são armazenados, eles são
preenchidos a direita com espaços até o tamanho
especificado. Quando valores CHAR
são
recuperados, espaços extras são removidos.
Valores no campo VARCHAR
são strings de
tamanho variável. Você pode declarar um campo
VARCHAR
para ter qualquer tamanho entre 1 e
255, assim como para campo CHAR
. No
entanto, diferente de CHAR
, valores
VARCHAR
são armazendos usando apenas
quantos caracteres forem necessários, mais 1 byte para gravar
o tamanho. Valores não são preenchidos; ao contrário,
espaços extras são removidos quando valores são
armazenados. (Esta remoção de espaços difere das
especificações do SQL-99). Nenhum caso de conversão é
feito durante um o armazenamento ou recuperação.
Se você atribuir um valor para uma coluna
CHAR
ou VARCHAR
que
exceda o tamanho máximo da coluna, o valor é truncado para
este tamanho.
A seguinte tabela ilustra as diferenças entre os dois tipos
de colunas, mostrando o resultado de se armazenar vários
valores de strings em campos CHAR(4)
e
VARCHAR(4)
:
Valor | CHAR(4) | Exigência p/ armazenamento | VARCHAR(4) | Exigência p/ armazenamento |
'' | ' ' | 4 bytes | '' | 1 byte |
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
'abcdefgh' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
Os valores recuperados para as colunas
CHAR(4)
e VARCHAR(4)
serão os mesmos em cada caso, já que espaços ectras são
removidos das colunas CHAR
quando
recuperados.
Valores nas colunas CHAR
e
VARCHAR
são ordenados e comparadaos no
modo caso-insensitivo, a menos que o atributo
BINARY
seja especificado quando a tabela
for criada. O atributo BINARY
significa que
os valores das colunas são ordenados e comparados no modo
caso-sensitivo de acordo com a ordem ASCII da maquina onde o
servidor MySQL está sesndo executado.
BINARY
não afeta como as colunas são
armazenadas e recuperadas.
A partir da versão 4.1.0, o tipo de coluna CHAR
BYTE
é um alias para CHAR
BINARY
. Thite é um recurso para compatibilidade.
O atributo BINARY
é pegajoso. Isto
significa que se uma coluna definida com
BINARY
é usada na expressão, toda a
expressão é comparada como um valor
BINARY
.
MySQL pode alterar sem aviso o tipo de uma coluna
CHAR
ou VARCHAR
na hora
de criar a tabela. See
Secção 6.5.3.1, “Alteração de Especificações de Colunas”.
Um BLOB
é um objeto binario grande que
pode guardar um montante variado de dados. Os quatro tipos
BLOB
: TINYBLOB
,
BLOB
, MEDIUMBLOB
, e
LONGBLOB
diferem apenas no tamanho maximo
dos valores que eles podem guradar. See
Secção 6.2.6, “Exigências de Armazenamento dos Tipos de Coluna”.
Os quatro tipos TEXT
:
TINYTEXT
, TEXT
,
MEDIUMTEXT
, e LONGTEXT
correspondem aos quatro tipos BLOB
e têm o
mesmo tamanho máximo e necessidade de tamanho para
armazenamento. A única diferença entre os tipos
BLOB
e TEXT
é que
ordenação e comparação são realizadas no modo
caso-sensitivo para valores BLOB
e no modo
caso-insensitivo para valores TEXT
. Em
outras palavras, um TEXT
é um
BLOB
no modo caso-insensitivo. Nenhum caso
de conversão é feito durante um o armazenamento ou
recuperação.
Se você atribuir um valor a uma coluna
BLOB
ou TEXT
que exceda
o tamanho máximo do tipo da coluna, o valor é truncado para
servir ao campo.
Em muitos casos, podemos considerar um campo
TEXT
como um campo
VARCHAR
que pode ser tão grande quando
desejamos. Da mesma forma podemos considerar um campo
BLOB
como um campo VARCHAR
BINARY
. As diferenças são:
A partir da versão 4.1.0, LONG
e
LONG VARCHAR
mapeiam para o tipo de dados
MEDIUMTEXT
. Este é um recurso de
compatibilidade.
MyODBC
define valores
BLOB
como LONGVARBINARY
e valores TEXT
como
LONGVARCHAR
.
Como valores BLOB
e TEXT
podem ser extremamentes longos, você pode deparar com alguns
problemas quando utilizá-los:
Se você quiser utilizar GROUP BY
ou
ORDER BY
em um campo
BLOB
ou TEXT
, você
deve converte-los em objetos de tamanho fixo. O modo
padrão de se fazer isto é com a função
SUBSTRING
. Por exemplo:
mysql>SELECT comentario FROM nome_tabela,SUBSTRING(comentario,20) AS substr
->ORDER BY substr;
Se você não fizer isto, só os primeiros
max_sort_length
bytes de uma coluna
serão utilizados na ordenação. O valor padrão de
max_sort_length
é 1024; este calor
pode ser alterado utilizando-se a opção
-O
quando o servidor é inicializado.
Você pode agrupar uma expressão envolvendo valores
BLOB
ou TEXT
especificando a posição da coluna ou utilizando apelidos
(alias):
mysql>SELECT id,SUBSTRING(col_blob,1,100) FROM nome_tabela GROUP BY 2;
mysql>SELECT id,SUBSTRING(col_blob,1,100) AS b FROM nome_tabela GROUP BY b;
O tamanho máximo de uma objeto BLOB
ou
TEXT
é determinado pelo seu tipo, mas o
maior valor que você pode, atualmente, transmitir entre o
cliente e o servidor é determinado pela quantidade de
memória disponível e o tamanho dos buffers de
comunicação. Você pode mudar o tamanho do buffer de
mensagem (max_allowed_packet
), mas
você deve faze-lo no servidor e no cliente. See
Secção 5.5.2, “Parâmetros de Sintonia do Servidor”.
Note que cada valor BLOB
ou
TEXT
é representado internamente por um
objeto alocado searadamente. Está é uma diferença com todos
os outros tipos de colunas, para o qual o armazenamento é
alocado um por coluna quando a tabela é aberta.
Um ENUM
é um objeto string cujo valor
normalmente é escolhido de uma lista de valores permitidos
que são enumerados explicitamente na especificação da
coluna na criação da tabela.
O valor pode ser a string vazia (""
) ou
NULL
sob certas circunstâncias:
Se você inserir um valor inválido em um
ENUM
(isto é, uma string que não
está presente na lista de valores permitidos), a string
vazia é inserida no lugar como um valor especial de erro.
Esta string pode se diferenciar de um string vazia 'norma'
pelo fato de que esta string tem uo valor numérico 0.
Veremos mais sobre este assunto mais tarde.
Se um ENUM
é declarado
NULL
, NULL
é
também um valor permitido para a coluna, e o valor padrao
é NULL
. Se um ENUM
é decalarado NOT NULL
, o valor padrão
é o primeiro elemento da lista de valores permitidos.
Cada enumeração tem um índice:
Valores da lista de elementos permitidos na especificação da coluna são números começados com 1.
O valor de índice de uma string vazia que indique erro é
0. Isto significa que você pode usar a seguinte
instrução SELECT
para encontrar
linhas nas quais valores ENUM
inválidos forma atribuidos:
mysql> SELECT * FROM nome_tabela WHERE col_enum=0;
O índice de um valor NULL
é
NULL
.
Por exemplo, uma coluna especificada como ENUM("um",
"dois", "três")
pode ter quqlquer um dos valores
mostrados aqui. O índice de cada valor também é mostrado:
Valor | Indice |
NULL | NULL |
"" | 0 |
"um" | 1 |
"dois" | 2 |
"três" | 3 |
Uma enumeração pode ter um máximo de 65535 elementos.
A partir da versão 3.23.51 espaços extras são
automaticamente deletados dos valores ENUM
quando a tabela é criada.
O caso da letra é irrelevante quando você atribui valores a
um coluna ENUM
. No entanto, valores
recuperados posteriormente da coluna terá o caso de letras de
acordo com os valores que foram usados para especificar os
valores permitidos na criação da tabela.
Se você recupera um ENUM
em um contexto
numérico, o indice do valor da coluna é retornado. Por
exemplo, você pode recuperar valores numéricos de uma coluna
ENUM
desta forma:
mysql> SELECT col_enum+0 FROM nome_tabela;
Se você armazena um número em um ENUM
, o
número é tratado como um índice, e o valor armazenado é o
membro da enumeração com este índice. (No entanto, este
não irá funcionar com LOAD DATA
, o qual
trata todas as entradas como strings.) Não é aconselhável
armazenar números em uma string ENUM
pois
pode tornar as coisas um pouco confusas.
Valores ENUM
são armazenados de acordo com
a ordem na qual os membros da enumeração foram listados na
especificação da coluna. (Em outras palavras, valores
ENUM
são ordenados de acordo com o seus
números de índice.) Por exemplo, "a"
vem
antes de "b"
para ENUM("a",
"b")
, mas "b"
vem antes de
"a"
para ENUM("b", "a")
.
A string vazia vem antes de strings não-vazias, e valores
NULL
vem antes de todos os outros valores
de enumeração. Para evitar resultados inesperados,
especifique a lista ENUM
em ordem
alfabética. Você também pode usar GROUP BY
CONCAT(col)
para ter certeza de que as colunas
estão ordenadas alfabeticamente e não pelo índice
numérico.
Se você quiser obter todos os valores possíveis para uma
coluna ENUM
, você deve usar: SHOW
COLUMNS FROM nome_tabela LIKE nome_coluna_enum
e
analizar a definição de ENUM
na segunda
coluna.
Um SET
é um objeto string que pode ter
zero ou mais valores, cada um deve ser escolhido de uma lista
de valores permitidos especificados quando a tabela é criada.
Valores de colunas SET
que consistem de
múltiplos membros são espeficados separados por virgula
(‘,
’). Uma consquência distop
é que valores dos membros de SET
não
podem, eles mesmos, conter vírgula.
Por exemplo, uma coluna especificada como SET("um",
"dois") NOT NULL
pode ter qualquer um destes
valores:
"" "um" "dois" "um, dois"
Um SET
pode ter no máximo 64 membros
diferentes.
A partir da versão 3.23.51, espaços extras são
automaticamente removidos dos valores de
SET
quando a tabela é criada.
MySQL armazena valores SET
numericamente,
com o bit de baixa-ordem do valor armazenado correspondendo ao
primeiro membro do conjunto. Se você recupera um valor
SET
em um contexto numérico, o valor
recuperado tem o conjunto de bits correspondente aos membros
que aparecem no valor da coluna. Por exemplo, você pode
recuperar valores numéricos de uma coluna
SET
assim:
mysql> SELECT col_set+0 FROM nome_tabela;
Se um número é armazenado em uma coluna
SET
, os bits que estão habilitados (com 1)
na representação binária do número determinam o qual o
membro no valor da coluna. Suponha uma coluna especificada
como SET("a","b","c","d")
. Então os
membros terão os seguintes valores binários:
SET membro | Valor decimal | Valor binário |
a | 1 | 0001 |
b | 2 | 0010 |
c | 4 | 0100 |
d | 8 | 1000 |
Se você atribuir um valor 9
a esta coluna,
que é 1001
em binário, o primeiro e o
quarto valores membros do SET
"a"
e "d"
são
selecionados e o valor resultante é "a,d"
.
Para um valor contendo mais que um elemento de
SET
, não importa em qual ordem os
elementos são listados quando foram inseridos seus valores.
Também não importa quantas vezes um dado elemento e listado
no valor. Quando o valor é recuperado posteriormente, cada
elemento aparecerá uma vez, listados de acordo com a ordem em
que eles foram especificados na crição da tabela. Por
exemplo, se uma coluna é especificada como
SET("a","b","c","d")
, então
"a,d"
, "d,a"
e
"d,a,a,d,d"
irão todos aparecer como
"a,d"
quando recuperados.
Se você define um valor que não é suportado pela coluna
SET
, o valor será ignorado.
Valores SET
são ordenados numéricamente.
Valores NULL
vêm antes de valores
SET
não NULL
.
Normalmente, você realiza um SELECT
em uma
coluna SET
usando o operador
LIKE
ou a função
FIND_IN_SET()
:
mysql>SELECT * FROM nome_tabela WHERE col_set LIKE '%valor%';
mysql>SELECT * FROM nome_tabela WHERE FIND_IN_SET('valor',col_set)>0;
Mas o seguinte também funciona:
mysql>SELECT * FROM nome_tabela 2 WHERE col_set = 'val1,val2';
mysql>SELECT * FROM nome_tabela 3 WHERE col_set & 1;
A primeira desta instruções procura por uma correpondencia exata. A segunda por valores contendo o primeiro membro.
Se você quer obter todos os valores possíveis para uma
coluna SET
, você deve usar: SHOW
COLUMNS FROM nome_tabela LIKE nome_coluna_set
e
analizar a definição do SET
na segunda
coluna.
Para um uso mais eficiente do armzenamento, tente usar o tipo
mais adequado em todos os casos. Por exemplo, se um campo de
inteiro for usado para valores em uma faixa entre
1
e 99999
,
MEDIUMINT UNSIGNED
é o melhor tipo.
Represtação precisa de valores monetários é um priblema
comum. No MySQL você deve usar o tipo
DECIMAL
. Ele armazena uma string, então
nenhuma perda de precisão deve ocorrer. Se a precisão não é
tão importante, o tipo DOUBLE
pode ser
satisfatório.
Para uma alta precisão você sempre pode converter para um tipo
de ponto fixo armazenado em um BIGINT
. Isto
perite fazer todos os cálculos com inteiros e converter o
resultado para um ponto flutuante somente quando necessário.
Para facilitar o uso de code para implementações SQL de outras empresas, MySQL mapeia os tipos de campos como mostrado na tabela seguinte. Este mapeamento torna fácil mudar definições de tabelas de outros mecanismos de banco de dados para o MySQL:
Tipo de outras empresas | Tipo MySQL |
BINARY(NUM) | CHAR(NUM) BINARY |
CHAR VARYING(NUM) | VARCHAR(NUM) |
FLOAT4 | FLOAT |
FLOAT8 | DOUBLE |
INT1 | TINYINT |
INT2 | SMALLINT |
INT3 | MEDIUMINT |
INT4 | INT |
INT8 | BIGINT |
LONG VARBINARY | MEDIUMBLOB |
LONG VARCHAR | MEDIUMTEXT |
MIDDLEINT | MEDIUMINT |
VARBINARY(NUM) | VARCHAR(NUM) BINARY |
O mapeamento do tipo de campo ocorre na criação da tabela. Se
você cria uma tabela com tipos usador por outras empresas e
então executa uma instrução DESCRIBE
nome_tabela
, MySQL relaciona a estrutura de tabela
utilizando os tipos equivalentes do MySQL.
As exigências de armazenamento para cada um dos tipos de colunas suportados pelo MySQL estão listados por categoria.
Exigências de armazenamento para tipos numéricos
Tipo da coluna | Tamanho exigido |
TINYINT | 1 byte |
SMALLINT | 2 bytes |
MEDIUMINT | 3 bytes |
INT | 4 bytes |
INTEGER | 4 bytes |
BIGINT | 8 bytes |
FLOAT(X) | 4 se X <= 24 ou 8 se 25 <= X <= 53 |
FLOAT | 4 bytes |
DOUBLE | 8 bytes |
DOUBLE PRECISION | 8 bytes |
REAL | 8 bytes |
DECIMAL(M,D) | M+2 bytes se D > 0, M+1 bytes
se D = 0 (D +2, se M <
D ) |
NUMERIC(M,D) | M+2 bytes se D > 0, M+1 bytes
se D = 0 (D +2, se M <
D ) |
Exigência de armazenamento para tipos data e hora
Tipo de coluna | Tamanho exigido |
DATE | 3 bytes |
DATETIME | 8 bytes |
TIMESTAMP | 4 bytes |
TIME | 3 bytes |
YEAR | 1 byte |
Exigência de armazenamento para tipos string
Tipo de coluna | Tamanho exigido |
CHAR(M) | M bytes, 1 <= M <= 255 |
VARCHAR(M) | L +1 bytes, onde L <= M e
1 <= M <= 255 |
TINYBLOB , TINYTEXT | L +1 bytes, onde L < 2^8 |
BLOB , TEXT | L +2 bytes, onde L < 2^16 |
MEDIUMBLOB , MEDIUMTEXT | L +3 bytes, onde L < 2^24 |
LONGBLOB , LONGTEXT | L +4 bytes, onde L < 2^32 |
ENUM('valor1','valor2',...) | 1 ou 2 bytes, dependendo do número de valores enumerados (65535 valores no máximo) |
SET('valor1','valor2',...) | 1, 2, 3, 4 or 8 bytes, dependendo do número de membros do conjunto (64 membros no máximo) |
Tipos VARCHAR
, BLOB
e
TEXT
são de tamanho variáveis, tendo o
tamanho exigido para armazenamento dependendo do tamanho atual
dos valores da coluna (representado por L
na
tabela anterior), e não do tamanho máximo do tipo. Por
exemplo, uma coluna VARCHAR(10)
pode guardar
uma string com um tamanho máximo de 10 caracteres. O tamanho
exigido para armazenamento atual é o tamanho da string
(L
), mais 1 byte para para gravar o tamanho
da string. Por exemplo, para a string 'abcd'
,
L
é 4 e o tamanho exigido para armazenamento
é 5 bytes.
Os tipos BLOB
e TEXT
exigem 1, 2, 3 ou 4 bytes para gravar o tamanho do valor da
coluna, dependendo do tamanho máximo possível do tipo. See
Secção 6.2.3.2, “Os Tipos BLOB
e TEXT
”.
Se uma tabela inclui qualquer tipo de coluna de tamanho variável, o formato do registro também será de tamanho variável. Note que quando uma tabela é criada, MySQL pode, sob certas condições, mudar uma coluna de um tipo de tamanho variável para um tipo de tamanho fixo, ou vice-versa. See Secção 6.5.3.1, “Alteração de Especificações de Colunas”.
O tamanho de um objeto ENUM
é determinado
por um número de diferntes valores enumerados. Um byte é usado
para enumerações até 255 valores possíveis. Dois bytes são
usados para enumerações até 65535 valores. See
Secção 6.2.3.3, “O Tipo ENUM
”.
O tamanho de uma objeto é determinado pelo número de
diferentes membros do conjunto. Se o tamanho do conjunto é
N
, o objeto ocupa (N+7)/8
bytes, arredondados acima para 1, 2, 3, 4, ou 8 bytes. Um
SET
pode ter no máximo 64 membros. See
Secção 6.2.3.4, “O Tipo SET
”.
O tamanho máximo de um registro em uma tabela
MyISAM
é 65534 bytes. Cada coluna
BLOB
e TEXT
ocupa apenas
5-9 bytes deste tamanho.
Um select_expression
ou
where_definition
em uma instrução SQL pode
consistir de qualquer expressão utilizando as funções descritas
abaixo.
Uma expressão que contém NULL
sempre produz
um valor NULL
a menos que esteja indicado na
dodumentação para os operandos e funções envolvidos na
expressão.
Nota: Não deve haver nenhum espaço em branco entre um nome de função e os parentesis que a seguem. Isto ajuda o analizador MySQL a distinguir entre chamadas de funções e referências a tabelas ou colunas que possuem o mesmo nome de uma função. Espaços entre argumentos são permitidos.
Você pode forçar o MySQL a aceitar espaços depois do nome de
funções iniciando o mysqld
com a opção
--ansi
ou usando o
CLIENT_IGNORE_SPACE
no
mysql_connect()
, mas neste caso nome de
funções se tornarão palavras reservadas. See
Secção 1.8.2, “Executando o MySQL no modo ANSI”.
Para sermos breve, exemplos mostram a saida do programa
mysql
na forma abreviada. Então isto:
mysql> SELECT MOD(29,9);
1 rows in set (0.00 sec)
+-----------+
| mod(29,9) |
+-----------+
| 2 |
+-----------+
é mostrado desta forma:
mysql> SELECT MOD(29,9);
-> 2
( ... )
Use parenteses para forçar a ordem em que as expressões serão avaliadas. Por exemplo:
mysql>SELECT 1+2*3;
-> 7 mysql>SELECT (1+2)*3;
-> 9
Operações de comparação resultam em um valor
1
(VERDADEIRO), 0
(FALSO), ou NULL
. Estas funções funcionam
tanto para tipos numéricos quanto para tipos strings. Strings
são convertidas automaticamente para números e números para
strings quando necessário (como em Perl).
MySQL realiza comparações de acordo com as seguintes regras:
Se um ou ambos os argumentos são NULL
,
o resultado da comparação é NULL
,
exceto para o operador <=>
.
Se ambos os argumentos em uma comparação são strings, eles são comparados como strings.
Se ambos os argumentos são inteiros, eles são comparados como inteiros.
Valores hexadecimais são tratados como strings binárias se não comparadas a um número.
Se uma dos argumentos é uma coluna
TIMESTAMP
ou
DATETIME
e o outro argumento é uma
constante, a constante é convertida para um timestamp
antes da comparação ser realizada. Isto ocorre para ser
mais amigável ao ODBC.
Em todos os outros casos, os argumentos são coparados como números de ponto flutuante (real).
Por padrão, comparações de string são feita de modo independente do caso, usando o conjunto de caracteres atual (ISO-8859-1 Latin1 por padrão, o qual também funciona de forma excelente para o Inglês).
Se você está comparando strings em caso insensitivo com
qualquer dos operadores padrões (=
,
<>
..., mas não o
LIKE
) espaços em branco no fim da string
(espaços, tabs e quebra de linha) serão ignorados.
mysql> SELECT "a" ="A \n";
-> 1
Os seguintes exemplos ilustram a conversão de strings para números para operações de comparação:
mysql>SELECT 1 > '6x';
-> 0 mysql>SELECT 7 > '6x';
-> 1 mysql>SELECT 0 > 'x6';
-> 0 mysql>SELECT 0 = 'x6';
-> 1
Note que quando você está comparando uma coluna string com um número, o MySQL não pode usar índices para encontrar o valor rapidamente:
SELECT * FROM table_name WHERE string_key=1
A razão para isto é que existem muitas strings diferentes
que podem retornar o valor 1
:
"1"
, " 1"
,
"1a"
...
=
Igual:
mysql>SELECT 1 = 0;
-> 0 mysql>SELECT '0' = 0;
-> 1 mysql>SELECT '0.0' = 0;
-> 1 mysql>SELECT '0.01' = 0;
-> 0 mysql>SELECT '.01' = 0.01;
-> 1
<>
, !=
Diferente:
mysql>SELECT '.01' <> '0.01';
-> 1 mysql>SELECT .01 <> '0.01';
-> 0 mysql>SELECT 'zapp' <> 'zappp';
-> 1
<=
Menor que ou igual:
mysql> SELECT 0.1 <= 2;
-> 1
<
Menor que:
mysql> SELECT 2 < 2;
-> 0
>=
Maior que ou igual:
mysql> SELECT 2 >= 2;
-> 1
>
Maior que:
mysql> SELECT 2 > 2;
-> 0
<=>
Igual para NULL
:
mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
-> 1 1 0
IS NULL
, IS NOT
NULL
Teste para saber se um valor é ou não
NULL
:
mysql>SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
-> 0 0 1 mysql>SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
-> 1 1 0
Para estar apto a funcionar bem com outros programas,
MySQL suporta os seguintes recursos extras quando
utiliza-se IS NULL
:
Você pode encontrar o último registro inserido com:
SELECT * FROM nome_tabela WHERE auto_col IS NULL
Isto pode ser desabilitado configurando
SQL_AUTO_IS_NULL=0
. See
Secção 5.5.6, “Sintaxe de SET
”.
Para colunas DATE
e
DATETIME
NOT
NULL
você pode encontrar a data especial
0000-00-00
utilizando:
SELECT * FROM nome_tabela WHERE coluna_data IS NULL
Isto é necessário para que algums aplicações
ODBC funcionem (já que ODBC não tem suporte a data
0000-00-00
)
expr BETWEEN min AND max
Se expr
é maior que ou igual a
min
e expr
é menor
que ou igual a max
,
BETWEEN
retorna 1
,
senão é retornado 0
. Isto é
equivalente a expressão (min <= expr AND expr
<= max)
se todos os argumentos são do mesmo
tipo. Senão os tipos são convertidos, conforme as regras
acima, e aplicadas a todos os três argumentos.
Note que antes da versão
4.0.5 argumentos eram convertidos para o tipo da
expr
.
mysql>SELECT 1 BETWEEN 2 AND 3;
-> 0 mysql>SELECT 'b' BETWEEN 'a' AND 'c';
-> 1 mysql>SELECT 2 BETWEEN 2 AND '3';
-> 1 mysql>SELECT 2 BETWEEN 2 AND 'x-3';
-> 0
expr NOT BETWEEN min AND max
O mesmo que NOT (expr BETWEEN min AND
max)
.
expr IN (valor,...)
Retorna 1
se expr
é
qualquer dos valores na lista IN
,
senão retorna 0
. Se todos os valores
são constantes, então os valores são avaliados de
acordo com o tipo da expr
e ordenado. A
busca do item é então feita usando pesquisa binária.
Isto significa que IN
é muito rápido
se os valores da lista IN
forem todos
contantes. Se expr
é uma expressão
strig em caso-sensitivo, a comparação é realizadas no
modo caso-sensitvo:
mysql>SELECT 2 IN (0,3,5,'wefwf');
-> 0 mysql>SELECT 'wefwf' IN (0,3,5,'wefwf');
-> 1
O número de valores na lista IN
é
limitada apenas pelo valor
max_allowed_packet
.
Na versão 4.1 (para se adequar ao padrão SQL-99),
IN
returna NULL
não
apeans se a expressão a sua esquerda é
NULL
, mas também se nenhuma
correspondência é encontrada na lista e uma de suas
expressões é NULL
.
A partir do MySQL versão 4.1, uma cláusula IN() também
pode conter uma subquery. See
Secção 6.4.2.3, “Subqueries with ANY
, IN
, and SOME
”.
expr NOT IN (valor,...)
O mesmo que NOT (expr IN (valor,...))
.
ISNULL(expr)
Se expr
é NULL
,
ISNULL()
retorna 1
,
senão retorna 0
:
mysql>SELECT ISNULL(1+1);
-> 0 mysql>SELECT ISNULL(1/0);
-> 1
Note que a compração de valores NULL
usando =
sempre será falso!
COALESCE(lista)
Retorna o primeiro elemento não NULL
na lista:
mysql>SELECT COALESCE(NULL,1);
-> 1 mysql>SELECT COALESCE(NULL,NULL,NULL);
-> NULL
INTERVAL(N,N1,N2,N3,...)
Retorna 0
se N
<
N1
, 1
se
N
< N2
e assim
por diante ou -1
se
N
é NULL
. Todos os
argumentos são tratados como inteiros. Isto exige que
N1
< N2
<
N3
< ...
<
Nn
para que esta função funcione
corretamente. Isto ocorre devido a utilização pesquisa
binária (muito rápida):
mysql>SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
-> 3 mysql>SELECT INTERVAL(10, 1, 10, 100, 1000);
-> 2 mysql>SELECT INTERVAL(22, 23, 30, 44, 200);
-> 0
Em SQL, todos os operadores logicos avaliam TRUE (VERDADEIRO),
FALSE (FALSO) ou NULL (DESCONHECIDO). No MySQL, esta
implementação é como 1
(TRUE),
0
(FALSE), e NULL
. A
maioria deles é comum entre diferentes bancos de dados SQL.
no entanto alguns podem retonar qualquer valor diferente de
zero para TRUE.
NOT
, !
NOT logico. Avalia como 1
se o operador
é 0
, como 0
se o
operador é diferente de zero, e NOT
NULL
retorna NULL
.
mysql>SELECT NOT 10;
-> 0 mysql>SELECT NOT 0;
-> 1 mysql>SELECT NOT NULL;
-> NULL mysql>SELECT ! (1+1);
-> 0 mysql>SELECT ! 1+1;
-> 1
O último exemplo produz 1
pois a a
expressão é avaliada como (!1)+1
.
AND
, &&
AND lógico. Avalia como 1
se todos os
operandos são diferentes de zero e não é
NULL
, como 0
se um
ou mais operandos são 0
, senão
retorna NULL
.
mysql>SELECT 1 && 1;
-> 1 mysql>SELECT 1 && 0;
-> 0 mysql>SELECT 1 && NULL;
-> NULL mysql>SELECT 0 && NULL;
-> 0 mysql>SELECT NULL && 0;
-> 0
Por favor note que as versões do MySQL anteriores a
versão 4.0.5 param a avaliação quando um valor
NULL
é encontrado, e não continua o
processo buscando por possíveis 0
s.
Isto significa que nessa versão, SELECT (NULL
AND 0)
retorna NULL
ao invés
de 0
. Na versão 4.0.5 o código tem
sido re-elaborado para que o resultado sempre seja como
prescrito pelo padrão SQL utilizando a otimização
sempre que possível.
OR
, ||
OR lógico. Avalia como 1
se algum
operando é diferente de zero e como
NULL
se algum operando for
NULL
, senão 0
é
retornado.
mysql>SELECT 1 || 1;
-> 1 mysql>SELECT 1 || 0;
-> 1 mysql>SELECT 0 || 0;
-> 0 mysql>SELECT 0 || NULL;
-> NULL mysql>SELECT 1 || NULL;
-> 1
XOR
XOR lógico. Retorna NULL
se o operando
também é NULL
. Para operandos não
NULL
, avalia como 1
se um número ímpar de operandos é diferente de zero,
senão 0
é retornado.
mysql>SELECT 1 XOR 1;
-> 0 mysql>SELECT 1 XOR 0;
-> 1 mysql>SELECT 1 XOR NULL;
-> NULL mysql>SELECT 1 XOR 1 XOR 1;
-> 1
a XOR b
é matematicamente igual a
(a AND (NOT b)) OR ((NOT a) and b)
.
XOR
foi adicionado na versão 4.0.2.
CASE valor WHEN [valor comparado] THEN resultado
[WHEN [valor comparado] THEN resultado ...] [ELSE
resultado] END
, CASE WHEN [condição]
THEN result [WHEN [condição] THEN resultado ...] [ELSE
resultado] END
A primeira expressão retorna o
resultado
onde valor=valor
comparado
. A segunda expressão retorna o o
resultado da primeira condição, a qual é verdadeira. Se
não existe nenhum resultado correspondente, então o
resultado depois do ELSE
é retornado.
Se não existe parte ELSE
então é
retornado NULL
is returned:
mysql>SELECT CASE 1 WHEN 1 THEN "um"
WHEN 2 THEN "dois" ELSE "mais" END; -> "one" mysql>SELECT CASE WHEN 1>0 THEN "verdadeiro" ELSE "falso" END;
-> "true" mysql>SELECT CASE BINARY "B" WHEN "a" THEN 1 WHEN "b" THEN 2 END;
-> NULL
O tipo do valor de retorno (INTEGER
,
DOUBLE
ou STRING
) é
do mesmo tipo do primeiro valor retornado (a expressão
depois do primeiro THEN
).
IF(expr1,expr2,expr3)
Se expr1
é VERDADEIRA (expr1
<> 0
e expr1 <>
NULL
) então IF()
retorna
expr2
, senão ela retorna
expr3
. IF()
returna
um valor numérico ou string, dependendo do contexto no
qual é usado.
mysql>SELECT IF(1>2,2,3);
-> 3 mysql>SELECT IF(1<2,'sim','não');
-> 'sim' mysql>SELECT IF(STRCMP('teste','teste1'),'não','sim');
-> 'não'
Se expr2
ou expr3
é
explicitamente NULL
então o tipo
resultante da função IF()
é o tipo
da coluna não NULL
. (Este
comportamento é novo na versão 4.0.3 do MySQL).
expr1
é avaliada como um valor
inteiro, o qual significa que se você está testando
valores de ponto flutuante ou strings, você de fazê-lo
usando um operando de comparação:
mysql>SELECT IF(0.1,1,0);
-> 0 mysql>SELECT IF(0.1<>0,1,0);
-> 1
No primeiro caso acima, IF(0.1)
retorna
0
porque 0.1
é
convertido para um valor inteiro, resultando um um teste
IF(0)
. Isto pode não ser o que você
esperava. No segundo caso, a comparação testa se o valor
de ponto flutuante não é zero. O resultado da
comparação converte o termo em um interiro.
O tipo de retorno padrão de IF()
(o
que pode importar quando ele é armazenado em uma tabela
temporária) é calculado na versão 3.23 do MySQL de
seguinte forma:
Expressão | Valor de retorno |
expr2 ou expr3 retorna string | string |
expr2 ou expr3 retorna um valor de ponto flutuante | ponto flutuante |
expr2 ou expr3 retorna um inteiro | inteiro |
Se expr2 e expr3 são strings, então o resultado é caso-insensitivo se ambas strings são caso insensitivo. (A patir da versão 3.23.51)
IFNULL(expr1,expr2)
Se expr1
não é
NULL
, IFNULL()
retorna expr1
, senão retorna
expr2
. IFNULL()
retorna um valor numérico ou string, dependendo do
contexto no qual é usado:
mysql>SELECT IFNULL(1,0);
-> 1 mysql>SELECT IFNULL(NULL,10);
-> 10 mysql>SELECT IFNULL(1/0,10);
-> 10 mysql>SELECT IFNULL(1/0,'yes');
-> 'yes'
Na versão 4.0.6 e acima o valor resultante padrão de
IFNULL(expr1,expr2)
é o mais geral das
duas expressões, na seguinte ordem:
STRING
, REAL
ou
INTEGER
. A diferença das versões
anteriores é mais notável quando se cria uma tabela
baseada em uma expressão ou o MySQL tem que armazenar
internamente um valor de IFNULL()
em
uma tabela temporária.
CREATE TABLE foo SELECT IFNULL(1,"teste") as teste;
Na versão 4.0.6 do MySQL o tipo da coluna 'teste' é
CHAR(4)
enquanto nas versões
anteriores ela seria do tipo BIGINT
.
NULLIF(expr1,expr2)
Se expr1 = expr2
for verdadeiro, é
retornado NULL
senão é retornado
expr1
. Isto é o mesmo que
CASE WHEN x = y THEN NULL ELSE x END
:
mysql>SELECT NULLIF(1,1);
-> NULL mysql>SELECT NULLIF(1,2);
-> 1
Note que expr1
é avaliada duas vezes
no MySQL se os argumentos não são iguais.
Funções string retornam NULL
se o tamanho
do resultado for maior que o parâmetro do servidor
max_allowed_packet
. See
Secção 5.5.2, “Parâmetros de Sintonia do Servidor”.
Para funções que operam com as posições de uma string, a primeira posição é numerada como 1.
ASCII(str)
Retorna o valor do código ASCII do caracter mais a esquerda
da string str
. Retorna
0
se str
é uma string
vazia. Retorna NULL
se
str
é NULL
:
mysql>SELECT ASCII('2');
-> 50 mysql>SELECT ASCII(2);
-> 50 mysql>SELECT ASCII('dx');
-> 100
Veja também a função ORD()
.
BIN(N)
Retorna um representação string do valor binário de
N
, onde N
é um
número muito grande (BIGINT
). Isto é
equivalente a CONV(N,10,2)
. Retorna
NULL
se N
é
NULL
:
mysql> SELECT BIN(12);
-> '1100'
BIT_LENGTH(str)
Retorna o tamanho da string str
em bits:
mysql> SELECT BIT_LENGTH('text');
-> 32
CHAR(N,...)
CHAR()
interpretia os argumentos como
inteiros e retorna uma string com caracteres dados pelo
valor do código ASCII referentes a estes inteiros. Valores
NULL
são desconsiderados:
mysql>SELECT CHAR(77,121,83,81,'76');
-> 'MySQL' mysql>SELECT CHAR(77,77.3,'77.3');
-> 'MMM'
CONCAT(str1,str2,...)
Retorna a string resultante da concatenação dos
argumentos. Retorna NULL
se qualquer dos
argumentos for NULL
. Pode ter mais de 2
argumentos. Um argumento numérico é convertido para sua
forma string equivalente:
mysql>SELECT CONCAT('My', 'S', 'QL');
-> 'MySQL' mysql>SELECT CONCAT('My', NULL, 'QL');
-> NULL mysql>SELECT CONCAT(14.3);
-> '14.3'
CONCAT_WS(separador, str1, str2,...)
CONCAT_WS()
significa CONCAT With
Separator (CONCAT com separador) e é uma forma especial do
CONCAT()
. O primeiro argumento é o
separador para os outros argumentos. O separador é
adicionado entre as strings a serem concatenadas: O
separador pode ser uma string assim como os outros
argumentos. Se o separador é NULL
, o
resultado será NULL
. A função irá
desconsiderar qualquer NULL
depois do
argumento do separador.
mysql>SELECT CONCAT_WS(",","First name","Second name","Last Name");
-> 'First name,Second name,Last Name' mysql>SELECT CONCAT_WS(",","First name",NULL,"Last Name");
-> 'First name,Last Name'
Antes do MySQL 4.1.1, CONCAT_WS()
desconsiderava strings vazias assim como valores
NULL
.
CONV(N,da_base,para_base)
Converte números entre diferentes bases. Retorna uma
representação string do número N
,
convertido da base da_base
para base
para_base
. Retorna
NULL
se qualquer argumento é
NULL
. O argumento N
é
interpretado como um inteiro, mas pode ser especificado como
um inteiro ou uma string. A base mínima é
2
e a máxima é 36
.
Se para_base
é um número negativo,
N
é considerado como um número com
sinal. Caso contrário, N
é tratado como
um número sem sinal. CONV
funciona com
precisão de 64-bit:
mysql>SELECT CONV("a",16,2);
-> '1010' mysql>SELECT CONV("6E",18,8);
-> '172' mysql>SELECT CONV(-17,10,-18);
-> '-H' mysql>SELECT CONV(10+"10"+'10'+0xa,10,10);
-> '40'
ELT(N,str1,str2,str3,...)
Retorna str1
se N
=
1
, str2
se
N
= 2
, e assim por
diante. Retorna NULL
se
N
é menor que 1
ou
maior que o número de argumentos. ELT()
é o complemento de FIELD()
:
mysql>SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');
-> 'ej' mysql>SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');
-> 'foo'
EXPORT_SET(bits,on,off,[separador,[numero_de_bits]])
Retorna uma string onde para todo bit 1 em 'bit', você obtém uma string 'on' e para cada bit 0 você obtem uma string 'off', Cada string é separada com 'separador' (padrão,',') e só 'número_de_bits' (padrão 64) de 'bits' é usado:
mysql> SELECT EXPORT_SET(5,'S','N',',',4)
-> S,N,S,N
FIELD(str,str1,str2,str3,...)
Retorna o índice de str
na lista
str1
, str2
,
str3
, ...
. Retorns
0
se str
não for
encontrada. FIELD()
é o complemento de
ELT()
:
mysql>SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
-> 2 mysql>SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
-> 0
FIND_IN_SET(str,strlista)
Retorna um valor 1
para
N
se a string str
está na lista strlist
contendo
N
substrings. A lista de string é
composta de substrings separadas pelo caracter
‘,
’. Se o primeiro argumento
é uma string constante e o segundo é uma coluna do tipo
SET
, a função
FIND_IN_SET()
é otimizada para usar
aritmética binária! Retorna 0
se
str
não está na
strlista
ou se
strlista
é uma string vazia. Retorna
NULL
se os argumentos são
NULL
. Esta função não irá funcionar
adequadamente se o primeiro argumento contém uma vírgula
(‘,
’):
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
HEX(N_ou_S)
Se N_OU_S é um número, é retornado um representação
string do valor hexadecimal de N
, onde
N
é um número muito grande
(BIGINT
). Isto é equivalente a
CONV(N,10,16)
.
Se N_OU_S é uma string, é retornado uma string hexadecimal
de N_OU_S onde cada caracter de N_OU_S é convertido para 2
dígitos hexadecimais. Isto é o inverso da string
0xff
.
mysql>SELECT HEX(255);
-> 'FF' mysql>SELECT HEX("abc");
-> 616263 mysql>SELECT 0x616263;
-> "abc"
INSTR(str,substr)
Retorna a posição da primeira ocorrência da substring
substr
na string str
.
É o mesmo que as o LOCATE()
com dois
argumentos, exceto pelo fato de que os argumentos estão
tracados:
mysql>SELECT INSTR('foobarbar', 'bar');
-> 4 mysql>SELECT INSTR('xbar', 'foobar');
-> 0
Esta função é multi-byte. Na versão 3.23 do MySQL esta função é caso sensitivo, enquanto na versão 4.0 ela só é caso-sensitivo se os argumentos são uma string binária.
INSERT(str,pos,tam,novastr)
Retorna a string str
, com a a substring
começando na posição pos
e contendo
tam
caracteres substituida pela string
novastr
:
mysql> SELECT INSERT('Quadratico', 3, 4, 'Onde');
-> 'QuOndetico'
Esta função é multi-byte.
LCASE(str)
,
LOWER(str)
Retorna a string str
com todos caracteres
alterados para letra minúsculas de acordo com o conjunto de
caracteres atual (o padrão é ISO-8859-1 Latin1):
mysql> SELECT LCASE('MYSQL');
-> 'mysql'
Esta é uma função multi-byte.
LEFT(str,tam)
Retorna os tam
caracteres mais a esquerda
da string str
:
mysql> SELECT LEFT('foobarbar', 5);
-> 'fooba'
Esta função é multi-byte.
LOAD_FILE(nome_arquivo)
Lêb o arquivo e retona o conteudo do arquivo como uma
string. O arquivo beve estar no servidor, você deve
especificar o caminho completo para o arquivo, e você deve
ter o privilégio FILE
. O arquivo deve
ser legível para todos e ser menor que o especificado em
max_allowed_packet
.
Se o arquivo não existe ou não pode ser lido devido a
alguma das razões acima, a função retornará
NULL
:
mysql> UPDATE nome_tabela
SET coluna_blob=LOAD_FILE("/tmp/picture")
WHERE id=1;
Se você não está usando a versão 3.23 MySQL, você tem
que fazer a leitura do arquivo dentro do seu aplicativo e
criar uma instrução INSERT
para
atualizar o banco de dados com a informação do arquivo. Um
modo de se fazer isto, se você estiver usando a biblioteca
MySQL++, pode ser encontrada em
http://www.mysql.com/documentation/mysql++/mysql++-examples.html.
LOCATE(substr,str)
,
LOCATE(substr,str,pos)
A primeira sintaxe retorna a posição da primeira
ocorrência da substring substr
na string
str
. A segunda sintaxe retorna a
posição da primeira ocorrência da substring
substr
na string str
,
iniciando na posição pos
. Retornam
0
se substr
não está
em str
:
mysql>SELECT LOCATE('bar', 'foobarbar');
-> 4 mysql>SELECT LOCATE('xbar', 'foobar');
-> 0 mysql>SELECT LPAD('hi',4,'??');
-> '??hi'
LTRIM(str)
Retorna a string str
com caracteres de
espaços extras iniciais removidos:
mysql> SELECT LTRIM(' barbar');
-> 'barbar'
MAKE_SET(bits,str1,str2,...)
Retorna um conjunto (uma string contendo substrings
separadas por ‘,
’) contendo
as strings que tem o bit correspondente em
bits
definido . str1
corresponde ao bit 1, str2
ao bit 2, etc.
Strings NULL
em str1
,
str2
, ...
não são
adicionadas ao resultado:
mysql>SELECT MAKE_SET(1,'a','b','c');
-> 'a' mysql>SELECT MAKE_SET(1 | 4,'Oi','meu','mundo');
-> 'Oi,mundo' mysql>SELECT MAKE_SET(0,'a','b','c');
-> ''
OCT(N)
Retorna uma representação string do valor octal de
N
, onde N
é um
número muito grande. Isto é equivalente a
CONV(N,10,8)
. Retorna
NULL
se N
é
NULL
:
mysql> SELECT OCT(12);
-> '14'
ORD(str)
Se o caracter mais a esquerda da string
str
é um caracter multi-byte, é
retornado o código para este caracter, calculado a partir
dos valores do código ASCII dos seus caracteres
contituintes utizando-se a seguinte fórmula:
((primeiro byte do código ASCII)*256+(segundo byte
do código ASCII))[*256+terceiro byte do código
ASCII...]
. Se o caracter mais a esquerda não é
multi-byte, é retornado o mesmo valor que a função
ASCII()
retorna:
mysql> SELECT ORD('2');
-> 50
LENGTH(str)
,
OCTET_LENGTH(str)
,
CHAR_LENGTH(str)
,
CHARACTER_LENGTH(str)
Retorna o tamanho da string str
:
mysql>SELECT LENGTH('text');
-> 4 mysql>SELECT OCTET_LENGTH('text');
-> 4
LENGTH()
e
OCTET_LENGTH()
são sinônimos e medem o
tamanho da length em bytes (octets). Um caracter multi-byte
conta é considerado vários bytes.
CHAR_LENGTH()
e
CHARACTER_LENGTH()
são sinônimos e
medem o tamanho da string em caracteres. Um caracter
multi-byte conta como um único caracter. Isto significa que
para uma string contendo cinco caracteres de dois bytes,
LENGTH()
retorna 10
,
enquanto CHAR_LENGTH()
retorna
5
.
MID(str,pos,len)
MID(str,pos,len)
é um sinônimo para
SUBSTRING(str,pos,len)
.
POSITION(substr IN str)
POSITION(substr IN str)
é um sinônimo
para LOCATE(substr,str)
.
QUOTE(str)
Coloca uma string entre aspas para produzir um resultado que
possa ser usada em uma intrução SQL como um valor de dados
com o caracter de escape correto. A string é retornada
entre aspas simples e cada instâqncia de aspas simples
(‘'
’), barra invertida
(‘\
’), ASCII NUL, e Control-Z
é precedida por uma barra invertida. Se o argumento é
NULL
, o valor retornado é a palavra
``NULL'' sem aspas simples.
A função QUOTE()
foi adicionada na
versão 4.0.3 do MySQL.
mysql>SELECT QUOTE("Don't");
-> 'Don\'t!' mysql>SELECT QUOTE(NULL);
-> NULL
REPEAT(str,cont)
Retorna uma string consistindo da string
str
repetida cont
vezes. Se cont <= 0
, é retornado uma
string vazia. É retornado NULL
se
str
ou cont
são
NULL
:
mysql> SELECT REPEAT('MySQL', 3);
-> 'MySQLMySQLMySQL'
REPLACE(str,da_str,para_str)
Retorna a string str
com todas
ocorrências da string da_str
substituida
pela string para_str
:
mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
-> 'WwWwWw.mysql.com'
Esta função é multi-byte.
REVERSE(str)
Returns the string str
with the order of
the characters reversed:
mysql> SELECT REVERSE('abc');
-> 'cba'
Esta função é multi-byte.
RIGHT(str,tem)
mysql> SELECT RIGHT('foobarbar', 4);
-> 'rbar'
Esta função é multi-byte.
RPAD(str,tam,strpreech)
Retorna a string str
, preenchida a
direita com a string strpreench
para um
tamanho de tam
caracteres. Se
str
é maior que tam
,
o valor retornado é reduzido para tam
caracteres.
mysql> SELECT RPAD('hi',5,'?');
-> 'hi???'
RTRIM(str)
Retourna a string str
com caracteres de
espaços extras finais removidos:
mysql> SELECT RTRIM('barbar ');
-> 'barbar'
Esta função é multi-byte.
SOUNDEX(str)
Retorna uma string 'soundex' de str
. Duas
strings que parecidas fonéticamentea devem ter strings
'soundex' iguais. Uma string soundex padrão possui 4
caracteres, mas a função SOUNDEX()
retorna uma string de tamanho arbitrário. Você posde usar
SUBSTRING()
no resultado para obter uma
string 'soundex' padrão. Todos os caracteres não
alfanuméricos são ignorados na string dada. Todas
caracteres internacionais fora da faixa A-Z são tratados
como vogais:
mysql>SELECT SOUNDEX('Hello');
-> 'H400' mysql>SELECT SOUNDEX('Quadratically');
-> 'Q36324'
SPACE(N)
Retorna uma string contendo N
caracteres
de espaço:
mysql> SELECT SPACE(6);
-> ' '
SUBSTRING(str,pos)
,
SUBSTRING(str FROM pos)
,
SUBSTRING(str,pos,tam)
,
SUBSTRING(str FROM pos FOR tam)
A forma sem um argumento tam
retorna uma
substring da string str
iniciando na
posição pos
. A forma com um argumento
tam
retorna a substring com
tam
caracteres da string
str
, iniciando da posição
pos
. A forma variante que utiliza
FROM
é a sintaxe SQL-92:
mysql>SELECT SUBSTRING('Quadratically',5);
-> 'ratically' mysql>SELECT SUBSTRING('foobarbar' FROM 4);
-> 'barbar' mysql>SELECT SUBSTRING('Quadratically',5,6);
-> 'ratica'
Esta função é multi-byte.
SUBSTRING_INDEX(str,delim,cont)
Retorna a substring da string str
antes
de cont
ocorrencias do delimitador
delim
. Se cont
é
positivo, tudo a esquerda do delimitador final (contando a
partir da esquerda) é retornado. Se cont
é negativo, tudo a direita do delimitador final (contando a
partir da direita) é retornado.
mysql>SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
-> 'www.mysql' mysql>SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
-> 'mysql.com'
Esta função é multi-byte.
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM]
str)
Retorna a string str
com todos prefixos
e/ou sufixos remstr
removidos. Se nenhum
dos especificadores BOTH
,
LEADING
ou TRAILING
são dados, é considerado BOTH
. Se
remstr
não é especificada, espaços
são removidos:
mysql>SELECT TRIM(' bar ');
-> 'bar' mysql>SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
-> 'barxxx' mysql>SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
-> 'bar' mysql>SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
-> 'barx'
Esta função é multi-byte.
UCASE(str)
,
UPPER(str)
Retorna a string str
com todos caracteres
alterados para letra maiúsculas de acordo com o conjunto de
caracteres atual (o padrão é ISO-8859-1 Latin1):
mysql> SELECT UCASE('Hej');
-> 'HEJ'
Esta é uma função multi-byte.
MySQL automaticamente converte números para quando necessário, e vice-versa:
mysql>SELECT 1+"1";
-> 2 mysql>SELECT CONCAT(2,' test');
-> '2 test'
Se você quiser converter um número em uma string de forma
explicita, passe-o como um argumento de
CONCAT()
.
Se uma função de string tem uma string binária como argumento, a string resultante é também um string binária. Um número convertido para uma string é tratado como um string binária. Isto afeta apenas a comparação.
Normalmente, se qualquer expressão em uma string é caso-sensitivo, a comparação é realizada no modo caso sensitivo.
expr LIKE pad [ESCAPE 'car-escape']
Correspondência de padrões usando uma simples expressão
de comparações SQL. Retorna 1
(VERDADEIRO) ou 0
(FALSO). Com
LIKE
você pode usar os seguintes
meta-caracteres no padrao:
Car | Descrição |
% | Corresponde a qualquer número de caracteres, até zero caracteres |
_ | Corresponde a exatamente um caracter |
mysql>SELECT 'David!' LIKE 'David_';
-> 1 mysql>SELECT 'David!' LIKE '%D%v%';
-> 1
Para testar instâncias literais de um meta caracter,
preceda o caracter com o carcter de escape. Se você não
especificar o caracter de ESCAPE
,
assume-se ‘\
’:
String | Description |
\% | Correponde a um caracter % |
\_ | Correponde a um caracter _ |
mysql>SELECT 'David!' LIKE 'David\_';
-> 0 mysql>SELECT 'David_' LIKE 'David\_';
-> 1
Para especificar um caracter de escape diferebte, use a
cláusula ESCAPE
:
mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
-> 1
As seguintes instruções mostram que a comparação de strings são caso-insensitivo, a menos que um dos operandos seja uma string binária:
mysql>SELECT 'abc' LIKE 'ABC';
-> 1 mysql>SELECT 'abc' LIKE BINARY 'ABC';
-> 0
LIKE
é permitido em uma expressão
numérica! (Esta é uma extensão MySQL para o
LIKE
do SQL-99.)
mysql> SELECT 10 LIKE '1%';
-> 1
Nota: Como MySQL usa sintaxe de escape do C em strings
(por exemplo, '\n
'), você deve dobrar
qualquer ‘\
’ que você usar
em sua string LIKE
. Por exemplo, para
pesquisar por '\n
', especifique-o como
'\\n
'. Para buscar por
‘\
’, especifique-o como
'\\\\
' (as barras invertidas são
eliminadas uma vez pelo analizador e outra vez quando a
correspondência de padrões é feita, deixando uma
únicas barra invertida para ser verificada).
Note: O
LIKE
atual não é um caracter
multi-byte
. Comparaçãoes são feitas caracter
por caracter.
expr NOT LIKE pad [ESCAPE 'car-escape']
O mesmo que NOT (expr LIKE pad [ESCAPE
'car-escape'])
.
expr SOUNDS LIKE expr
O mesmo que SOUNDEX(expr)=SOUNDEX(expr)
(disponível apenas na versão 4.1 ou posterior).
expr REGEXP pad
, expr RLIKE
pad
Realiza a busca de padrões em uma expressã string com
base no padrão pad
. O padrão pode ser
uma expressão regular extendida. See
Apêndice G, Sintaxe de Expressões Regulares do MySQL. Retorna 1
se
expr
conincide com
pad
, senão retorna
0
. RLIKE
é um
sinônimo para REGEXP
, fornecido para
compatibilidade com mSQL
. Nota: Como
MySQL usa a sintaxe de escape do C em strings (por
exemplo, '\n
'), você deve dobrar
qualquer ‘\
’ que você use
em sua string REGEXP
. Como na versão
3.23.4 do MySQL, REGEXP
é caso-
insensitivo para strings normais (não binárias).
mysql>SELECT 'Monty!' REGEXP 'm%y%%';
-> 0 mysql>SELECT 'Monty!' REGEXP '.*';
-> 1 mysql>SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
-> 1 mysql>SELECT "a" REGEXP "A", "a" REGEXP BINARY "A";
-> 1 0 mysql>SELECT "a" REGEXP "^[a-d]";
-> 1
REGEXP
e RLIKE
usam
o conjunto de caracteres atual (ISO-8859-1 Latin1 por
padrão) para decidir o tipo de caracter.
expr NOT REGEXP pad
, expr NOT
RLIKE pad
O mesmo que NOT (expr REGEXP pad)
.
STRCMP(expr1,expr2)
STRCMP()
retorna 0
se as string são a mesma, -1
se o
primeiro argumento é menor que o segundo de acordo com a
ordenação atual e 1
em caso
contrário:
mysql>SELECT STRCMP('texto', 'texto2');
-> -1 mysql>SELECT STRCMP('texto2', 'texto');
-> 1 mysql>SELECT STRCMP('texto', 'texto');
-> 0
MATCH (col1,col2,...) AGAINST (expr [IN BOOLEAN
MODE | WITH QUERY EXPANSION] )
MATCH ... AGAINST()
é usado para busca
de textos completos e retorna a relvância - similaridade
medidad entre o texto nas colunas
(col1,col2,...)
e a consulta
expr
. Relevância é um número de
ponto flutuante. Relevância zero significa que não houve
nenhuma similaridade. MATCH ...
AGAINST()
está disponível na versão 3.23.23
ou posterior do MySQL. A extensão IN BOOLEAN
MODE
foi adicionada na versão 4.0.1,
WITH QUERY EXPANSION
foi adicionado na
versão 4.1.1. Para detalhes e exemplos de uso, veja
Secção 6.8, “Pesquisa Full-text no MySQL”.
BINARY
O operador BINARY
transforma uma string
em uma string binária. Este é um modo fácil de forçar
a comparação para se caso-sensitivo mesmo se a coluna
não seja definida como BINARY
ou
BLOB
:
mysql>SELECT "a" = "A";
-> 1 mysql>SELECT BINARY "a" = "A";
-> 0
BINARY string
é um atalho para
CAST(string AS BINARY)
. See
Secção 6.3.5, “Funções de Conversão”.
BINARY
foi introduzida na versão
3.23.0 do MySQL.
Note que em alguns contextos MySQL não estará apto a
usar o índice de forma eficiente quando se transformar
uma coluna índice em BINARY
.
Se você quiser compara um blob caso-insensitivo você pode sempre convertê-lo para letras maiúsculas antes de faer a comparação:
SELECT 'A' LIKE UPPER(col_blobl) FROM nome_tabela;
Não planejamos introduzir em breve coerção (casting) entre diferentes conjuntos de caracteres para tornar comparções de strings mais flexível.
Os operadores aritiméticos usuais estão disponíveis.
‘-
’,
‘+
’, e
‘*
’, o resultado é calculado
com precisão de BIGINT
(64-bit) se ambos
os argumentos são inteiros! Se um dos argumentos for um
inteiro sem sinal, e o outro argumento é um inteiro também,
o resultado será um inteiro sem sinal. See
Secção 6.3.5, “Funções de Conversão”.
+
Adição:
mysql> SELECT 3+5;
-> 8
-
Subtração:
mysql> SELECT 3-5;
-> -2
*
Multiplicação:
mysql>SELECT 3*5;
-> 15 mysql>SELECT 18014398509481984*18014398509481984.0;
-> 324518553658426726783156020576256.0 mysql>SELECT 18014398509481984*18014398509481984;
-> 0
O resultado da última expressão é incorreta porque o
resultado da multiplicação de inteiros excede a faixa de
64-bits dos cálculos BIGINT
.
/
Divisão:
mysql> SELECT 3/5;
-> 0.60
Divisões por zero produz um resultado
NULL
:
mysql> SELECT 102/(1-1);
-> NULL
Uma divisão será calculada com aritimética
BIGINT
somente se executada em um
contexto no qual o resultado é convertido para um
interiro!
Todas as funções matematicas retornam
NULL
no caso de um erro.
-
Menos unario. Muda o sinal do argumento:
mysql> SELECT - 2;
-> -2
Note que se este operador é utilizando com um
BIGINT
, o valor retornado é um
BIGINT
! Isto significa que você deve
evitar usar -
em inteiros que pode ter
o valor de -2^63
!
ABS(X)
Retorna o valor absoluto de X
:
mysql>SELECT ABS(2);
-> 2 mysql>SELECT ABS(-32);
-> 32
O uso desta função é seguro com valores
BIGINT
.
SIGN(X)
Retorna o sinal do argumento como -1
,
0
, ou 1
, dependendo
de quando X
é negativo, zero, ou
positivo:
mysql>SELECT SIGN(-32);
-> -1 mysql>SELECT SIGN(0);
-> 0 mysql>SELECT SIGN(234);
-> 1
MOD(N,M)
, %
Modulo (como o operador %
em C).
Retorna o resto de N
dividido por
M
:
mysql>SELECT MOD(234, 10);
-> 4 mysql>SELECT 253 % 7;
-> 1 mysql>SELECT MOD(29,9);
-> 2 mysql>SELECT 29 MOD 9;
-> 2
O uso desta função é seguro com valores
BIGINT
. O último exemplo só funciona
no MySQL 4.1
FLOOR(X)
Retorna o maior valor inteiro não maior que
X
:
mysql>SELECT FLOOR(1.23);
-> 1 mysql>SELECT FLOOR(-1.23);
-> -2
Note que o valor retornado é convertido para um
BIGINT
!
CEILING(X)
, CEIL(X)
Retorna o menor valor inteiro não menor que
X
:
mysql>SELECT CEILING(1.23);
-> 2 mysql>SELECT CEIL(-1.23);
-> -1
O alias CEIL()
foi adicionado versão
4.0.6.
Note que o valor retornado é convertido para um
BIGINT
!
ROUND(X)
,
ROUND(X,D)
Retorna o argumeto X
, arredondado para
o inteiro mais próximo. Com dois argumentos o
arredandamento é feito para um número com
D
decimais.
mysql>SELECT ROUND(-1.23);
-> -1 mysql>SELECT ROUND(-1.58);
-> -2 mysql>SELECT ROUND(1.58);
-> 2 mysql>SELECT ROUND(1.298, 1);
-> 1.3 mysql>SELECT ROUND(1.298, 0);
-> 1 mysql>SELECT ROUND(23.298, -1);
-> 20
Note que o comportamento de ROUND()
quando o argumento está no meio do caminho entre dois
inteiros depende da implementação da biblioteca C.
Alguns arredondamentos para o número mais próximo, são
sempre para baixo, para cima ou são zero. Se você
precisa de um tipo de arredondamento, você deve usar uma
função bem definida como TRUNCATE()
ou FLOOR()
.
DIV
Divisão de inteiros. Similar ao
FLOOR()
mas seguro com valores
BIGINT
.
mysql> SELECT 5 DIV 2
-> 2
DIV
é novo no MySQL 4.1.0.
EXP(X)
Retorna o valor de e
(the base of
natural logarithms) raised to the power of
X
:
mysql>SELECT EXP(2);
-> 7.389056 mysql>SELECT EXP(-2);
-> 0.135335
LN(X)
Retorna o logaritmo natural de X
:
mysql>SELECT LN(2);
-> 0.693147 mysql>SELECT LN(-2);
-> NULL
Esta função foi adicionada na versão 4.0.3 do MySQL. É
sinônimo de LOG(X)
no MySQL.
LOG(X)
, LOG(B,X)
Se chamado com um parâmetro, esta função retorna o
logarítmo natural de X
:
mysql>SELECT LOG(2);
-> 0.693147 mysql>SELECT LOG(-2);
-> NULL
Se chamado com dois parâmetros, esta função retorna o
logarítmo natural de X
para uma base
arbitraria B
:
mysql>SELECT LOG(2,65536);
-> 16.000000 mysql>SELECT LOG(1,100);
-> NULL
A opção de base arbitrária foi adicionada na versão
4.0.3 do MySQL. LOG(B,X)
é equivalente
a LOG(X)/LOG(B)
.
LOG2(X)
Returna o logarítmo na base 2 de X
:
mysql>SELECT LOG2(65536);
-> 16.000000 mysql>SELECT LOG2(-100);
-> NULL
LOG2()
é útil para descobrir quantos
bits um número necessitaria para ser armazenado. Esta
função foi adicionada na versão 4.0.3 do MySQL. Em
versões anteriores, você pode usar
LOG(X)/LOG(2)
.
LOG10(X)
Returna o logarítmo na base 10 de X
:
mysql>SELECT LOG10(2);
-> 0.301030 mysql>SELECT LOG10(100);
-> 2.000000 mysql>SELECT LOG10(-100);
-> NULL
POW(X,Y)
,
POWER(X,Y)
Retorna o valor de X
elevado a
potência de Y
:
mysql>SELECT POW(2,2);
-> 4.000000 mysql>SELECT POW(2,-2);
-> 0.250000
SQRT(X)
Retorna o a raiz quadrada não negativa de
X
:
mysql>SELECT SQRT(4);
-> 2.000000 mysql>SELECT SQRT(20);
-> 4.472136
PI()
Retorna o valor de PI. A quantidade de números decimais padrão é 5, mas o MySQL usa internamente a precisão dupla completa para PI.
mysql>SELECT PI();
-> 3.141593 mysql>SELECT PI()+0.000000000000000000;
-> 3.141592653589793116
COS(X)
Retorna o cosseno de X
, onde
X
é dado em radianos:
mysql> SELECT COS(PI());
-> -1.000000
SIN(X)
Retorna o seno de X
, onde
X
é dado em radianos:
mysql> SELECT SIN(PI());
-> 0.000000
TAN(X)
Retorna a tangente de X
, onde
X
é dado em radianos:
mysql> SELECT TAN(PI()+1);
-> 1.557408
ACOS(X)
Retorna o arco cosseno X
, isto é, o
valor cujo cosseno é X
. Retorna
NULL
se X
não está
na faixa de -1
a 1
:
mysql>SELECT ACOS(1);
-> 0.000000 mysql>SELECT ACOS(1.0001);
-> NULL mysql>SELECT ACOS(0);
-> 1.570796
ASIN(X)
Retorna o arco seno X
, isto é, o valor
cujo seno é X
. Retorna
NULL
se X
não está
na faixa de -1
a 1
:
mysql>SELECT ASIN(0.2);
-> 0.201358 mysql>SELECT ASIN('foo');
-> 0.000000
ATAN(X)
Retorna o arco tangente X
, isto é, o
valor cuja tangente é X
.
X
:
mysql>SELECT ATAN(2);
-> 1.107149 mysql>SELECT ATAN(-2);
-> -1.107149
ATAN(Y,X)
,
ATAN2(Y,X)
Retorna o arco tangente de duas variaveis
X
e Y
. É similar ao
caclculo do arco tengente de Y / X
,
exceto que os sinais de ambos argumentos são usados para
determinas o quadrante do resultado:
mysql>SELECT ATAN(-2,2);
-> -0.785398 mysql>SELECT ATAN2(PI(),0);
-> 1.570796
COT(X)
Returns a cotangente de X
:
mysql>SELECT COT(12);
-> -1.57267341 mysql>SELECT COT(0);
-> NULL
CRC32(expr)
Calcula um valor de verificação de redundância cíclica
e retorna um valor unsigned de 32 bits. O resultado é
NULL
se o argumento é
NULL
. O argumento esperado é uma
string e será tratado como tal se não for.
mysql> SELECT CRC32('MySQL');
-> 3259397556
CRC32()
está disponível a partir do
MySQL 4.1.0.
RAND()
, RAND(N)
Retorna um valor de ponto flutuante aleatório na faixa de
0
a 1.0
. Se um
argumento inteiro N
é especificado,
ele é usado como uma semente (produzindo uma sequência
repetitiva):
mysql>SELECT RAND();
-> 0.9233482386203 mysql>SELECT RAND(20);
-> 0.15888261251047 mysql>SELECT RAND(20);
-> 0.15888261251047 mysql>SELECT RAND();
-> 0.63553050033332 mysql>SELECT RAND();
-> 0.70100469486881
Você não pode usar uma coluna com valores
RAND()
em uma cláusula ORDER
BY
, pois ORDER BY
avaliaria a
coluna múltiplas vezes. Na versão 3.23 você pode fazer:
SELECT * FROM nome_tabela ORDER BY
RAND()
Isto é útil para obter um amostra aleatória de um
conjunto SELECT * FROM tabela1,tabela2 WHERE a=b
AND c<d ORDER BY RAND() LIMIT 1000
.
Note que um RAND()
em uma cláusula
WHERE
será reavliado toda vez que
WHERE
é executado.
RAND()
não é um gerador de números
aletatórios perfeito, mas é um modo rápido de se gerar
números aleatórios ad hoc que serão portáveis entre
plataformas para a mesma versão do MySQL.
LEAST(X,Y,...)
Com dois ou mais argumentos, retorna o menor (valor-mínimo) argumento. Os argumentos são comparados usando as seguintes regras:
Se o valor de retorno é usado em um contexto
INTEGER
, ou todos argumentos são
valores inteiro, eles são comparados como inteiros.
Se o valor de retorno é usado em um contexto
REAL
, ou todos argumentos são
valores reais, eles são comparados como inteiros.
Se qualquer um dos argumento for uma string caso-sensitivo, os argumentos são comparados como strings caso-sensitivo.
Nos outros casos, os argumentos são comparados como strings caso-insensitivo:
mysql>SELECT LEAST(2,0);
-> 0 mysql>SELECT LEAST(34.0,3.0,5.0,767.0);
-> 3.0 mysql>SELECT LEAST("B","A","C");
-> "A"
Em versões do MySQL anteriores a versão 3.22.5, você
pode usar MIN()
no lugar de
LEAST
.
GREATEST(X,Y,...)
Retorna o maior (valor máximo) argumento. Os argumentos
são comparados usando as mesmas regras do
LEAST
:
mysql>SELECT GREATEST(2,0);
-> 2 mysql>SELECT GREATEST(34.0,3.0,5.0,767.0);
-> 767.0 mysql>SELECT GREATEST("B","A","C");
-> "C"
Em versões do MySQL anteriores a versão 3.22.5, você
pode usar MAX()
no lugar de
GRATEST
.
DEGREES(X)
Retorna o argumento X
, convertido de
radianos para graus:
mysql> SELECT DEGREES(PI());
-> 180.000000
RADIANS(X)
Retorna o argumento X
, convertido de
graus para radianos:
mysql> SELECT RADIANS(90);
-> 1.570796
TRUNCATE(X,D)
Retiorna o número X
, truncado para
D
casas decimais. Se
D
é 0
, o resultado
não terá ponto deciaml ou prate fracionária:
mysql>SELECT TRUNCATE(1.223,1);
-> 1.2 mysql>SELECT TRUNCATE(1.999,1);
-> 1.9 mysql>SELECT TRUNCATE(1.999,0);
-> 1 mysql>SELECT TRUNCATE(-1.999,1);
-> -1.9
A partir do MySQL 3.23.51 todos o números são arredondados para zero.
Se D
é negativo, então D numeros da
parte inteira são zerados:
mysql> SELECT TRUNCATE(122,-2);
-> 100
Note que como os números decimais não são normalmente armazenados como números exatos, mas como valores de dupla precisão, você pode obter o seguinte resultado:
mysql> SELECT TRUNCATE(10.28*100,0);
-> 1027
O resultado acima acontece porque 10.28 é, na verdade, armazenado como 10.2799999999999999.
Esta seção descreve as funções que podem ser usadas para manipular valores temporais.
Veja Secção 6.2.2, “Tipos de Data e Hora” para uma descrição da faixa de valores que cada tipo tem e os formatos válidos nos quais valores de data e hora podes ser especificados.
Aqui está um exemplo que usa funções de data. A consulta
seguinte seleciona todos os registros com um valores em uma
coluna col_data
dentro dos últimos 30 dias:
mysql> SELECT algo FROM nome_tabela
WHERE TO_DAYS(NOW()) - TO_DAYS(col_data) <= 30;
(Note que a consulta também selecionará registros com datas futuras.)
Funções que esperam valores de data normaemente aceitaram valores datetime e ignoram a parte da hora. Funções que esperam valores de hora normalmente aceitarão valores datetime e ignoram a parte da data.
Funções que retornam a data ou hora atual são avaliadas
apenas uma vez por consulta, no inicio da sua execução. Isto
significa que várias referências a uma função com
NOW()
dentro de uma mesma consulta sempre
produzirá o memo resultado. Este princípio também se aplica a
CURDATE()
, CURTIME()
,
UTC_DATE()
, UTC_TIME()
,
UTC_TIMESTAMP()
, e qualquer um dos seus
sinônimos.
A faixa do valor retornado na seguinte descrição da função
se aplica a datas completas. Se uma data é um valor ``zero'' ou
uma data incompleta tal como '2001-11-00'
,
funções que extraem parte de uma data podem retornam 0. Por
exemplo, DAYOFMONTH('2001-11-00')
retorna 0.
DATE(expr)
Extrai a parte da data da expressão date ou datetime em
expr
.
mysql> SELECT DATE('2003-12-31 01:02:03');
-> '2003-12-31'
DATE()
está disponível a partir do
MySQL 4.1.1.
TIME(expr)
Extrai a parte da hora da expressão time ou datetime em
expr
.
mysql>SELECT TIME('2003-12-31 01:02:03');
-> '01:02:03' mysql>SELECT TIME('2003-12-31 01:02:03.000123');
-> '01:02:03.000123'
TIME()
está disponível a partir do
MySQL 4.1.1.
TIMESTAMP(expr)
,
TIMESTAMP(expr,expr2)
Com um argumento, retorna a expressão date ou datetime em
expr
como um valor datetime. Com dois
argumentos, adiciona a expressão time e
expr2
à expressão date ou datetime em
expr
e retorna um valor datetime.
mysql>SELECT TIMESTAMP('2003-12-31');
-> '2003-12-31 00:00:00' mysql>SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');
-> '2004-01-01 00:00:00'
TIMESTAMP()
está disponível a partir do
MySQL 4.1.1.
DAYOFWEEK(data)
Retorna o índice do dia da semana para
data
(1
= Domingo,
2
= Segunda, ... 7
=
Sábado). Estes valores de índices correspondem ao padrão
ODBC.
mysql> SELECT DAYOFWEEK('1998-02-03');
-> 3
WEEKDAY(data)
Retorna o índice do dia das semana para
data
(0
= Segunda,
1
= Terça, ... 6
=
Domingo):
mysql>SELECT WEEKDAY('1998-02-03 22:23:00');
-> 1 mysql>SELECT WEEKDAY('1997-11-05');
-> 2
DAYOFMONTH(data)
Retorna o dia do mês para data
, na faixa
de 1
até 31
:
mysql> SELECT DAYOFMONTH('1998-02-03');
-> 3
DAY(date)
DAY()
é um sinônimo para
DAYOFMONTH()
. Está disponível a partir
do MySQL 4.1.1.
DAYOFYEAR(data)
Retorna o dia do ano para data
, na faixa
de 1
até 366
:
mysql> SELECT DAYOFYEAR('1998-02-03');
-> 34
MONTH(data)
Retorna o mês para data
, na faixa de
1
até 12
:
mysql> SELECT MONTH('1998-02-03');
-> 2
DAYNAME(data)
Retorna o nome do dia da semana para
data
:
mysql> SELECT DAYNAME('1998-02-05');
-> 'Thurday'
MONTHNAME(data)
Retorna o nome do mês para data
:
mysql> SELECT MONTHNAME('1998-02-05');
-> 'February'
QUARTER(data)
Retorna o trimaster para data
, na faixa
de 1
até 4
:
mysql> SELECT QUARTER('98-04-01');
-> 2
WEEK(data [,modo])
A função retorna o número da semana para
date
. A forma de dois argumentos de
WEEK()
permite que você especifique se a
semana começa no Domingo ou na Segunda e se o valor de
retorno deve estar na faixa de 0-53 ou 1-5. Quando o
argumento modo
é omitido, o valor de uma
variável de servidor default_week_format
(ou 0 no MySQL 4.0 e mais novo) é assumido. See
Secção 5.5.6, “Sintaxe de SET
”.
A seguinte tabela demonstra como o argumento
modo
funciona:
Valor | Significado |
0 | Semana começa no Domingo; retorna o valor na faixa de 0 a 53; semana 1 é a primeira semana neste ano. |
1 | Semana começa na Segunda; retorna o valor na faixa de 0 a 53; semana 1 é a primeira semana com mais de 3 dias neste ano |
2 | Semana começa no Domingo; retorna o valor na faixa de 1 a 53; semana 1 é a primeira semana neste ano. |
3 | Semana começa na Segunda; retorna o valor na faixa de 1 a 53; semana 1 é a primeira semana com mais de 3 dias neste ano. |
4 | Semana começa no Domingo; retorna o valor na faixa de 0 a 53; semana 1 é a primeira semana com mais de 3 dias neste ano. |
5 | Semana começa na Segunda; retorna o valor na faixa de 0 a 53; semana 1 é a primeira semana neste ano. |
6 | Semana começa no Domingo; retorna o valor na faixa de 0 a 53; semana 1 é a primeira semana que tenha mais de 3 dias neste ano. |
7 | Semana começa na Segunda; retorna o valor na faixa de 1 a 53; semana 1 é a primeira semana neste ano. |
O valor mode
de 3
pode
ser usado a partir do MySQL 4.0.5. O valor
mode
de 4
e acima pode
ser usado a partir do MySQL 4.0.17.
mysql>SELECT WEEK('1998-02-20');
-> 7 mysql>SELECT WEEK('1998-02-20',0);
-> 7 mysql>SELECT WEEK('1998-02-20',1);
-> 8 mysql>SELECT WEEK('1998-12-31',1);
-> 53
Nota: Na versão 4.0, WEEK(#,0)
foi
alterado para corresponder ao calendário americano. Antes
WEEK()
era calculada de forma errada para
data no EUA. (Na verdade WEEK(#) e WEEK(#,0) era errado para
todos os casos).
Note que se a data for a última semana do ano anterior, o
MySQL retornará 0 se você não usar 2, 3, 6 ou 7 como
argumento opcional modo
:
mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
-> 2000, 0
Pode-se questionar que o MySQL deveria retornar 52 para a
função WEEK()
ja que a data dada
ocorre, na verdade, ma 52a. semana de 1999. Nós decidimos
retornar 0 já que queremos que função retorne ``o número
da semana do ano dado''. Isto faz com que o uso da função
WEEK()
seja seguro quando combinado com
outras funções que extraiam um parte de uma data.
Se você prefere que o resultado seja avaliado em relacão
ao ano que aontém o primeiro dia da semana de uma data
dada, então você deve usar o 2, 3, 6 ou 7 como argumento
opcional modo
:
mysql> SELECT WEEK('2000-01-01',2);
-> 52
Alternativamente você pode usar a função
YEARWEEK()
:
mysql>SELECT YEARWEEK('2000-01-01');
-> 199952 mysql>SELECT MID(YEARWEEK('2000-01-01'),5,2);
-> '52'
WEEKOFYEAR(data)
Retorna a semana da data como um número na faixa de
1
a 53
.
mysql> SELECT WEEKOFYEAR('1998-02-20');
-> 8
WEEKOFYEAR()
esta disponível a partir do
MySQL 4.1.1.
YEAR(data)
Retorna o ano para data
na faixa de
1000
a 9999
:
mysql> SELECT YEAR('98-02-03');
-> 1998
YEARWEEK(data)
,
YEARWEEK(data,inicio)
Retorna o ano e a semana para a data. O argumento
inicio
funciona exatamente como o
argumento inicio
de
WEEK()
. Note que o ano pode ser diferente
do ano no argumento data para a primeira e a última semana
do ano:
mysql> SELECT YEARWEEK('1987-01-01');
-> 198653
Note que o número da semana é diferente do que seria
retornado pela função WEEK()
(0
) para os argumentos opcionais
0
ou 1
, já que
WEEK()
retorna a semana no centexto de um
ano dado.
HOUR(hora)
Retorna a hora para hora
. A faixa do
valor retornado será de 0
a
23
para o valor hora do dia.
mysql> SELECT HOUR('10:05:03');
-> 10
No entanto, a faixa dos valores TIME
atualmente são muito grandes, assim HOUR
pode retornar valores maior que 23
:
mysql> SELECT HOUR('272:59:59');
-> 272
MINUTE(hora)
Retorna o minuto para hora
, na faixa de
0
a 59
:
mysql> SELECT MINUTE('98-02-03 10:05:03');
-> 5
SECOND(hora)
Retorna o segundo para hora
, na faixa de
0
a 59
:
mysql> SELECT SECOND('10:05:03');
-> 3
MICROSECOND(expr)
Retorna os microsegundos da expressão time ou datetime em
expr
como um número na faixa de
0
a 999999
.
mysql>SELECT MICROSECOND('12:00:00.123456');
-> 123456 mysql>SELECT MICROSECOND('1997-12-31 23:59:59.000010');
-> 10
MICROSECOND()
está disponível a partir
do MySQL 4.1.1.
PERIOD_ADD(P,N)
Adiciona N
meses ao período
P
(no formato AAMM
ou
AAAAMM
). Retorna um valor no formato
AAAAMM
.
Note que o argumento de período P
não é um valor de data:
mysql> SELECT PERIOD_ADD(9801,2);
-> 199803
PERIOD_DIFF(P1,P2)
Retorna o número de meses entre os períodos
P1
e P2
.
P1
e P2
devem estar no
formato AAMM
ou
AAAAMM
.
Note que os argumentos de período P1
e
P2
não
são valores de data:
mysql> SELECT PERIOD_DIFF(9802,199703);
-> 11
DATE_ADD(data,INTERVAL tipo expr)
,
DATE_SUB(data,INTERVAL tipo expr)
Estas funções realizam operações aritméticas em datas.
A partir do MySQL 3.23, INTERVAL expr
tipo
é permitido nos dois lados do operador
+
se a expressao em ambos os lados é um
valor date ou datetime. Para o operador
-
, INTERVAL expr tipoe
é permitido apenas no lado direito, porque não faz sentido
subtrair um valor date ou datetime de um intervalo. (Veja
exemplo abaixo.)
data
é um valor
DATETIME
ou DATE
especificando a data de início. expr
is
an expressão especificando o intervala a ser adicionado ou
subtraido da data de início. expr
é uma
string; ela pode iniciar com um
‘-
’ para intervalos
negativos. type
é uma palavra chave
indicando como a expressão deve ser interpretada.
A seguinte tabela mostra como os argumentos
tipo
e expr
se
relacionam:
tipo do valor | Formarto esperado da
expr |
SECOND | SECONDS |
MINUTE | MINUTES |
HOUR | HOURS |
DAY | DAYS |
MONTH | MONTHS |
YEAR | YEARS |
MINUTE_SECOND | 'MINUTES:SECONDS' |
HOUR_MINUTE | 'HOURS:MINUTES' |
DAY_HOUR | 'DAYS HOURS' |
YEAR_MONTH | 'YEARS-MONTHS' |
HOUR_SECOND | 'HOURS:MINUTES:SECONDS' |
DAY_MINUTE | 'DAYS HOURS:MINUTES' |
DAY_SECOND | 'DAYS HOURS:MINUTES:SECONDS' |
DAY_MICROSECOND | 'DAYS.MICROSECONDS' |
HOUR_MICROSECOND | 'HOURS.MICROSECONDS' |
MINUTE_MICROSECOND | 'MINUTES.MICROSECONDS' |
SECOND_MICROSECOND | 'SECONDS.MICROSECONDS' |
MICROSECOND | 'MICROSECONDS' |
Os valores do tipo
DAY_MICROSECOND
,
HOUR_MICROSECOND
,
MINUTE_MICROSECOND
,
SECOND_MICROSECOND
e
MICROSECOND
são permitidos após o MySQL
4.1.1.
O MySQL permite qualquer delimitador de pontuação no
formato de expr
. Os delimitadores
mostrados na tabela são apenas sugeridos. Se o argumento
date
é um valor de
DATA
e seus cálculos envolvem apenas as
partes ANO
, MÊS
, e
DIA
(into é, nenhuma parte de hora), o
resultado é um valor do tipo DATE
.
Senão, o resultado é um valor do tipo
DATETIME
:
mysql>SELECT '1997-12-31 23:59:59' + INTERVAL 1 SECOND;
-> '1998-01-01 00:00:00' mysql>SELECT INTERVAL 1 DAY + '1997-12-31';
-> '1998-01-01' mysql>SELECT '1998-01-01' - INTERVAL 1 SECOND;
-> '1997-12-31 23:59:59' mysql>SELECT DATE_ADD('1997-12-31 23:59:59',
-> INTERVAL 1 SECOND); -> '1998-01-01 00:00:00' mysql>SELECT DATE_ADD('1997-12-31 23:59:59',
-> INTERVAL 1 DAY); -> '1998-01-01 23:59:59' mysql>SELECT DATE_ADD('1997-12-31 23:59:59',
-> INTERVAL '1:1' MINUTE_SECOND); -> '1998-01-01 00:01:00' mysql>SELECT DATE_SUB('1998-01-01 00:00:00',
-> INTERVAL '1 1:1:1' DAY_SECOND); -> '1997-12-30 22:58:59' mysql>SELECT DATE_ADD('1998-01-01 00:00:00',
-> INTERVAL '-1 10' DAY_HOUR); -> '1997-12-30 14:00:00' mysql>SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
-> '1997-12-02' mysql>SELECT DATE_ADD('1992-12-31 23:59:59.000002',
-> INTERVAL '1.999999' SECOND_MICROSECOND); -> '1993-01-01 00:00:01.000001'
Se você especificado um intervalo muito curto (não inclue
todas as partes que seriam esperadas pelo intervalo para
aquele tipo
), MySQL assume que você não
especificou a parte mais a esquerda do valor do intervalo.
Por exemplo, se você especifica um tipo
DAY_SECOND
, o valor esperado de
expr
deverá ter as partes de dias,
horas, minutos e segundos. Se você especifica um valor como
'1:10'
, MySQL assume que as partes do dia
e da hora foram esquecidas e o valor representa minutos e
segundos. Em outras palavras, '1:10'
DAY_SECOND
é interpretado de forma equivalente a
'1:10' MINUTE_SECOND
. Isto é análogo a
forma que o MySQL interpreta valores TIME
representado tempo decorrido no lugar de hora do dia.
Note que se você adicionar ou subtrair de uma data algo contendo uma parte de hora, o resultado é automaticamente convertido para um valor datetime:
mysql>SELECT DATE_ADD('1999-01-01', INTERVAL 1 DAY);
-> '1999-01-02' mysql>SELECT DATE_ADD('1999-01-01', INTERVAL 1 HOUR);
-> '1999-01-01 01:00:00'
Se você utilizar datas mal formadas, o valor retornado
NULL
. Sê você adicionar
MONTH
, YEAR_MONTH
, ou
YEAR
e a data resultante tiver um dia
maior que o dia máximo para aquele mês, o dia é ajustado
para o dia máximo no mês.
mysql> SELECT DATE_ADD('1998-01-30', interval 1 month);
-> '1998-02-28'
Note pelo exemplo anterior que a palavra-chave
INTERVAL
e o especificador
tipo
não são caso sensitivo.
ADDDATE(data,INTERVAL expr type)
,
ADDDATE(expr,dias)
Quando chamada com a forma INTERVAL
do
segundo argumento, ADDDATE()
é um
sinônimo para DATE_ADD()
. A função
relcionada SUBDATE()
é um sinônimo para
DATE_SUB()
.
mysql>SELECT DATE_ADD('1998-01-02', INTERVAL 31 DAY);
-> '1998-02-02' mysql>SELECT ADDDATE('1998-01-02', INTERVAL 31 DAY);
-> '1998-02-02'
A partir do MySQL 4.1.1, a segunda sintaxe é permitida,
onde expr
é uma expresão date ou
datetime e dias
é o número de dias a
ser adicionado a expr
.
mysql> SELECT ADDDATE('1998-01-02', 31);
-> '1998-02-02'
ADDTIME(expr,expr2)
ADDTIME()
adiciona
expr2
a expr
e retorna
o resultado. expr
é uma expressão date
ou datetime, e expr2
é uma expressão
time.
mysql>SELECT ADDTIME("1997-12-31 23:59:59.999999", "1 1:1:1.000002");
-> '1998-01-02 01:01:01.000001' mysql>SELECT ADDTIME("01:00:00.999999", "02:00:00.999998");
-> '03:00:01.999997'
ADDTIME()
foi adicionado no MySQL 4.1.1.
EXTRACT(tipo FROM data)
A função EXTRACT()
usa o mesmo tipo de
intervalo especificado como DATE_ADD()
ou
DATE_SUB()
, mas extrai partes da da data
em vez de realizar aritimética de data.
mysql>SELECT EXTRACT(YEAR FROM "1999-07-02");
-> 1999 mysql>SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
-> 199907 mysql>SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
-> 20102 mysql>SELECT EXTRACT(MICROSECOND FROM "2003-01-02 10:30:00.00123");
-> 123
DATEDIFF(expr,expr2)
,
TIMEDIFF(expr,expr2)
DATEDIFF()
retorna o número de dias
entre a data inicial expr
e a data final
expr2
. expr
e
expr2
são expressões de datas ou data e
hora. Apenas a parte da data dos valores sã usados no
cálculo.
TIMEDIFF()
retorna o tempo entre a hora
inicial expr
e a hora final
expr2
. expr
e
expr2
são expressões de hora ou data e
hora, mas ambas devem ser do mesmo tipo.
mysql>SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
-> 1 mysql>SELECT DATEDIFF('1997-11-31 23:59:59','1997-12-31');
-> -30 mysql>SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');
-> '-00:00:00.000001' mysql>SELECT TIMEDIFF('1997-12-31 23:59:59.000001','1997-12-30 01:01:01.000002');
-> '46:58:57.999999'
DATEDIFF()
e
TIMEDIFF()
foram adicionados no MySQL
4.1.1.
TO_DAYS(data)
Dada uma data data
, retorna o número do
dia (o número de dias desde o ano 0);
mysql>SELECT TO_DAYS(950501);
-> 728779 mysql>SELECT TO_DAYS('1997-10-07');
-> 729669
TO_DAYS()
não pode ser usado com valores
que orecedem o advento do calendario Gregoriano (1582),
porque ele não leva em conta os dias perdidos quando o
calendário foi mudado.
FROM_DAYS(N)
Dado um número de dia N
, retorna um
valor DATE
:
mysql> SELECT FROM_DAYS(729669);
-> '1997-10-07'
FROM_DAYS()
não pode ser usado com
valores que orecedem o advento do calendario Gregoriano
(1582), porque ele não leva em conta os dias perdidos
quando o calendário foi mudado.
DATE_FORMAT(data,formato)
Formata o valor de data
de acordo com a
string formato
string. Os seguintes
identificadores podem ser utilizados na string
formato
:
Specifier | Description |
%M | Nome do mês (January ..December ) |
%W | Nome da semana (Sunday ..Saturday ) |
%D | Dia do mês com sufixo Inglês (0th ,
1st , 2nd ,
3rd , etc.) |
%Y | Ano, numerico, 4 digitos |
%y | Ano, numerico, 2 digitos |
%X | Ano para a semana onde o Domingo é o primeiro dia da semana, numerico,
4 digitos; usado com %V |
%x | Ano para a semana onde a segunda é o primeiro dia da semana, numerico,
4 digitos; usado com %v |
%a | Nome da semana abreviado
(Sun ..Sat ) |
%d | Dia do mês, numerico (00 ..31 ) |
%e | Dia do mês, numerico (0 ..31 ) |
%m | Mês, numerico (00 ..12 ) |
%c | Mês, numerico (0 ..12 ) |
%b | Nome do mês abreviado (Jan ..Dec ) |
%j | Dia do ano (001 ..366 ) |
%H | Hora (00 ..23 ) |
%k | Hora (0 ..23 ) |
%h | Hora (01 ..12 ) |
%I | Hora (01 ..12 ) |
%l | Hora (1 ..12 ) |
%i | Minutos, numerico (00 ..59 ) |
%r | Tempo, 12-horas (hh:mm:ss seguido por
AM ou PM ) |
%T | Tempo, 24-horas (hh:mm:ss ) |
%S | Segundos (00 ..59 ) |
%s | Segundos (00 ..59 ) |
%f | Microsegundos (000000 ..999999 ) |
%p | AM ou PM |
%w | Dia da semana
(0 =Domingo..6 =Sabado) |
%U | Semana(00 ..53 ), onde o Domingo é
o primeiro dia da semana. |
%u | Semana(00 ..53 ), onde a Segunda é
o primeiro dia da semana. |
%V | Semana(01 ..53 ), onde o Domingo é
o primeiro dia da semana; usado com
%X |
%v | Semana(01 ..53 ), onde a Segunda é
o primeiro dia da semana; usado com
%x |
%% | Um literal ‘% ’. |
Todos os outros caracteres são apenas copiados para o resultado, sem interpretação.
O especificador dr formato %f
está
disponível a partir do MySQL 4.1.1.
Como na versão 3.23 do MySQL, o caracter
‘%
’ é exigido antes dos
caracteres de especificação de formato. Em versões
anteriores do MySQL ‘%
’ era
opcional.
A razão para a faixa de valores do mês e do dia começarem
com zero é que o MySQL permite datas incompletas tais como
'2004-00-00'
serem armazenadas no MySQL
3.23.
mysql>SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
-> 'Saturday October 1997' mysql>SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00' mysql>SELECT DATE_FORMAT('1997-10-04 22:23:00',
'%D %y %a %d %m %b %j'); -> '4th 97 Sat 04 10 Oct 277' mysql>SELECT DATE_FORMAT('1997-10-04 22:23:00',
'%H %k %I %r %T %S %w'); -> '22 22 10 10:23:00 PM 22:23:00 00 6' mysql>SELECT DATE_FORMAT('1999-01-01', '%X %V');
-> '1998 52'
STR_TO_DATE(str,format)
Esta é a função reversa da função
DATE_FORMAT()
. Ela pega uma string
str
, e um formato
format
, e retorna uma valor DATETIME.
Os valores date, time, ou datetime contidos em
str
devem ser dados no formato indicado
por format
. Para o especificadores que
podem ser usados em format
, veja a tabela
na descrição da função DATE_FORMAT()
.
Todos os outros caracteres serão apenas exibidos, não
sendo interpretados. Se str
contém um
valor date, time, ou datetime ilegal,
STR_TO_DATE()
retorna
NULL
.
mysql>SELECT STR_TO_DATE('03.10.2003 09.20', '%d.%m.%Y %H.%i')
-> 2003-10-03 09:20:00 mysql>SELECT STR_TO_DATE('10rap', '%crap')
-> 0000-10-00 00:00:00 mysql>SELECT STR_TO_DATE('2003-15-10 00:00:00', '%Y-%m-%d %H:%i:%s')
-> NULL
STR_TO_DATE()
está disponível a partir
do MySQL 4.1.1.
GET_FORMAT(DATE | TIME | TIMESTAMP, 'EUR' | 'USA' |
'JIS' | 'ISO' | 'INTERNAL')
Retorna uma string de formato. Esta função é útil
combinado com as funções DATE_FORMAT()
e STR_TO_DATE()
, e quando configurarmos
as variáveis do servidor DATE_FORMAT
,
TIME_FORMAT
e
DATETIME_FORMAT
. Os três valores
possíveis para o primeiro argumento e os cinco valores
possíveis para o segundo argumento resultam em 15 strings
de formato possíveis (para o especificador usado, veja a
tabela na descrição da função
DATE_FORMAT()
):
Chamada da Função | Resultado |
GET_FORMAT(DATE,'USA') | '%m.%d.%Y' |
GET_FORMAT(DATE,'JIS') | '%Y-%m-%d' |
GET_FORMAT(DATE,'ISO') | '%Y-%m-%d' |
GET_FORMAT(DATE,'EUR') | '%d.%m.%Y' |
GET_FORMAT(DATE,'INTERNAL') | '%Y%m%d' |
GET_FORMAT(TIMESTAMP,'USA') | '%Y-%m-%d-%H.%i.%s' |
GET_FORMAT(TIMESTAMP,'JIS') | '%Y-%m-%d %H:%i:%s' |
GET_FORMAT(TIMESTAMP,'ISO') | '%Y-%m-%d %H:%i:%s' |
GET_FORMAT(TIMESTAMP,'EUR') | '%Y-%m-%d-%H.%i.%s' |
GET_FORMAT(TIMESTAMP,'INTERNAL') | '%Y%m%d%H%i%s' |
GET_FORMAT(TIME,'USA') | '%h:%i:%s %p' |
GET_FORMAT(TIME,'JIS') | '%H:%i:%s' |
GET_FORMAT(TIME,'ISO') | '%H:%i:%s' |
GET_FORMAT(TIME,'EUR') | '%H.%i.%S' |
GET_FORMAT(TIME,'INTERNAL') | '%H%i%s' |
Formato ISO é do ISO ISO 9075, não do ISO 8601.
mysql>SELECT DATE_FORMAT('2003-10-03', GET_FORMAT(DATE, 'EUR')
-> '03.10.2003' mysql>SELECT STR_TO_DATE('10.31.2003', GET_FORMAT(DATE, 'USA'))
-> 2003-10-31 mysql>SET DATE_FORMAT=GET_FORMAT(DATE, 'USA'); SELECT '2003-10-31';
-> 10-31-2003
GET_FORMAT()
está disponível a partir
do MySQL 4.1.1. Veja See Secção 5.5.6, “Sintaxe de SET
”.
SUBDATE(date,INTERVAL expr type)
,
SUBDATE(expr,days)
Quando chamado com a forma INTERVAL
do
segunto argumento, SUBDATE()
é um
sinonimo para DATE_SUB()
.
mysql>SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
->'1997-12-02'
mysql>SELECT SUBDATE('1998-01-02', INTERVAL 31 DAY);
->'1997-12-02'
A partir do MySQL 4.1.1, a segunda sintaxe é permitida,
onde expr
é uma expressão date ou
datetime e days
é o número de dias a
ser subtraído de expr
.
mysql> SELECT SUBDATE('1998-01-02 12:00:00', 31);
-> '1997-12-02 12:00:00'
SUBTIME(expr,expr2)
SUBTIME()
subtrai
expr2
de expr
e
retorna o resultado. expr
é uma
expressão date ou datetime, e expr2
é
uma expressão time.
mysql>SELECT SUBTIME("1997-12-31 23:59:59.999999", "1 1:1:1.000002");
-> '1997-12-30 22:58:58.999997' mysql>SELECT SUBTIME("01:00:00.999999", "02:00:00.999998");
-> '-00:59:59.999999'
SUBTIME()
foi adicionado no MySQL 4.1.1.
TIME_FORMAT(hora,formato)
É usado como a função DATE_FORMAT()
acima, mas a string de formato
pode
conter apenas os especificadores de formato que tratam de
horas, minutos e segundos. Outros especificadores produzem
um valor NULL
ou 0
.
Se o valor time
contém uma hora que é
maior que 23
, os especificadores de
formato de hora %H
e
%k
produzem um valor maior que a faixa
como de 0..23
. O outro especificador do
formato de hora produz o valor da hora módulo 12:
mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
-> '100 100 04 04 4'
LAST_DAY(data)
Pega um valor date ou datetime e retorna o valor
correspondente para o último dia do mês. Retorna
NULL
se o argumento é invalido.
mysql>SELECT LAST_DAY('2003-02-05'), LAST_DAY('2004-02-05');
-> '2003-02-28', '2004-02-29' mysql>SELECT LAST_DAY('2004-01-01 01:01:01');
-> '2004-01-31' mysql>SELECT LAST_DAY('2003-03-32');
-> NULL
LAST_DAY()
está disponível a partir do
MySQL 4.1.1.
MAKEDATE(ano,diadoano)
Retorna uma data, dado os valores da ano e dia do ano.
diadoano
deve ser maior que 0 ou o
resultado será NULL
.
mysql>SELECT MAKEDATE(2001,31), MAKEDATE(2001,32);
-> '2001-01-31', '2001-02-01' mysql>SELECT MAKEDATE(2001,365), MAKEDATE(2004,365);
-> '2001-12-31', '2004-12-30' mysql>SELECT MAKEDATE(2001,0);
-> NULL
MAKEDATE()
está disponível a partir do
MySQL 4.1.1.
MAKETIME(hora,minuto,segundo)
Retorna um valor time calculado a partir dos argmentos
hora
, minuto
e
segundo
.
mysql> SELECT MAKETIME(12,15,30);
-> '12:15:30'
MAKETIME()
está disponível a partir do
MySQL 4.1.1.
CURDATE()
,
CURRENT_DATE
,
CURRENT_DATE()
Retorna a data atual como um valor no formato
'YYYY-MM-DD'
ou
YYYYMMDD
, dependendo se a função é
usada num contexto numérico ou de string.
mysql>SELECT CURDATE();
-> '1997-12-15' mysql>SELECT CURDATE() + 0;
-> 19971215
CURTIME()
,
CURRENT_TIME
,
CURRENT_TIME()
Retorna a hora atual como um valor no formato
'HH:MM:SS'
ou HHMMSS
,
dependo se a função é usada em um contexto numérico ou
como string:
mysql>SELECT CURTIME();
-> '23:50:26' mysql>SELECT CURTIME() + 0;
-> 235026
NOW()
, SYSDATE()
,
CURRENT_TIMESTAMP
,
CURRENT_TIMESTAMP()
,
LOCALTIME
,
LOCALTIME()
,
LOCALTIMESTAMP
,
LOCALTIMESTAMP()
Retorna a data e hora atual como um valor no formato
'YYYY-MM-DD HH:MM:SS'
ou
YYYYMMDDHHMMSS
, dependendo se a função
é utilizada num contexto numérico ou de string.
mysql>SELECT NOW();
-> '1997-12-15 23:50:26' mysql>SELECT NOW() + 0;
-> 19971215235026
UNIX_TIMESTAMP()
,
UNIX_TIMESTAMP(data)
Se chamado sem argumento, retorna um tipo timestamp do Unix
(segundos desde '1970-01-01 00:00:00'
GMT) como um inteiro sem sinal. Se
UNIX_TIMESTAMP()
é chamada com um
argumento data
, é retornado o valor do
argumento como segundo desde '1970-01-01
00:00:00'
GMT. data
pode ser um
string DATE
, uma string
DATETIME
, um
TIMESTAMP
, ou um número no formato
YYMMDD
ou YYYYMMDD
na
hora local:
mysql>SELECT UNIX_TIMESTAMP();
-> 882226357 mysql>SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
-> 875996580
Qaundo UNIX_TIMESTAMP
é usado em uma
coluna TIMESTAMP
, a função retorna o
valor timestamp interno diretamente, sem nenhuma conversão
``string-para-unix-timestamp'' implicita. Se você passar
uma data fora da faixa para
UNIX_TIMESTAMP()
, a função irá
retornar 0, mas por favor note que só verificações
básicas são realizadas. (ano 1970-2037, mês 01-12, dia
01-31).
Se você subtrair colunas
UNIX_TIMESTAMP()
, você pode querer mudar
o resultado para inteiro com sinal. See
Secção 6.3.5, “Funções de Conversão”.
FROM_UNIXTIME(unix_timestamp)
,
FROM_UNIXTIME(unix_timestamp,format)
Retorna a representação do argumento
unix_timestamp
como um valor no formato
'YYYY-MM-DD HH:MM:SS'
ou
YYYYMMDDHHMMSS
, dependendo de do contexto
em que a funçõ é utilizada:
mysql>SELECT FROM_UNIXTIME(875996580);
-> '1997-10-04 22:23:00' mysql>SELECT FROM_UNIXTIME(875996580) + 0;
-> 19971004222300
Se o formato
é dado o resultado é
formatado de acordo com a string formato
.
formato
pode conter os especificadores
listados acima para a função
DATE_FORMAT()
mysql>SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
->'%Y %D %M %h:%i:%s %x');
->'2003 6th August 06:22:58 2003'
SEC_TO_TIME(seconds)
Retorna o argumento segundos
, convertido
em horas, minutos e segundos como um valor no formato
'HH:MM:SS'
ou HHMMSS
,
dependendo do contexto em que a função é utilizada:
mysql>SELECT SEC_TO_TIME(2378);
-> '00:39:38' mysql>SELECT SEC_TO_TIME(2378) + 0;
-> 3938
TIME_TO_SEC(time)
Retorna o argumento time
, convertido em
segundos:
mysql>SELECT TIME_TO_SEC('22:23:00');
-> 80580 mysql>SELECT TIME_TO_SEC('00:39:38');
-> 2378
UTC_DATE
, UTC_DATE()
Retorna a data UTC atual como um valor no formato
'YYYY-MM-DD'
ou
YYYYMMDD
, dependendo se a função é
usada emum contexto string ou numérico:
mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
-> '2003-08-14', 20030814
UTC_DATE()
está disponível a partir do
MySQL 4.1.1.
UTC_TIME
, UTC_TIME()
Retorna a hora UTC atual como um valor no formato
'HH:MM:SS'
ou HHMMSS
,
dependendo se a função é usada em um contexto string ou
numérico:
mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
-> '18:07:53', 180753
UTC_TIME()
está disponível a partir do
MySQL 4.1.1.
UTC_TIMESTAMP
,
UTC_TIMESTAMP()
Retorna a data e hora UTC atual como um valor no formato
'YYYY-MM-DD HH:MM:SS'
ou
YYYYMMDDHHMMSS
, dependendo se a função
é usada em um contexto string ou numérico:
mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
-> '2003-08-14 18:08:04', 20030814180804
UTC_TIMESTAMP()
está disponível a
partir do MySQL 4.1.1.
As funções CAST()
e
CONVERT()
devem ser usada para tomar um valor
de um tipo e produzir um valor de outro tipo. As suas sintaxes
são as seguintes:
CAST(expressão AS tipo) CONVERT(expressão,tipo) CONVERT(expr USING transcoding_name)
O valor tipo
pode ser um dos seguintes:
BINARY
CHAR
DATE
DATETIME
SIGNED {INTEGER}
TIME
UNSIGNED {INTEGER}
CAST()
e CONVERT()
estão
disponíveis a partir do MySQL 4.0.2. O tipo de conversão
CHAR
está disponível a partir do versão
4.0.6. A forma USING
de
CONVERT()
está disponível a partir da
versão 4.1.0.
CAST()
e CONVERT(... USING
...)
são da sintaxe SQL-99. A forma
não-USING
de CONVERT()
é
da sintaxe ODBC.
CAST()
é da sintaxe SQL-99 syntax e
CONVERT()
é da sintaxe ODBC.
As funções de conversão são principalmente úteis quando
você deseja criar uma coluna com um tipo específico em uma
CREATE ... SELECT
:
CREATE TABLE nova_tabela SELECT CAST('2000-01-01' AS DATE);
As funções também podem ser úteis para ordenar colunas
ENUM
na ordem lexicográfica. Normalmente a
ordenação das colunas ENUM
ocorrem usando
os valores numéricos internos. Converter os valores para
CHAR
resultam em uma ordenação
lexicográfica:
SELECT enum_col FROM tbl_name ORDER BY CAST(enum_col AS CHAR);
CAST(string AS BINARY)
é a mesma coisa que
BINARY string
. CAST(expr AS
CHAR)
trata a expressão como uma string com o
conjunto de caracteres padrão.
NOTA: No MysQL 4.0 o
CAST()
para DATE
,
DATETIME
ou TIME
só marca
a coluna para ser um tipo específico mas não altera o valor da
coluna.
No MySQL 4.1.0 o valor será convertido para a coluna correta quando for enviado para o usuário (este é um recurso de como o novo protocolo na versão 4.1 envia as informações de data para o cliente):
mysql> SELECT CAST(NOW() AS DATE);
-> 2003-05-26
Em versões futuras do MySQL (provavelmente 4.1.2 ou 5.0) iremos
corrigir o fato de que CAST
também altera o
resultado se você usá-lo como parte de uma expressão mais
complexa, como CONCAT("Data: ",CAST(NOW() AS
DATE))
.
Você não deve utilizar CAST()
para extrair
dados em formatos diferentes, mas sim para usar funções strins
como LEFT
ou EXTRACT()
.
See Secção 6.3.4, “Funções de Data e Hora”.
Para converter uma string para um valor numérico, normalmente não é necessário se fazer nada; apenas use a string como se fosse um número:
mysql> SELECT 1+'1';
-> 2
Se você usar um número em um contexto string, o número será
convertido automaticamente para uma string
BINARY
.
mysql> SELECT CONCAT("hello you ",2);
-> "hello you 2"
O MySQL suporta aritimético com valores de 64 bits com sinal e
sem sinal. Se você está usando operações numéricas (como
+
) e um dos operandos é unsigned
integer
(inteiro sem sinal), o resultado também será
sem sinal (unsigned). Você pode forçar o tipo usando os
operadores de conversão SIGNED
e
UNSIGNED
para converter a operação para um
inteiro de 64 bits com sinal e sem sinal, respectivamente.
mysql>SELECT CAST(1-2 AS UNSIGNED)
-> 18446744073709551615 mysql>SELECT CAST(CAST(1-2 AS UNSIGNED) AS SIGNED);
-> -1
Note que se um dos operandos for um valor de ponto flutuante o
resultado é um valor de ponto flutuante e não é afetado pela
regra acima. (Neste contexto DECIMAL()
é
considerado um valor de ponto flutuante).
mysql> SELECT CAST(1 AS UNSIGNED) -2.0;
-> -1.0
Se você estiver utilizando uma string em uma operação aritimética, ela é convertida para um número de ponto flutuante.
O tratamento de valores sem sinais foi mudado no MySQL 4.0 para
suportar valores BIGINT
apropriadamente. Se
você tiver algum código que deseja executar no MySQL 4.0 e
3.23 (casos em que você provavelmente não poderá usar a
função CAST()
), você pode utilizar o
seguinte truque para conseguir um resultado com sinal quando
subtraindo duas colunas do tipo unsigned integer (inteiro sem
sinal):
SELECT (coluna_sem_sinal_1+0.0)-(coluna_sem_sinal_2+0.0);
A idéia é que as colunas sejam convertidas para valores de ponto flutuante antes da subtração ocorrer.
Se você tiver algum problema com colunas
UNSIGNED
no seu aplicação MySQL antiga ao
portar para o MySQL 4.0, você pode usar a opção
--sql-mode=NO_UNSIGNED_SUBTRACTION
ao iniciar
mysqld
. Note, no entanto, que enquanto você
utilizar esta opção, não será possível conseguir um uso
efetivo do tipo de coluna BIGINT UNSIGNED
.
CONVERT()
com USING
é
usado para converter dados entre diferentes conjuntos de
caracteres. No MySQL, nomes trancodificados são o mesmo que o
nome do conjunto de caracteres correspondentes. Por exemplo,
esta instrução converte a string 'abc'
no
conjunto de caracteres padrão do servidor na string
correspondente no conjunto de caracteres
utf8
:
SELECT CONVERT('abc' USING utf8);
O MySQL utiliza aritimética BIGINT
(64bits) para operações binárias, assim estes operadores
possuem uma faixa máxima de 64 bits.
|
Operador binário OR
mysql> SELECT 29 | 15;
-> 31
O resultado é um inteiro sem sinal de 64 bits.
&
Operado binário AND
mysql> SELECT 29 & 15;
-> 13
O resultado é um inteiro sem sinal de 64 bits.
^
Operado binário XOR
mysql>SELECT 1 ^ 1;
-> 0 mysql>SELECT 1 ^ 0;
-> 1 mysql>SELECT 11 ^ 3;
-> 8
O resultado é um inteiro sem sinal de 64 bits.
XOR
foi adicionado na versão 4.0.2.
<<
Desloca um número BIGINT
(muito
grande) a esquerda:
mysql> SELECT 1 << 2;
-> 4
O resultado é um inteiro sem sinal de 64 bits.
>>
Desloca um número BIGINT
(muito
grande) a direita:
mysql> SELECT 4 >> 2;
-> 1
O resultado é um inteiro sem sinal de 64 bits.
~
Inverte todos os bits:
mysql> SELECT 5 & ~1;
-> 4
O resultado é um inteiro sem sinal de 64 bits.
BIT_COUNT(N)
Retorna o número de bits que são passados no argumento
N
:
mysql> SELECT BIT_COUNT(29);
-> 4
DATABASE()
Retorna o nome do banco de dados atual:
mysql> SELECT DATABASE();
-> 'test'
Se nenhum banco de dados estiver selecionado,
DATABASE()
retorna
NULL
a partir do MySQL 4.1.1, e uma
string vazia em versões anteriores.
USER()
,
SYSTEM_USER()
,
SESSION_USER()
Retorna o nome do usuário MySQL e nome de máquina atual:
mysql> SELECT USER();
-> 'davida@localhost'
O valor indica o nome do usuário que você especificou ao conectar ao servidor e a máquina cliente da qual você se conectou. (Antes do MySQL versão 3.22.11, o valor da função não inclui o nome da máquina cliente.)
Você pode extrair apenas a parte do nome do usuário, desconsiderando se o valor inclui a parte do nome de máquina, desta forma:
mysql> SELECT SUBSTRING_INDEX(USER(),"@",1);
-> 'davida'
CURRENT_USER()
Retorna o nome do usuário e o nome de máquina com os
quais a sessão atual foi autenticada. Este valor
corresponde a conta que é usada para acessar seu
privilégio de acessos. Ela pode ser diferente do valor de
USER()
.
mysql>SELECT USER();
-> 'davida@localhost' mysql>SELECT * FROM mysql.user;
-> ERROR 1044: Access denied for user: '@localhost' to database 'mysql' mysql>SELECT CURRENT_USER();
-> '@localhost'
O exemplo ilustra que embora o cliente tenha especificado
um nome de usuário davida
(como
indicado pelo valor da função
USER()
), o servidor autenticou o
cliente usando uma conta de usuário anônimo (como visto
pela parte vazia no nome de usuário do valor
CURRENT_USER()
). Um modos de isto
ocorrer é que não haja uma conta listada na tabela de
permissões para davida
.
PASSWORD(str)
,
OLD_PASSWORD(str)
Calcula a senha a partir de senha str
em texto puro. Está é a função que é utilizada para
criptografar a senha do MySQL para armazenamento na coluna
Password
da tabela de permissões
user
mysql> SELECT PASSWORD('badpwd');
-> '7f84554057dd964b'
A criptografia de PASSWORD()
não e
reversível.
PASSWORD()
não realiza a criptografia
da senha da mesa maneira que as senhas Unix são
criptografadas. Veja ENCRYPT()
.
Note: A função
PASSWORD()
é usada pelo sistema de
autentificação no servidor MySQL, você
NÃO
deve uitlizá-las em suas
próprias aplicações. Para este propósito utilize
MD5()
ou SHA1()
.
Veja também RFC-2195
para maiores
informações sobre o tratamento de senha e autenticação
segura em suas aplicações.
ENCRYPT(str[,salt])
Criptografa str
utilizando a chamada de
sistema crypt()
do Unix. O argumento
salt
deve ser uma string com dois
caracteres. (Na versão 3.22.16 do MySQL,
salt
deve ser maior que dois
caracteres.)
mysql> SELECT ENCRYPT("hello");
-> 'VxuFAJXVARROc'
ENCRYPT()
ignora tudo depois dos
primeiros 8 caracteres de str
, pelo
menos em alguns sistemas. Este comportamento é
determinado pela implementação da chamada de sistema
crypt()
.
Se crypt()
não estiver disponível no
seu sistema, ENCRYPT()
sempre retorna
NULL
. Devido a isto recomendamos que
você use MD5()
ou
SHA1()
em vez dos existentes em sua
plataforma.
ENCODE(str,senha_str)
Criptografa str
usando
senha_str
como a senha. Para
descriptografar o resultado, utilize
DECODE()
.
O resultado é uma string binária do mesmo tamanho de
str
. Se você deseja salvá-la em uma
coluna, use uma coluna do tipo BLOB
.
DECODE(cript_str,senha_str)
Descriptografa o string criptografada
cript_str
usando
senha_str
como a senha.
cript_str
deve ser uma string retornada
de ENCODE()
.
MD5(string)
Calcula um checksum MD5 de 128 bits para a string. O valor é retornado como um número hexadecimal de 32 digitos que pode, por exemplo, ser usado como uma chave hash:
mysql> SELECT MD5("testing");
-> 'ae2b1fca515949e5d54fb22b8ed95575'
Este é o "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
SHA1(string)
,
SHA(string)
Calcula um checksum SHA1 de 160 bit para a string, como
descrito no RFC 3174 (Algoritmo Hash de Segurança). O
valor é retornado como um número hexadecial de 40
digitos, or NULL
no caso do argumento
ser NULL
. Uma das possibilidades para
o uso desta função é a chave hash. Você também pode
usá-lo como uma função segura de criptografia para
armazenar senhas.
mysql> SELECT SHA1("abc");
-> 'a9993e364706816aba3e25717850c26c9cd0d89d'
SHA1()
foi adicionado na versão 4.0.2,
e pode ser considerada um equivalente ao
MD5()
com criptografia mais segura.
SHA()
é um sinônimo para
SHA1()
.
AES_ENCRYPT(string,string_chave)
,
AES_DECRYPT(string,string_chave)
Estas funções permitem criptografia/descriptografia de dados usando o algoritmo oficial AES (Padrão Avançado de Criptografia), antes conhecido como Rijndael. Criptgrafia com uma chave de 128 bits podem ser usadas, mas você pode extendê-la para 256 bits através da fonte. Nós escolhemos 128 bits porque é muito mais rápido e é bastante seguro.
Os argumentos de entrada podem ser de qualquer tamanho. Se
ambos argumentos são NULL
, o resultado
desta função tam bém será NULL
.
Como o AES é um algorítimo de nível de bloco, padding é usado para codificar strings de tamanho ímpares e então a string resultante pode ser calculada como 16*(trunc(tamanho_string/16)+1).
Se AES_DECRYPT()
detectar dados
inválidos ou padding incorreto, ela retorna
NULL
. No entanto, é possível para o
AES_DECRYPT()
retornar um valor
não-NULL
(possivelmente lixo) se os
dados de entrada ou a chave eram inválidos
Você pode usar as funções AES para armazenar dados de forma criptografada modificando as suas consultas:
INSERT INTO t VALUES (1,AES_ENCRYPT('text','password'));
Você pode obter mais segurança não transferindo a chave em suas conexões a cada consulta, o que pode ser conseguido armazenando-o em varáveis do lado do servidor na hora das conexão.
SELECT @password:='my password'; INSERT INTO t VALUES (1,AES_ENCRYPT('text',@password));
AES_ENCRYPT()
e
AES_DECRYPT()
foram adicionados na
versão 4.0.2, e podem ser considerados a função de
criptografia mais segura atualmente disponível no MySQL.
DES_ENCRYPT(string_para_ciptografar [,
(numero_chave | chave_string) ] )
Criptografa a string com a chave dada utilizando o algortimo Triplo-DES.
Note que esta função só funciona se o MySQL tiver sido configurado com suporte a SSL. See Secção 4.4.10, “Usando Conexões Seguras”.
A chave de criptografia utilizada é escolhida da seguinte forma:
Argumento | Descrição |
Somente um argumento | A primeira chave de des-key-file é utilizada. |
Número da chave | A chave dada (0-9) de des-key-file é utilizada. |
string | A chave_string dada será utilizada para criptografar
string_para_criptografar . |
O string retornada será uma string binária onde o
primeiro caracter será CHAR(128 |
número_chave)
.
O 128 é adicionado para facilitar o reconhecimento da
chave de criptografia. Se você usar uma chave string,
numéro_chave
será 127.
Havendo erro, esta função retorna
NULL
.
O tamanho da string para o resultado será
novo_tamanho= tamanho_orig + (8-(tamanho_orig %
8))+1
.
O des-key-file
terá o seguinte
formato:
numero_chave chave_string_des numero_chave chave_string_des
Cada numero_chave
deve ser um núero na
faixa de 0 a 9. As linhas do arquivo podem estar em
qualquer ordem. chave_string_des
é a
string que será usada para criptografar a mensagem. Entre
o número e a chave deve haver pelo menos um espaço. A
primeira chave é a chave padrão que será utilizada se
não for especificada nenhuma chave como argumento para
DES_ENCRYPT()
Você pode dizer ao MySQL para ler novos valores de
arquivos de chave com o comando FLUSH
DES_KEY_FILE
. Isto exige o privilégio
Reload_priv
.
Um benefício de ter um conjunto de chaves padrões é que ele dá a aplicação um modo de verificar a existência de valores criptografados em colunas, sem dar ao usuário final o direito de descriptografar estes valores.
mysql> SELECT endereco_clientes FROM tabela_clientes WHERE
cartao_credito_criptografado = DES_ENCRYPT("numero_cartao_credito");
DES_DECRYPT(string_para_descriptografar [,
chave_string])
Derscritogra uma string criptografada com
DES_ENCRYPT()
.
Note que esta função só funciona se o MySQL tiver sido configurado com suporte SSL. See Secção 4.4.10, “Usando Conexões Seguras”.
Se nenhum argumento chave_string
for
dado, DES_DECRYPT()
examina o primeiro
byte da string criptografada para determinar o número de
chave DES que foi usado para criptografar a string
original, e então lê a chave de
des-key-file
para descriptografar a
mensagem. Para isto funcionar o usuário deve ter o
privilégio SUPER
.
Se você passar para esta função um argumento
chave_string
, aquela string é usada
como a chave para descriptografar a mensagem.
Se a string_para_descriptografar
não
se paracer com uma string criptografada, o MySQL
retornará a
string_para_descriptografar
dada.
Havendo erro, esta função retorna
NULL
.
COMPRESS(string_para_compactar)
Compacta uma string
mysql>SELECT LENGTH(COMPRESS(REPEAT("a",1000)));
-> 21 1 row in set (0.00 sec) mysql>SELECT LENGTH(COMPRESS(""));
-> 0 1 row in set (0.00 sec) mysql>SELECT LENGTH(COMPRESS("a"));
-> 13 1 row in set (0.00 sec) mysql>SELECT LENGTH(COMPRESS(REPEAT("a",16)));
-> 15 1 row in set (0.00 sec)
COMPRESS()
foi adicionado no MySQL
4.1.1. Se exigido, o MySQL tem que ser compilado com uma
biblioteca de compactação como zlib
.
Senão , o valor de retorno é sempre
NULL
.
O conteúdo da string compactada é armazenada da seguinte forma:
Strings vazias são armazenadas como strings vazias
Strings que não estão vazias são armazenadas como
um string descompacatada de 4 byte de tamanho
(low-byte-first) seguida pela string compactada com
gzip. Se a string finaliza com espaço, adicionamos
um ‘.
’ extra para
evitar problemas com o corte do espaço final o
resultado deve ser armazenado em um campo
CHAR
ou
VARCHAR
. O uso de
CHAR
ou
VARCHAR
para armazenar strings
compactadas não é recomendado. É melhor usar uma
coluna BLOB
.
UNCOMPRESS(string_para_descompactar)
Descompacta uma string compactado pela função
COMPRESS()
mysql> select UNCOMPRESS(COMPRESS("any string"));
-> 'any string'
1 row in set (0.00 sec)
UNCOMPRESS()
foi adicionado no MySQL
4.1.1 Se exigido, o MySQL tem que ser compilado com uma
biblioteca de compactação como zlib
.
Senão , o valor de retorno é sempre
NULL
.
UNCOMPRESSED_LENGTH(string_compactada)
Retorna o tamanho da string compactada antes da compactação
mysql> select UNCOMPRESSED_LENGTH(COMPRESS(REPEAT("a",30)));
-> 30
1 row in set (0.00 sec)
UNCOMPRESSED_LENGTH()
foi adicionado no
MySQL 4.1.1
LAST_INSERT_ID([expr])
Retorna o último valor gerado automaticamente que tenha
sido inserido em um coluna
AUTO_INCREMENT
.
mysql> SELECT LAST_INSERT_ID();
-> 195
O último ID que foi gerado e mantido no servidor em uma
base por conexão. Isto significa que o valor que a
função retona para um dado cliente é o valor
AUTO_INCREMENT
gerado mais recentemente
por aquele cliente. O valor não pode ser afetado pelos
outros clientes, mesmo se eles gerarem um valor
AUTO_INCREMENT
deles mesmos. Este
comportamento assegura que você pode recuperar seu
próprio ID sem se preocupar com a atividade de outros
clientes e sem precisar de locks ou transações.
O valor de LAST_INSERT_ID()
não é
alterado se você atualizar uma coluna
AUTO_INCREMENT
de uma linha com um
valor não-mágico (Isto é, um valor que não seja
NULL
e nem 0
).
Se você inserir muitos registros ao mesmo tempo com uma
instrução insert, LAST_INSERT_ID()
retorna o valor da primeira linha inserida. A razão para
isto é tornar possível reproduzir facilmente a mesma
intrução INSERT
em algum outro
servidor.
Se expr
é dado com um argumento para
LAST_INSERT_ID()
, então o valor do
argumento é retornado pela função e é configurado como
o próximo valor para ser retornado pela
LAST_INSERT_ID()
. Isto pode ser útil
para simular sequências:
Primeiro crie a tabela:
mysql>CREATE TABLE sequencia (id INT NOT NULL);
mysql>INSERT INTO sequencia VALUES (0);
Então a tabela pode ser usada para gerar sequência de números como estes:
mysql> UPDATE sequencia SET id=LAST_INSERT_ID(id+1);
Você pode gerar sequências sem chamar
LAST_INSERT_ID()
, mas a utilidade de se
usar a função deste modo é que o valor ID é mantido no
servidor como o último valor gerado automaticamente
(seguro para multi-usurário). Você pode recuperar a nova
ID como você leria qualquer valor
AUTO_INCREMENT
normal no MySQL. Por
exemplo, LAST_INSERT_ID()
(sem um
argmento) retornará a nova ID. A função
mysql_insert_id()
da API C também pode
ser usada para obter o valor.
Note que como mysql_insert_id()
só é
atualizado depois de instruções
INSERT
e UPDATE
,
você não pode utilizar a função da API C para
recuperar o valor para
LAST_INSERT_ID(expr)
depois de executar
outra instrução SQL como SELECT
ou
SET
. See
Secção 12.1.3.32, “mysql_insert_id()
”.
FORMAT(X,D)
Formata o número X
com um format como
'#,###,###.##'
, arredondado para
D
casas decimais, e retorna o resultado
como uma string. Se D
é
0
, o resultado não terá nehum ponto
decimal ou parte fracionária:
mysql>SELECT FORMAT(12332.123456, 4);
-> '12,332.1235' mysql>SELECT FORMAT(12332.1,4);
-> '12,332.1000' mysql>SELECT FORMAT(12332.2,0);
-> '12,332'
VERSION()
Retorna uma string indicando a versão do servidro MySQL:
mysql> SELECT VERSION();
-> '3.23.13-log'
Note que se seu versão finalizar com
-log
, significa que o log está
habilitado.
CONNECTION_ID()
Retorna a identificação (ID da thread) desta conexão. Cada conexão tem seu próprio ID único:
mysql> SELECT CONNECTION_ID();
-> 23786
GET_LOCK(str,temo_limite)
Tenta conseguir uma trava com o nome dado pela string
str
, com um tempo limite de
timeout
segundos. Retorna
1
se o bloqueio foi obtido com sucesso,
0
se o tempo esgotou (por exemplo,
porque outro cliente ja bloqueou o nome), ou
NULL
se uma erro ocorreu (tal como
estouro de memória ou a threado tiver sido finalizada com
mysqladmin kill
). Uma trava é liberada
quando você executa RELEASE_LOCK()
,
executa uma nova GET_LOCK()
, ou a
thread termina. (tanto de forma normal quanto anormal)
Esta função pode ser usada para implementar bloqueio de
aplicação ou para simular registros travados. Nomes são
bloqueados em uma base ampla do servidor. Se um nome foi
bloqueado por um cliente, GET_LOCK()
trava qualquer pedido de bloqueio de outro cliente com o
mesmo nome. Isto permite que clientes que concordam com um
dado nome da trava possam usar a string para realizar
travamento de consultas cooperativas:
mysql>SELECT GET_LOCK("lock1",10);
-> 1 mysql>SELECT IS_FREE_LOCK("lock2");
-> 1 mysql>SELECT GET_LOCK("lock2",10);
-> 1 mysql>SELECT RELEASE_LOCK("lock2");
-> 1 mysql>SELECT RELEASE_LOCK("lock1");
-> NULL
Note que a segunda chamada de
RELEASE_LOCK()
retorna
NULL
porque a trava
"lock1"
foi liberada automaticamente
pela segunda chamada GET_LOCK()
.
RELEASE_LOCK(str)
Libera a trava nomeada pela string str
que foi obtida com GET_LOCK()
. Retorna
1
se a trava foi liberada,
0
se a trava não foi bloquada pela
thread (caso onde a trava não é liberada), e
NULL
se o nome da trava não existe. (A
trava nunca exitirá se ela nunca for obtida pela chamada
de GET_LOCK()
ou se ela ja tiver sido
liberada).
A instrução DO
é conveniente para
ser utilizada com RELEASE_LOCK()
. See
Secção 6.4.10, “Sintaxe DO
”.
IS_FREE_LOCK(str)
Verifica se a trava chamada str
está
livre para ser utilizada (ex. não está bloqueada).
Retorna 1
se a trava está liver
(ninguém a esta usando), 0
se a trava
está em uso, e NULL
caso ocorra erro
(como argumentos incorretos).
BENCHMARK(cont,expr)
A função BENCHMARK()
executa a
expressão expr
repetidamente
cont
vezes. Ela pode ser usada para
medir a velocidade em que o MySQL processa a expressão. O
valor resultante é sempre 0
. A
intenção é usá-la no clientei
mysql
, relatando o tempo de execução
da consulta:
mysql> SELECT BENCHMARK(1000000,ENCODE("hello","goodbye"));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE("hello","goodbye")) |
+----------------------------------------------+
| 0 |
+----------------------------------------------+
1 row in set (4.74 sec)
O tempo relatado é o tempo decorrido no cliente, não o
tempo de CPU no servidor. Pode ser aconselhável executar
BENCHMARK()
diversas vezes e
interpretar o resultado cosiderado o peso da carga da
maquina servidora.
INET_NTOA(expr)
Dado um endereço numérico de rede (4 ou 8 bytes), retorna a representacão no formato com pontos do endereço como uma string:
mysql> SELECT INET_NTOA(3520061480);
-> "209.207.224.40"
INET_ATON(expr)
Dada a represenação com pontos de um endereço de rede como uma string, retorna um inteiro que representa o valor numérico deste endereço. Endereços podem ter 4 ou 8 bytes de endereçamento:
mysql> SELECT INET_ATON("209.207.224.40");
-> 3520061480
O número gerado é sempre na ordem de bytes da rede; por
exemplo o número acima é calculado como
209*256^3 + 207*256^2 + 224*256 +40
.
MASTER_POS_WAIT(nome_log, log_pos [,
tempo_limite])
Envia blocos o slave alcançar (ex.: ter lido e aplicado
todas as atualizações) a posição específica no log
master. Se a informação master não está inicializada,
ou se os argumentos estão incorretos, retorna
NULL
. Se o slave não está em
execução, enviará blocos e irá esperar até que ele
seja iniciado e vá para (ou passe por) a posição
especificada. Se o slave já passou pela posição
especificada, retorna imediatamente.
Se tempo_limite
(novo na versão
4.0.10) é especificado, irá esperar até que
tempo_limite
segundos tenham se
passado. tempo_limite
deve ser maior
que 0; zero ou um tempo_limite
negativo
significa sem tempo_limite. O valor de retorno é o
número de eventos de log que ele tem que esperar para
obter a posição especificada, NULL
no
caso de erro, ou -1
se o tempo_limite
tiver sido excedido.
O comando é útil para controle de sincronização mo master/slave.
FOUND_ROWS()
Uma instrução SELECT
pode incluir uma
cláusula LIMIT
para restringir o
número de linhas que o servidor retorna para um cliente.
Em alguns casos, é desejável saber quantas linhas a
instrução teria retornado sem o
LIMIT
, mas sem executar a instrução
novamente. Para obter esta contagem de linhas, inclua uma
opção SQL_CALC_FOUND_ROWS
na
instrução SELECT
, então chame
FOUND_ROWS()
loga depois:
mysql>SELECT SQL_CALC_FOUND_ROWS * FROM nome_tabela
WHERE id > 100 LIMIT 10; mysql>SELECT FOUND_ROWS();
O segundo SELECT
irá retornar um
número indicando quantas linhas o primeiro
SELECT
teria retornado se ele fosse
escrito sem a cláusula LIMIT
. (Se o
instrução SELECT
anterior não inclui
a opção SQL_CALC_FOUND_ROWS
, então
FOUND_ROWS()
pode retornar um resultado
diferente quando LIMIT
é usado daquele
que não é usado).
Note que se você estiver usando SELECT
SQL_CALC_FOUND_ROWS ...
, o MySQL tem que
calcular quantos registros existem em todo o conjunto de
resultados. No entanto, isto é mais rápido que se você
não utilizar LIMIT
, já que o
resultado precisa ser enviado ao cliente.
SQL_CALC_FOUND_ROWS
e
FOUND_ROWS()
podem ser úteis em
situações em que você queira restringir o número de
registros que uma consulta retorna, mas também determinar
o número de linhas em todo o resultado sem executar a
consulta novamente. Um exemplo é um script web que
apresenta um display paginado contendo links para as
páginas que mostram outras seções de um resultado de
busca. Usar FOUND_ROWS()
lhe permite
determinar quantos outras páginas são necessárias para
o resto do resultado.
O uso de SQL_CALC_FOUND_ROWS
e
FOUND_ROWS()
é mais complexa para
consultas UNION
que para instruções
SELECT
simples, porque
LIMIT
pode ocorrer em vários lugares
em um UNION
. Ele pode ser aplicado a
instruções SELECT
individuais no
UNION
, ou globais ao resultado
UNION
como um todo.
A intenção de SQL_CALC_FOUND_ROWS
para UNION
é que ele deve retornar a
contagem das linhas que seriam retornadas sem um
LIMIT
global. As consições para uso
de SQL_CALC_FOUND_ROWS
com
UNION
são:
A palavra chave
SQL_CALC_FOUND_ROWS
deve aparecer
na primeira SELECT
do
UNION
.
O valor de FOUND_ROWS()
é exato
apenas se UNION ALL
for usado. Se
UNION
sem ALL
for usado, as duplicatas são removidas e o valor de
FOUND_ROWS()
é apenas
aproximado.
Se nenhum LIMIT
está presente no
UNION
,
SQL_CALC_FOUND_ROWS
é ignorado e
retorna o número de linhas na tabela temporária
que é criada para processar o
UNION
.
SQL_CALC_FOUND_ROWS
e
FOUND_ROWS()
estão disponíveis a
partir da versão 4.0.0 do MySQL.
Se você utiliza um função de agrupamento em uma instrução
que não contenha um cláusula GROUP BY
,
equivale a fazer um agrupamento com todos os registros.
COUNT(expr)
Retorna a quantidade de valores
não-NULL
nos registros recuperados por
uma instrucao SELECT
:
mysql>SELECT estudante.nome_estudente,COUNT(*)
->FROM estudante,curso
->WHERE estudante.id_estudante=curso.id_estudante
->GROUP BY nome_estudante;
COUNT(*)
difere um pouco ao retornar o
número de registros recuperados, se eles possuírem ou
não valores NULL
.
COUNT(*)
é otimizado para retornar
muito rápido se SELECT
recuoperar
registros de uma tabela, nenhuma outra coluna for
retornada, e não houver nenhuma cláusula
WHERE
. Por exemplo:
mysql> SELECT COUNT(*) FROM estudente;
Esta otimizacão se aplica apenas a tabelas
MyISAM
e ISAM
,
porque uma contagem exata de registros é armazenada para
estes tipos de tabelas e podem ser acessadas muito
rapidamente. Para mecanismos de armazenamentos
transacionais (InnodB
,
BDB
), armazenar um contagem de
registros exatos é mais problemático porque múltiplas
transações podem estar ocorrendo, e cada uma pode afetar
a contagem.
COUNT(DISTINCT expr,[expr...])
Retorna a quantidade de regiastros com valores
não-NULL
diferentes:
mysql> SELECT COUNT(DISTINCT resultados) FROM estudente;
No MySQL você pode obter o número de combinação de
expressões distintas que não contém NULL fornecendo uma
lista de expressões. No SQL-99 você teria que concatenar
todas as expressão utilizando COUNT(DISTINCT
...)
.
AVG(expr)
Retorna o valor médio de expr
:
mysql>SELECT nome_estudante, AVG(nota_teste)
->FROM estudante
->GROUP BY nome_estudante;
MIN(expr)
,
MAX(expr)
Retorna o valor mínimo o u máximo de
expr
. MIN()
e
MAX()
poder usar uma string como
argumento; nestes casos eles retornam o a string de valor
mínimo ou máximo. See Secção 5.4.3, “Como o MySQL Utiliza Índices”.
mysql>SELECT nome_estudante, MIN(nota_teste), MAX(nota_teste)
->FROM estudante
->GROUP BY nome_estudante;
Em MIN()
, MAX()
e
outras funções de agrupamento o MySQL, atualmente,
compara colunas ENUM
e
SET
pelo seu valor string em vez de
fazê-lo pela sua posição relativa de string no
conjunto. Isto será retificado.
SUM(expr)
Retorna a soma de expr
. Note que se o
conjunto de retorno não possuir registros ele retornará
NULL!
GROUP_CONCAT(expr)
Sintaxe completa:
GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY {inteiro_sem_sinal | nome_coluna | formula} [ASC | DESC] [,col ...]] [SEPARATOR valor_str])
Esta função foi adicionada na versão 4.1 do MySQL. Ele retorna a string resultante contendo valores de um grupo:
mysql>SELECT nome_estudante,
->GROUP_CONCAT(note_teste)
->FROM estudante
->GROUP BY nome_estudante;
ou mysql>SELECT nome_estudante,
->GROUP_CONCAT(DISTINCT nota_teste
->ORDER BY nota_teste DESC SEPARATOR " ")
->FROM estudante
->GROUP BY nome_estudante;
No MySQL você pode obter valores de combinações de
expressões concatenados. Você pode eliminar valores
duplicados utilizando DISTINCT
. Se
você quiser ordenar valores no resultado você deve
utilizar a cláusula ORDER BY
. Para
ordenar inversamente, adicione a palavra chave
DESC
(descendente) ao nome da coluna
que você está ordenando na cláusula ORDER
BY
. O padrão é a ordem crescente; pode-se
também especificála explicitamente usando a palavra
chave ASC
. SEPARATOR
é o valor string que deve ser inserido entre os valores
no resultado. O padrão é um virgula
('","
'). Você pode remover o separador
especificando SEPARATOR ""
.
Você pode definir um tamanho máximo permitido com a
variável group_concat_max_len
em sua
configuração. A sintaxe para se fazer isto em tempo de
execução é:
SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;
Se um tamanho máximo tiver sido atribuido, o resultado é truncado no seu tamanho máximo.
A função GROUP_CONCAT()
é uma
implementação aprimorada da função básica
LIST()
suportada pelo Sybase SQL
Anywhere. GROUP_CONCAT()
é compatível
com a funcionalidade extrwemamente limitada de de
LIST()
, se utilizada em apenas uma
coluna e nenhuma outra opção é especificada.
LIST()
não tem uma ordem de
classificação padrão.
VARIANCE(expr)
Retorna a variância padrão de expr
(considerando linha como toda a população, não com uma
amostra; assim ele tem o número de linhas como
denominador). Esta é uma extensão do SQL-99 (disponível
somente a partir da versão 4.1).
STD(expr)
,
STDDEV(expr)
Retorna o desvio padrão de expr
(a
raiz quadrada de VARIANCE()
). Esta é
uma extensão do SQL-99. O formato
STDDEV()
desta função é fornecida
para compatibilidade com Oracle.
BIT_OR(expr)
Retorna o resultado da operação binária
OR
de todos os bits em
expr
. O calcululo é relizado com
precisão de 64 bits (BIGINT
).
A função retortna 0 se não houver registros coincidentes.
BIT_XOR(expr)
Retorna o bitwise XOR
de todos os bits
em expr
. O calculo é relizado com
precisão de 64-bits (BIGINT
).
A função retorna 0 se não houver linhas coincidentes.
Esta função está disponível a partir do MySQL 4.1.1.
BIT_AND(expr)
Retorna o resultado da operação binária
AND
de todos os bits em
expr
. O calcululo é relizado com
precisão de 64 bits (BIGINT
).
A função retortna 1 se não houver registros coincidentes.
No MySQL 4.1.1, a cláusula GROUP BY
permite um modificador WITH ROLLUP
que faz
com que uma linha extra seja adicionada à saida resumo. Estas
linhas representam operações de resumo de nível mais alto
(ou super agregadas). Assim, o ROLLUP
permite que você responda questões em multiplos níveis de
análise com uma única consulta. Ele pode ser usado, por
exemplo, para fornecer suporte para operações OLAP (Online
Analytical Processing - Processamento Analítico OnLine).
Como ilustração, suponha que uma tabela chamada
sales
tenha as colunas
year
, country
,
product
e profit
para
registrar as vendas lucrativas:
CREATE TABLE sales ( year INT NOT NULL, country VARCHAR(20) NOT NULL, product VARCHAR(32) NOT NULL, profit INT );
O conteúdo da tabela pode ser resumido pode ano com um
simples GROUP BY
como este:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 | 4525 |
| 2001 | 3010 |
+------+-------------+
Esta saída mostra o lucro total para cada ano, mas se você também quiser determinar o lucro total somado em todos os anos, você deve adicionar os valores adicionais ou executar uma consulta adicional.
Ou você pode usar o ROLLUP
, que fornece os
dois níveis de análise com uma única consulta. Adicionando
um modificador WITH ROLLUP
a cláusula
GROUP BY
faz com que a consulta produza
outra linha que mostra o total geral de todos os anos:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 | 4525 |
| 2001 | 3010 |
| NULL | 7535 |
+------+-------------+
A linha de total super-agrupada é identificada pelo valor
NULL
na coluna year
.
ROLLUP
tem um efeito mais complexo quando
há múltiplas colunas GROUP BY
. Neste
caso, cada vez que houver um ``break'' (alteração no valor)
em qualquer agrupamento, com exceção da última coluna, a
consulta produz um linha resumo super-agrupada extra.
Por exemplo, sem ROLLUP
, um resumo na
tabela sales
baseada no
year
, country
e
product
pode se parecer com isto:
mysql>SELECT year, country, product, SUM(profit)
->FROM sales
-> GROUP BY year, country, product; +------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | | 2000 | USA | Calculator | 75 | | 2000 | USA | Computer | 1500 | | 2001 | Finland | Phone | 10 | | 2001 | USA | Calculator | 50 | | 2001 | USA | Computer | 2700 | | 2001 | USA | TV | 250 | +------+---------+------------+-------------+
A saída indica os valores resumidos apenas no nível
year/country/product da análise. Quando
ROLLUP
é adicionado, a consulta produz
diversas linhas extras:
mysql>SELECT year, country, product, SUM(profit)
->FROM sales
->GROUP BY year, country, product WITH ROLLUP;
+------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | Finland | NULL | 1600 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | | 2000 | India | NULL | 1350 | | 2000 | USA | Calculator | 75 | | 2000 | USA | Computer | 1500 | | 2000 | USA | NULL | 1575 | | 2000 | NULL | NULL | 4525 | | 2001 | Finland | Phone | 10 | | 2001 | Finland | NULL | 10 | | 2001 | USA | Calculator | 50 | | 2001 | USA | Computer | 2700 | | 2001 | USA | TV | 250 | | 2001 | USA | NULL | 3000 | | 2001 | NULL | NULL | 3010 | | NULL | NULL | NULL | 7535 | +------+---------+------------+-------------+
Para esta consulta, adicionar ROLLUP
faz
com que a saída inclua uma informação resumida nos qualtro
níveis de análise, não só em um. Aqui está como
interpretar a saída ROLLUP
:
Seguindo cada conjunto de produtos para um dado ano e
país, um linha de resumo extra é produzida mostrando o
total para todos os produtos. Estas linhas têm a coluna
product
atribuída com
NULL
.
Seguindo cada conjunto de linhas para um dado ano, uma
l;inha resumo extra é produzida mostrando o total para
todos os países e produtos. Estas linhas têm as colunas
country
e products
atribuídas com NULL
.
Finalmente, seguindo todas as outras linhas, um linha
resumo extra é produzida mostrando o total geral para
todos os anos, países e produtos. Esta linha tem as
colunas year
,
country
e products
atribuídas com NULL
.
Outras Considerações ao Usar
ROLLUP
O seguinte item lista alguns comportamentos específicaos para
a implementação do ROLLUP
no MySQL:
Quando você usa ROLLUP
, você não pode
usar uma cláusula ORDER BY
para ordenar os
resultados. (Em outras palavras, ROLLUP
e
ORDER BY
são exclusivos mutualmente.) No
entanto, você ainda tem algum controle sobre a ordem de
ordenação. O GROUP BY
no MySQL ordena os
resultados, e você pode usar as palavras chaves
ASC
e DESC
explicitamente com colunas chamadas na lista GROUP
BY
para especificar a ordem de classificação para
colunas individuais. (A linha resumo de nível mais alto
adicionado por ROLLUP
ainda aparece depois
da linha para as quais elas são calculadas, considerando a
ordenação.)
LIMIT
pode ser usado para restringir o
númerod e linhas retornadas para o cliente.
LIMIT
é aplicado depois do
ROLLUP
, assim o limite se aplica contra as
linhas extras adicionadas por ROLLUP
. Por
exemplo:
mysql>SELECT year, country, product, SUM(profit)
->FROM sales
->GROUP BY year, country, product WITH ROLLUP
->LIMIT 5;
+------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | Finland | NULL | 1600 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | +------+---------+------------+-------------+
Note que usar LIMIT
com
ROLLUP
pode produzir resultados mais
difíceis de interpretar, porque você têm menos contexto
para entender as linhas super agrupadas.
O indicador NULL
em cada linha
super-agrupadas são produzidas quando a linha é enviada para
o cliente. O servidor olha por cada coluna chamada na
cláusula GROUP BY
seguindo aquela mais a
esquerda que tem o valor alterado. Para qualquer coluna no
resultado com o nome que é uma combinação léxica de
qualquer daqueles nomes, seu valor é definido com
NULL
. (Se você especifica o agrupamento de
colunas pelo número da coluna, o servidor identifica quais
colunas definir com NULL
pelo número.)
Como os valores NULL
em linhas super
agrupadas são colocadas dentro do resultado como um estágio
posterior no processamento da consulta, você não pode
testá-los com valores NULL
dentro da
própria consulta. Por exemplo, você não pode adicionar
HAVING product IS NULL
a consulta para
eliminar da saída todas as linhas com exceção das
agrupadas.
Por outro lado, o valor NULL
aparece como
NULL
no lado do cliente e pode ser testado
usando qualquer interface de programação do cliente MySQL.
O MySQL tem extendido o uso de GROUP BY
.
Você pode utilizar colunas ou cálculos na expressão
SELECT
que não aparecem na parte
GROUP BY
. Ele espera por qalquer
valor possível para este grupo. Você pode
utilizar isto para conseguir um melhor desempenho evitando
ordenação e agrupamento em itens desnecessários. Por
exemplo, você não precisa fazer um agrupamento em
cliente.nome
na consulta seguinte:
mysql>SELECT pedido.idcliente,cliente.nome,MAX(pagamento)
->FROM pedido, cliente
->WHERE pedido.idcliente = cliente.idcliente
->GROUP BY pedido.idcliente;
No padrão SQL, você teria que adicionar
cliente.nome
a cláusula GROUP
BY
. No MySQL, o nomê é redundante se você não o
executa em modo ANSI.
Não utilize este recurso se
as colunas omitidas na parte GROUP BY
não
são únicas no grupo! Você obterá resultados inexperados.
Em alguns casos, você pode utilizar MIN
e
MAX
para obter o valor de uma coluna
específica, mesmo que ele não seja único. O exemplo
seguinte fornece o valor de coluna
do
registro contendo o menor valor na coluna
ordem
:
SUBSTR(MIN(CONCAT(RPAD(ordem,6,' '),coluna)),7)
See Secção 3.6.4, “As Linhas Armazenando o Group-wise Máximo de um Certo Campo”.
Note que se você estiver usando a versão 3.22 do MySQL (ou
anterior) ou se estiver tentando seguir o SQL-99, você não
pode utilizar expressões nas cláusulas GROUP
BY
or ORDER BY
. Você pode
contornar esta limitação utilizando um alias para a
expressão:
mysql>SELECT id,FLOOR(value/100) AS val FROM nome_tabela
->GROUP BY id,val ORDER BY val;
Na versão 3.23 do MySQL você pode fazer:
mysql> SELECT id,FLOOR(value/100) FROM nome_tabela ORDER BY RAND();
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY] [DISTINCT | DISTINCTROW | ALL] expressão_select,... [INTO {OUTFILE | DUMPFILE} 'nome_arquivo' opções_exportação] [FROM tabelas_ref [WHERE definição_where] [GROUP BY {inteiro_sem_sinal | nome_col | formula} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_definition] [ORDER BY {inteiro_sem_sinal | nome_coluna | formula} [ASC | DESC], ...] [LIMIT [offset,] row_count | row_count OFFSET offset] [PROCEDURE nome_procedimento(lista_argumentos)] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT
é utilizado para retornar registros
selecionados de uma ou mais tabelas. Cada
expressão_select
indica as colunas que você
deseja recuperar. SELECT
tanbém pode ser
utilizado para retornar registros calculados sem referência a
nenhuma tabela. Por exemplo:
mysql> SELECT 1 + 1;
-> 2
Todas as cláusulas usada devem ser fornecidas exatamente na
ordem mostrada na descrição da sintaxe. Por exemplo, uma
cláusula HAVING
deve vir depois de qualquer
cláusula GROUP BY
e antes de qualquer
cláusula ORDER BY
.
Uma expressão SELECT
pode utilizar um
alias usando AS nome_alias
. O alias é
usado como o nome da coluna da expressão e pode ser usado
com cláusulas ORDER BY
ou
HAVING
. Por exemplo:
mysql> SELECT CONCAT(primeiro_nome,' ',ultimo_nome) AS nome_completo
FROM minha_tabela ORDER BY nome_completo;
A palavra chave AS
é opcional quando se
utiliza alias em uma expressão SELECT
. O
exemplo anterior poderia ser escrito assim:
mysql> SELECT CONCAT(last_name,', ',first_name) full_name
FROM mytable ORDER BY full_name;
Como AS
é opcional, pode ocorrer um
problema se você esquecer a vírgula entre duas expressões
SELECT
: O MySQL interpretará o segundo
como um nome de alias. Por exemplo, na seguinte instrução,
columnb
é tratada como um nome de alias:
mysql> SELECT columna columnb FROM mytable;
Não é permitido utilizar um alias de coluna em uma
cláusula WHERE
, pois o valor da coluna
pode ainda não ter sido determinado quando a cláusula
WHERE
for executada. See
Secção A.5.4, “Problemas com alias
”.
A cláusula FROM table_references
indica
a tabela de onde os registros serão retornados. Se você
indicar mais de uma tabela, você estará realizando uma
join. Para informações sobre a sintaxe de join, veja
Secção 6.4.1.1, “Sintaxe JOIN
”. Para cada tabela especificada, você
pode, opcionalmente, especificar um alias.
nome_tabela [[AS] alias] [[USE INDEX (lista_indice)] | [IGNORE INDEX (lista_indice)] | FORCE INDEX (lista_indice)]]
Como na versão 3.23.12 do MySQL, você pode dar sugestões
sobre qual índice o MySQL deve usar ao recuperar
informações de uma tabela. Isto é útil se
EXPLAIN
mostrar que o MySQL esta
utilizando o índice errado da lista de índices possíveis.
Especificando USE INDEX (lista_indice)
você pode dizer ao MySQL para usar somente um dos índices
possíveis para encontrar registros em uma tabela. A sintaxe
alternativa IGNORE INDEX (lista_indice)
pode ser usada para dizer ao MySQL para não utilizar alguns
índices particulares.
Na versão 4.0.9 do MySQL você também pode usar
FORCE INDEX
. Ele funciona como
USE INDEX (lista_indice)
mas ele assume
que uma varredura em uma tabelas é MUITO cara. Em outras
palavras, uma varredura só será usada se não houver
nenhum modo de utilizar um dos índices dados para encontrar
registros nas tabelas.
USE/IGNORE/FORCE KEY
é sinônimo de
USE/IGNORE/FORCE INDEX
.
Nota:
USE/IGNORE/FORCE INDEX
afeta apenas os
índices usados quando o MySQL decide como encontrar
registros na tabela e como fazer a ligação. Ele não tem
efeito se um índice será usado ao resolver um
ORDER BY
ou GROUP BY
.
No MySQL 4.0.14 você pode usar SET
MAX_SEEKS_FOR_KEY=#
como um modo alternativo de
forçar o MySQL a preferir a busca em chaves em vez de
varrer a tabela.
Você pode se referir a uma tabela como
nome_tabela
(dentro do banco de dados
atual) ou como nomebd.nome_tabela
para
especificar um banco de dados. Você pode se referir a um
coluna como nome_coluna
,
nome_tabela.nome_coluna
ou
nomebd.nome_tabela.nome_coluna
. Você
não precisa especificar um prefixo
nome_tabla
ou
nomebd.nome_tabela
para referência a uma
coluna em uma instrução SELECT
a menos
a referência seja ambígua. Veja
Secção 6.1.2, “Nomes de Banco de dados, Tabela, Índice, Coluna e Alias”, para exemplos de ambiguidade
que exigem a forma mais explicita de referência a coluna.
A partir da versão 4.1.0, você pode especificar
DUAL
como um nome de tabela dummy, em
situações onde nenhuma tabela for referênciada. Este é
um recurso puramente para compatibilidade, alguns outros
servidores exijem esta sintaxe.
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
Pode se definir um alias fazendo referência a uma tabela
utilizando nome_tabela [AS] nome_alias
:
mysql>SELECT t1.nome, t2.salario FROM funcionarios AS t1, info AS t2
->WHERE t1.nome = t2.nome;
mysql>SELECT t1.nome, t2.salario FROM funcionarios t1, info t2
->WHERE t1.nome = t2.nome;
Colunas selecionadas para saída podem ser referidas em
cláusulas ORCER BY
e GROUP
BY
usando nomes de colunas, alias de colunas ou
posições de colunas. As posições de colunas começam com
1:
mysql>SELECT college, region, seed FROM tournament
->ORDER BY region, seed;
mysql>SELECT college, region AS r, seed AS s FROM tournament
->ORDER BY r, s;
mysql>SELECT college, region, seed FROM tournament
->ORDER BY 2, 3;
Para ordenar inversamente, adicione a palavra-chave
DESC
(descendente) ao nome da coluna na
cláusula ORDER BY
na qual você está
ordenando. A ordem padrão é ascedente; ela pode ser
especificada explicitamente usando a palavra-chave
ASC
.
Na cláusula WHERE
, você pode usar
qualquer uma das funções suportadas pelo MySQL. Exceto
para funções de agruopamento (resumo) See
Secção 6.3, “Funções para Uso em Cláusulas SELECT
e WHERE
”.
A cláusula HAVING
pode se referir a
qualquer coluna ou alias definido na
expressão_select
. Ele é aplicado no
final, pouco antes dos itens serem enviados ao cliente, sem
otimização. LIMIT
é aplicada depois de
HAVING
.) estar na cláusula
WHERE
. Por exemplo, não escreva isto:
mysql> SELECT nome_col FROM nome_tabela HAVING nome_col > 0;
Escreva assim:
mysql> SELECT nome_col FROM nome_tabela WHERE nome_col > 0;
Na versão 3.22.5 ou posterior, você também pode escrever consultar desta forma:
mysql>SELECT usuario,MAX(salario) FROM usuarios
->GROUP BY usuario HAVING MAX(salario)>10;
Em versões mais antigas, você pode escrever desta forma:
mysql>SELECT usuario,MAX(salario) AS soma FROM usuarios
->group by usuario HAVING soma>10;
As opções DISTINCT
,
DISTINCTROW
e ALL
especificam quando registros duplicados devem ser
retornados. O padrão é (ALL
), todos os
registros coincidentes são retornados.
DISTINCT
e DISTINCTROW
são sinônimos e espcificam que registros duplicados no
conjunto de resultados devem ser remopvidos.
STRAIGHT_JOIN
,
HIGH_PRIORITY
e opções começando com
SQL_
são extensões do MySQL para
SQL-99.
No MySQL 4.1.1, GROUP BY
permite um
modificador WITH ROLLUP
. See
Secção 6.3.7.2, “Modificadores GROUP BY
”.
HIGH_PRIORITY
dará uma prioridade
maior ao SELECT
do que para uma
instrução que atualizam uma tabela. Você só deve
isto para consultas que sejam rápidas e devam ser
feitas imediatamente. Uma consulta SELECT
HIGH_PRIORITY
retornará se a tabela está
bloqueada para leitura memsmo se houver uma instrução
de atualização que estiver esperando a liberação da
tabela.
SQL_BIG_RESULT
pode ser usado com
GROUP BY
ou
DISTINCT
para dizer ao otimizador que
o conjunto de resultados terá muitas linhas. Neste
caso, o MySQL usará diretamente tabelas temporarias em
disco se necessário. O MySQL também irá, neste caso,
preferir ordenar fazendo uma tabela temporária com um
cahve nos elementos GROUP BY
.
SQL_BUFFER_RESULT
força para que o
resultado seja colocado em uma tabela temporária. Isto
ajuda o MySQL a liberar as travas de tabelas mais cedo e
ajudará nos casos onde ele levá muito tempo para
enviar o conjunto de resultado ao cliente.
SQL_SMALL_RESULT
, uma opção
especifica do MySQL, pode ser usada com GROUP
BY
ou DISTINCT
para dizer
ao otimizador que o conjunto de resultados será
pequeno. Neste caso, o MySQL usa tabelas temporárias
rápidas para armazenar a tabela resultante em vez de
usar ordenação. Na versão 3.23 do MySQL isto não é
necessário normalmente.
SQL_CALC_FOUND_ROWS
(versão 4.0.0 e
acima) diz ao MySQL para calcular quantas linhas
haveriam no conjunto de resultados, desconsiderando
qualquer cláusula LIMIT
. O número
de linhas pode ser recuperado com SELECT
FOUND_ROWS()
. See
Secção 6.3.6.2, “Funções Diversas”.
Por favor, note que em nversões anteriores a 4.1.0 isto
não funciona com LIMIT 0
, o qual é
otimizado para retornar instantaneamente (resultando em
0 registros). See Secção 5.2.9, “Como o MySQL Otimiza Cláusulas LIMIT
”.
SQL_CACHE
diz ao MySQL para armazenar
o resultado da consulta em um cache de consultas se
você estiver utilizando
QUERY_CACHE_TYPE=2
(DEMAND
). See
Secção 6.9, “Cache de Consultas do MySQL”. No caso da consulta com
UNIONs e/ou subqueries esta opção terá efeito se
usada em qualquer SELECT da consulta.
SQL_NO_CACHE
diz ao MySQL para não
armazenar o resulado da consulta nesta cache de
consultas. See Secção 6.9, “Cache de Consultas do MySQL”. No caso da
consulta com UNIONs e/ou subqueries esta opção terá
efeito se usada em qualquer SELECT da consulta.
Se você utiliza GROUP BY
, os registros
de saída serão ordenados de acordo com o GROUP
BY
como se você tivesse um ORDER
BY
sobre todos os campos no GROUP
BY
. O MySQL tem expandido a cláusula
GROUP BY
para que você também possa
especificar ASC
e DESC
depois das colunas chamadas na cláusula:
SELECT a,COUNT(b) FROM tabela_teste GROUP BY a DESC
O MySQL tem extendido o uso do GROUP BY
para lhe permitir selecionar campos que não estão
mencionados na cláusula GROUP BY
. Se
você não está conseguindo os resultados esperados ara a
sua consulta, leia a descrição de GROUP
BY
. See
Secção 6.3.7, “Funções e Modificadores para Usar com Cláusulas GROUP BY
”.
A partir do MySQL 4.1.1, GROUP BY
permite
um modificador WITH ROLLUP
. See
Secção 6.3.7.2, “Modificadores GROUP BY
”.
A cláusula LIMIT
pode ser usada para
restringir o número de linhas retornadas pela instrução
SELECT
. LIMIT
utiliza
um ou dois agumebntos numéricos, que devem ser constants
inteiras.
Com um argumento. o valor especifíca o número de linhas para retornar do início do resultado. Com dois argumentos, o primeiro especifica a posição do primeiro registro a ser retornado e o segundo especifica o número máximo de linhas a retornar. A posição do registro inicial é 0 (não 1):
Para ser compatível com o PostgreeSQL, o MySQL suporta a
sintaxe: LIMIT row_count OFFSET offset
.
mysql> SELECT * FROM tabela LIMIT 5,10; # Recupera linhas 6-15
Para recuperar todos os registros de um determinado offset até um fim do resultado você pode usar um número grande como segundo parâmetro:
mysql> SELECT * FROM tabela LIMIT 95,18446744073709551615; # Recupera linhas 96-ultima.
Se um dos argumentos é dado, ele indica o número máximo de linhas a retornar:
mysql> SELECT * FROM tabela LIMIT 5; # Recupera as primeiras 5 linhas
Em outras palavras, LIMIT n
é
equivalente a LIMIT 0,n
.
A forma SELECT ... INTO OUTFILE
'nome_arquivo'
do SELECT
grava
os registros selecionados em um arquivo. O arquivo é criado
na máquina servidora e não pode já existir (entre outras
coisas, isto previne tabelas de banco de dados e arquivos
tais como /etc/passwd
de serem
destruídos). Você deve ter o privilégio
FILE
na máquina servidora para utilizar
esta forma de SELECT
.
A instrução SELECT ... INTO OUTFILE
tem
como intenção deixar que você descarregue rapidamente um
tabela de uma máquina servidora. Se você quiser criar o
arquivo resultante em outra máquina, diferente do servidor,
você não deve usar SELECT ... INTO
OUTFILE
. Neste caso você deve usar algum programa
cliente como mysqldump --tab
ou
mysql -e "SELECT..." > outfile
para
gerar o arquivo.
SELECT ... INTO OUTFILE
é o complemento
de LOAD DATA INFILE
; a sintaxe para a
parte opções_exportação
de uma
instrução consiste das mesmas cláusulas
CAMPOS
e LINHAS
que
são usadas com a instrução LOAD DATA
INFILE
. See Secção 6.4.8, “Sintaxe LOAD DATA INFILE
”.
No arquivo texto resultante, somente os seguintes coracteres
são escritos com o caracter ESCAPE BY
:
O caracter ESCAPE BY
O primeiro caracter em FIELDS TERMINATED
BY
O primeiro caracter em LINES TERMINATED
BY
Adicionalmente, ASCII 0
é convertido
para ESCAPE BY
seguido por 0
(ASCII 48
).
A razão para o mostrado acima é que você
deve
escapar qualquer caracter
FIELDS TERMINATED BY
, ESCAPE
BY
, or LINES TERMINATED BY
para
termos a segurança que o arquivo poderá ser lido de volta.
É feito escape de ASCII 0
para facilitar
a visuzlização com alguns paginadores.
Como o arquivo resultante não tem que estar em conformidade com a sintaxe SQL, nada mais precisa ser seguido de caraceres de escape.
Aqui segue um exemplo de como se obter um arquivo no formato usado por muitos programas antigos.
SELECT a,b,a+b INTO OUTFILE "/tmp/result.text" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n" FROM tabela_teste;
Se você utilizar INTO DUMPFILE
em vez de
INTO OUTFILE
, o MySQL só irá escrever
um linha no arquivo, sem nenhum terminador de linha ou
colunas e sem realizar nenhum processo de escape. Ele é
útil se você quiser armazenar um valor
BLOB
em um arquivo.
Note que qualuqer arquivo criado por INTO
OUTFILE
e INTO DUMPFILE
serão
escritos por todos os usuários no servidor! A razão é que
o servidor MySQL não pode criar um arquivo que pertence a
qualquer um além do usuário que o está executando (você
nunca deve executar mysqld
como
root
). Assim o arquivo tem que poder ser
gravado por todos para que você possa manipular o seu
conteúdo.
Uma cláusula PROCEDURE
chama um
procedimento que devia processar os dados em um resultado.
Para um exemplo, veja Secção 14.3.1, “Análise de Procedimento”.
Se você utilizar FOR UPDATE
em um
mecanismo de armazenamento com locks de páginas ou
registros, as linhas examinadas serão travadas para escrita
até o fim da transação atual.
O MySQL suporta as seguintes sintaxes JOIN
para uso em instruções SELECT
:
tabela_ref, tabela_ref tabela_ref [INNER | CROSS] JOIN table_reference [join_condition] tabela_ref STRAIGHT_JOIN tabela_ref tabela_ref LEFT [OUTER] JOIN table_reference [join_condition] tabela_ref NATURAL [LEFT [OUTER]] JOIN tabela_ref { OJ tabela_ref LEFT OUTER JOIN tabela_ref ON expr_condicional } tabela_ref RIGHT [OUTER] JOIN table_reference [join_condition] tabela_ref NATURAL [RIGHT [OUTER]] JOIN tabela_ref
Onde tabela_ref
é definido como:
nome_tabela [[AS] alias] [[USE INDEX (lista_indice)] | [IGNORE INDEX (lista_indice)] | [FORCE INDEX (lista_indice)]]
a condição_join
é definido como:
ON expr_condicional | USING (lista_colunas)
Geralamente você não deverá ter nenhuma condição na parte
ON
que é usada para restringir quais
registros você terá no seu resultado, mas ao invés disto,
especificar estas condições na cláusula
WHERE
. Existem exceções para isto.
Note que a sintaxe INNER JOIN
permite uma
condição_join
apenas a partir da versão
3.23.17. O mesmo acontece para JOIN
e
CROSS JOIN
apenas a partir do MySQL 4.0.11.
A última sintaxe LEFT OUTER JOIN
mostrada
na lista anterior só existe para compatibilidade com ODBC:
Pode se usar um alias para referência a tabelas com
nome_tabela AS nome_alias
ou
nome_tabela nome_alias
:
mysql>SELECT t1.nome, t2.salario FROM funcionarios AS t1, info AS t2
->WHERE t1.nome = t2.nome;
A condicional ON
é qualquer condição
da forma que pode ser usada em uma cláusula
WHERE
.
Se não houver registros coincidentes para a tabela a
direita da parte ON
ou
USING
em um LEFT
JOIN
, uma linha com NULL
atribuído a todas as colunas é usada para a tabela a
direita. Você pode usar este fato para encontrar registro
em uma tabela que não houver contrapartes em outra tabela
mysql>SELECT tabela1.* FROM tabela1
->LEFT JOIN tabela2 ON tabela1.id=tabela2.id
->WHERE tabela2.id IS NULL;
Este exemplo encontra todas as linhas em
tabela1
com um valor
id
que não está presente em
tabela2
(isto é, toda as linhas em
tabela1
sem linha correspondente em
tabela2
). Assume-se que
tabela2.id
é declarada NOT
NULL
. See
Secção 5.2.7, “Como o MySQL Otimiza LEFT JOIN
e RIGHT JOIN
”.
A cláusula USING
(lista_colunas)
nomeia uma lista de
colunas que devem existir em ambas as tabelas. As
seguintes duas cláusulas são semanticamente idênticas:
a LEFT JOIN b USING (c1,c2,c3) a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3
Um NATURAL [LEFT] JOIN
de duas tabelas
é definido para ser semanticamente equivalente a um
INNER JOIN
ou um LEFT
JOIN
com uma cláusula USING
que nomeia todas as colunas que exitem em ambas as
tabelas.
INNER JOIN
e ,
(vírgula) são semanticamente equivalentes na ausência
da condição join: ambos produzirão um produto
Cartesiano entre as tabelas especificadas. (isto é, todos
os registros na primeira tabela serão ligados com todos
os registros na segunda tabela).
RIGHT JOIN
funciona de forma análoga a
um LEFT JOIN
. Para manter o código
portável entre banco de dados, é recomendado usar
LEFT JOIN
em vez de RIGHT
JOIN
.
STRAIGHT_JOIN
é identico a
JOIN
, exceto pelo fato de que a tabela
de esquerda sempre é lida antes da tabela da direita. Ele
pode ser usado para aqueles casos (poucos) onde o
otimizador join coloca as tabelas na ordem errada.
Como na versão 3.23.12, você pode dar sugestões sobre
qual índice o MySQL deve us quando retornar informações
de uma tabela. Isto é útil se EXPLAIN
mostar que o MySQL está utilizando o índice errado da
lista de índices possíveis. Especificando USE
INDEX (lista_indice)
, você pode dizer ao MySQL
para usar somente um dos índices possíveis para
encontrar registros em uma tabela. A sintaxe alternativa
IGNORE INDEX (lista_indice)
pode ser
usado para dizer ao MySQL para não utilizar índices
particulares.
Na versão 4.0.9 do MySQL você também pode utilizar
FORCE INDEX
. Ele funciona como
USE INDEX (key_list)
mas com assume que
uma varredura na tabela é MUITO cara. Em outras palavras,
uma varredura na tabela só será feita se não houver
modo de uitlizar um dos índices fornecidos para se
enecontrar registros no tabela.
USE/IGNORE KEY
são sinônimos de
USE/IGNORE INDEX
.
Nota:
USE/IGNORE/FORCE INDEX
afeta apenas os
índices usados quando o MySQL decide como encontrar registros
na tabela e como fazer a ligação. Ele não tem efeito se um
índice será usado ao resolver um ORDER BY
ou GROUP BY
.
Alguns exemplos:
mysql>SELECT * FROM tabela1,tabela2 WHERE tabela1.id=tabela2.id;
mysql>SELECT * FROM tabela1 LEFT JOIN tabela2 ON tabela1.id=tabela2.id;
mysql>SELECT * FROM tabela1 LEFT JOIN tabela2 USING (id);
mysql>SELECT * FROM tabela1 LEFT JOIN tabela2 ON tabela1.id=tabela2.id
->LEFT JOIN tabela3 ON tabela2.id=tabela3.id;
mysql>SELECT * FROM tabela1 USE INDEX (chave1,chave2)
->WHERE chave1=1 AND chave2=2 AND chave3=3;
mysql>SELECT * FROM tabela1 IGNORE INDEX (chave3)
->WHERE chave1=1 AND chave2=2 AND chave3=3;
See Secção 5.2.7, “Como o MySQL Otimiza LEFT JOIN
e RIGHT JOIN
”.
SELECT ... UNION [ALL] SELECT ... [UNION SELECT ...]
UNION
foi implementado no MySQL 4.0.0.
UNION
é usado para combinar o resultado de
muitas instruções SELECT
em um único
conjunto de resultados.
As colunas listadas na porção expressão_select de
SELECT
devem ter o mesmo tipo. Os nomes das
colunas usadas na primeira consulta SELECT
serão usadas como nomes de colunas para o resultado
retornado.
Os comandos SELECT
são comandos selects
normais, mas com a seguinte restrição:
Somente o último comando SELECT
pode
ter INTO OUTFILE
.
Se você não utilzar a palavra-chave ALL
para o UNION
, todas as linhas retornadas
serão únicas, como se você tivesse utilizado um
DISTINCT
para o resultado final. Se você
especificar ALL
, você obterá todos os
regitros encontrados em todas as instruções
SELECT
.
Se você quiser usar um ORDER BY
para o
resultado UNION
final, você deve utilizar
parenteses:
(SELECT a FROM nome_tabela WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM nome_tabela WHERE a=11 AND B=2 ORDER BY a LIMIT 10) ORDER BY a;
ANY
, IN
, and SOME
ALL
EXISTS
and NOT EXISTS
FROM
clause
Uma subquery é uma instrução SELECT
dentro
de outra instrução. Por exemplo:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
No exemplo acima, SELECT * FROM t1 ...
é a
consulta principal (ou
instrução principal), e (SELECT
column1 FROM t2)
é a subquery.
Dizemos que a subquery está aninhada na
consulta principal, e de fato é possível aninhar subqueries
dentro de outras subqueries, a uma grande profundidade. uma
subquery deve estar sempres dentro de parenteses.
A partir da versão 4.1. o MySQL suporta todas as formas de subqueries e operações que o padrão SQL exige, assim como alguns recursos que são especificos do MySQL. A principal vantagem das subqueries são:
elas permitem consultas que estão estruturadas assim é possível isolar cada parte de uma instrução,
elas fornecem modos alternativos de realizar operações que, de outra forma, exigiriam joins e unions complexos,
elas são, na opinião de muitas pessoas, legíveis. De
fato, foi a inovação das subqueries que deu às pessoas a
idéia original do nome SQL
``Structured
Query Language''.
Com versões MySQL anteriores era necessário evitar ou contornar as subqueries, mas as pessoas que começam a escrever código agora descobrirão que subqueries são uma parte muito útil do pacote de ferramentas.
Aqui está uma instrução exemplo que mostra o ponto principal sobre a sintaxe de subquery como especificado pelo SQL padrão e suportado no MySQL.
DELETE FROM t1 WHERE s11 > ANY (SELECT COUNT(*) /* no hint */ FROM t2 WHERE NOT EXISTS (SELECT * FROM t3 WHERE ROW(5*t2.s1,77)= (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM (SELECT * FROM t5) AS t5)));
Para as versões do MySQL anteriores a 4.1, a maioria da subqueries podem ser reescritas com sucesso usando join e outros métodos. See Secção 6.4.2.11, “Rewriting Subqueries for Earlier MySQL Versions”.
Na sua forma mais simples (a subquery
scalar é o oposto das subqueries de
row ou table que
será discutido posteriormente), uma subqquery é um opernado
simples. Assim você pode usá-la se um valor de uma coluna ou
literal é permitido, e você pode esperar que eles tenham
certas características que todos os operandos possuem: um
tipo de dados, um tamanho, um indicador para informar se ele
pode ser NULL
, etc. Por exemplo:
CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL); SELECT (SELECT s2 FROM t1);
The subquery in the above SELECT
has a data
type of CHAR
, a length of 5, a character
set and collation equal to the defaults in effect at
CREATE TABLE
time, and an indication that
the value in the column can be NULL
. In
fact almost all subqueries can be NULL
,
because if the table is empty -- as in the example -- then the
value of the subquery will be NULL
. There
are few restrictions.
A subquery's outer statement can be any one of:
SELECT
, INSERT
,
UPDATE
, DELETE
,
SET
, or DO
.
A subquery can contain any of the keywords or clauses that
an ordinary SELECT
can contain:
DISTINCT
, GROUP BY
,
ORDER BY
, LIMIT
,
joins, hints, UNION
s, comments,
functions, and so on.
So, when you see examples in the following sections that
contain the rather Spartan construct (SELECT column1
FROM t1)
, imagine that your own code will contain
much more diverse and complex constructions.
For example, suppose we make two tables:
CREATE TABLE t1 (s1 INT); INSERT INTO t1 VALUES (1); CREATE TABLE t2 (s1 INT); INSERT INTO t2 VALUES (2);
Then perform a SELECT
:
SELECT (SELECT s1 FROM t2) FROM t1;
The result will be 2
because there is a row
in t2
, with a column s1
,
with a value of 2.
The subquery may be part of an expression. If it is an operand for a function, don't forget the parentheses. For example:
SELECT UPPER((SELECT s1 FROM t1)) FROM t2;
The most common use of a subquery is in the form:
<non-subquery operand> <comparison operator> (<subquery>)
Where <comparison operator> is one of:
= > < >= <= <>
For example:
... 'a' = (SELECT column1 FROM t1)
At one time the only legal place for a subquery was on the right side of a comparison, and you might still find some old DBMSs which insist on that.
Here is an example of a common-form subquery comparison which
you can't do with a join: find all the values in table
t1
which are equal to a maximum value in
table t2
.
SELECT column1 FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2);
Here is another example, which again is impossible with a join
because it involves aggregating for one of the tables: find
all rows in table t1
which contain a value
which occurs twice.
SELECT * FROM t1 WHERE 2 = (SELECT COUNT(column1) FROM t1);
Syntax:
<operand> <comparison operator> ANY (<subquery>) <operand> IN (<subquery>) <operand> <comparison operator> SOME (<subquery>)
The word ANY
, which must follow a
comparison operator, means ``return TRUE
if
the comparison is TRUE
for
ANY
of the rows that the subquery
returns.'' For example,
SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
Suppose that there is a row in table t1
containing {10}. The expression is TRUE
if
table t2
contains {21,14,7} because there
is a value in t2
-- 7 -- which is less than
10. The expression is FALSE
if table
t2
contains {20,10}, or if table
t2
is empty. The expression is
UNKNOWN
if table t2
contains
{NULL
,NULL
,NULL
}.
The word IN
is an alias for =
ANY
. Thus these two statements are the same:
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);
The word SOME
is an alias for
ANY
. Thus these two statements are the
same:
SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);
Use of the word SOME
is rare, but the above
example shows why it might be useful. The English phrase ``a
is not equal to any b'' means, to most people's ears, ``there
is no b which is equal to a'' -- which isn't what is meant by
the SQL syntax. By using <> SOME
instead, you ensure that everyone understands the true meaning
of the query.
Syntax:
<operand> <comparison operator> ALL (<subquery>)
The word ALL
, which must follow a
comparison operator, means ``return TRUE
if
the comparison is TRUE
for
ALL
of the rows that the subquery
returns''. For example,
SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);
Suppose that there is a row in table t1
containing {10}. The expression is TRUE
if
table t2
contains {-5,0,+5} because all
three values in t2
are less than 10. The
expression is FALSE
if table
t2
contains {12,6,NULL,-100} because there
is a single value in table t2
-- 12 --
which is greater than 10. The expression is
UNKNOWN
if table t2
contains {0,NULL,1}.
Finally, if table t2
is empty, the result
is TRUE
. You might think the result should
be UNKNOWN
, but sorry, it's
TRUE
. So, rather oddly,
SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);
is TRUE
when table t2
is
empty, but
SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);
is UNKNOWN
when table t2
is empty. In addition,
SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);
is UNKNOWN
when table t2
is empty. In general, tables with NULLs
and empty tables are edge
cases -- when writing subquery code, always
consider whether you have taken those two possibilities into
account.
A correlated subquery is a subquery which contains a reference to a column which is also in the outer query. For example:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);
Notice, in the example, that the subquery contains a reference
to a column of t1
, even though the
subquery's FROM
clause doesn't mention a
table t1
. So MySQL looks outside the
subquery, and finds t1 in the outer query.
Suppose that table t1
contains a row where
column1 = 5
and column2 =
6
; meanwhile table t2
contains a
row where column1 = 5
and column2
= 7
. The simple expression ... WHERE
column1 = ANY (SELECT column1 FROM t2)
would be
TRUE
, but in this example the
WHERE
clause within the subquery is
FALSE
(because 7 <> 5), so the
subquery as a whole is FALSE
.
Scoping rule: MySQL evaluates from inside to outside. For example:
SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x WHERE x.column1 = (SELECT column1 FROM t3 WHERE x.column2 = t3.column1));
In the above, x.column2
must be a column in
table t2
because SELECT column1
FROM t2 AS x ...
renames t2
. It
is not a column in table t1
because
SELECT column1 FROM t1 ...
is an outer
query which is further out.
For subqueries in HAVING
or ORDER
BY
clauses, MySQL also looks for column names in the
outer select list.
MySQL's unofficial recommendation is: avoid correlation because it makes your queries look more complex, and run more slowly.
If a subquery returns any values at all, then EXISTS
<subquery>
is TRUE
, and
NOT EXISTS <subquery>
is
FALSE
. For example:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Traditionally an EXISTS
subquery starts
with SELECT *
but it could begin with
SELECT 5
or SELECT
column1
or anything at all -- MySQL ignores the
SELECT
list in such a subquery, so it
doesn't matter.
For the above example, if t2
contains any
rows, even rows with nothing but NULL
values, then the EXISTS
condition is
TRUE
. This is actually an unlikely example,
since almost always a [NOT] EXISTS
subquery
will contain correlations. Here are some more realistic
examples.
Example: What kind of store is present in one or more cities?
SELECT DISTINCT store_type FROM Stores WHERE EXISTS (SELECT * FROM Cities_Stores WHERE Cities_Stores.store_type = Stores.store_type);
Example: What kind of store is present in no cities?
SELECT DISTINCT store_type FROM Stores WHERE NOT EXISTS (SELECT * FROM Cities_Stores WHERE Cities_Stores.store_type = Stores.store_type);
Example: What kind of store is present in all cities?
SELECT DISTINCT store_type FROM Stores S1 WHERE NOT EXISTS ( SELECT * FROM Cities WHERE NOT EXISTS ( SELECT * FROM Cities_Stores WHERE Cities_Stores.city = Cities.city AND Cities_Stores.store_type = Stores.store_type));
The last example is a double-nested NOT
EXISTS
query -- it has a NOT
EXISTS
clause within a NOT EXISTS
clause. Formally, it answers the question ``does a city exist
with a store which is not in Stores?''. But it's easier to say
that a nested NOT EXISTS
answers the
question ``is x TRUE for all y?''.
The discussion to this point has been of column (or scalar) subqueries -- subqueries which return a single column value. A row subquery is a subquery variant that returns a single row value -- and may thus return more than one column value. Here are two examples:
SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2); SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
The queries above are both TRUE
if table
t2
has a row where column1 =
1
and column2 = 2
.
The expression (1,2)
is sometimes called a
row constructor and is legal in other
contexts too. For example
SELECT * FROM t1 WHERE (column1,column2) = (1,1);
is equivalent to
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
The normal use of row constructors, though, is for comparisons with subqueries that return two or more columns. For example, this query answers the request: ``find all rows in table t1 which are duplicated in table t2'':
SELECT column1,column2,column3 FROM t1 WHERE (column1,column2,column3) IN (SELECT column1,column2,column3 FROM t2);
Subqueries are legal in a SELECT
statement's FROM
clause. The syntax that
you'll actually see is:
SELECT ... FROM (<subquery>) AS <name> ...
The AS <name>
clause is mandatory,
because any table in a FROM
clause must
have a name. Any columns in the
<subquery>
select list must have
unique names. You may find this syntax described elsewhere in
this manual, where the term used is ``derived tables''.
For illustration, assume you have this table:
CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);
Here's how to use the Subqueries in the FROM clause feature, using the example table:
INSERT INTO t1 VALUES (1,'1',1.0); INSERT INTO t1 VALUES (2,'2',2.0); SELECT sb1,sb2,sb3 FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb WHERE sb1 > 1;
Result: 2, '2', 4.0.
Here's another example: Suppose you want to know the average of the sum for a grouped table. This won't work:
SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;
But this query will provide the desired information:
SELECT AVG(sum_column1) FROM (SELECT SUM(column1) AS sum_column1 FROM t1 GROUP BY column1) AS t1;
Notice that the column name used within the subquery
(sum_column1)
is recognized in the outer
query.
At the moment, subqueries in the FROM
clause cannot be correlated subqueries.
There are some new error returns which apply only to subqueries. This section groups them together because reviewing them will help remind you of some points.
ERROR 1235 (ER_NOT_SUPPORTED_YET) SQLSTATE = 42000 Message = "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'"
This means that
SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)
will not work, but only in some early versions, such as MySQL 4.1.1.
ERROR 1240 (ER_CARDINALITY_COL) SQLSTATE = 21000 Message = "Operand should contain 1 column(s)"
This error will occur in cases like this:
SELECT (SELECT column1, column2 FROM t2) FROM t1;
It's okay to use a subquery that returns multiple columns, if the purpose is comparison. See Secção 6.4.2.7, “Row Subqueries”. But in other contexts the subquery must be a scalar operand.
ERROR 1241 (ER_SUBSELECT_NO_1_ROW) SQLSTATE = 21000 Message = "Subquery returns more than 1 row"
This error will occur in cases like this:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
but only when there is more than one row in
t2
. That means this error might occur
in code that has been working for years, because somebody
happened to make a change which affected the number of
rows that the subquery can return. Remember that if the
object is to find any number of rows, not just one, then
the correct statement would look like this:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
Error 1093 (ER_UPDATE_TABLE_USED) SQLSTATE = HY000 Message = "You can't specify target table 'x' for update in FROM clause"
This error will occur in cases like this:
UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
It's okay to use a subquery for assignment within an
UPDATE
statement, since subqueries are
legal in UPDATE
and in
DELETE
statements as well as in
SELECT
statements. However, you cannot use
the same table, in this case table t1
, for
both the subquery's FROM
clause and the
update target.
Usually, failure of the subquery causes the entire statement to fail.
Development is ongoing, so no optimization tip is reliable for the long term. Some interesting tricks that you might want to play with are:
Using subquery clauses which affect the number or order of the rows in the subquery, for example
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
Replacing a join with a subquery, for example
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);
instead of
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
Moving clauses from outside to inside the subquery, for example:
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
instead of
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
Para outro exemplo:
SELECT (SELECT column1 + 5 FROM t1) FROM t2;
em vez de:
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
Using a row subquery instead of a correlated subquery, for example:
SELECT * FROM t1 WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
instead of
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2);
Using NOT (a = ANY (...))
rather than
a <> ALL (...)
.
Using x = ANY (table containing {1,2})
rather than x=1 OR x=2
.
Using = ANY
rather than
EXISTS
The above tricks may cause programs to go faster or slower.
Using MySQL facilities like the BENCHMARK()
function, you can get an idea about what helps in your own
situation. Don't worry too much about transforming to joins
except for compatibility with older versions.
Some optimizations that MySQL itself will make are:
MySQL will execute non-correlated subqueries only once,
(use EXPLAIN
to make sure that a given
subquery really is non-correlated),
MySQL will rewrite
IN
/ALL
/ANY
/SOME
subqueries in an attempt to take advantage of the
possibility that the select-list columns in the subquery
are indexed,
MySQL will replace subqueries of the form
... IN (SELECT indexed_column FROM single_table ...)
with an index-lookup function, which
EXPLAIN
will describe as a special join
type,
MySQL will enhance expressions of the form
value {ALL|ANY|SOME} {> | < | >= | <=} (non-correlated subquery)
with an expression involving MIN
or
MAX
(unless NULL
s or
empty sets are involved). For example,
WHERE 5 > ALL (SELECT x FROM t)
might be treated as
WHERE 5 > (SELECT MAX(x) FROM t)
There is a chapter titled ``How MySQL Transforms Subqueries''
in the MySQL Internals Manual, which you can find by
downloading the MySQL source package and looking for a file
named internals.texi
.
Up to version 4.0, only nested queries of the form
INSERT ... SELECT ...
and REPLACE
... SELECT ...
are supported. The
IN()
construct can be used in other
contexts.
It is often possible to rewrite a query without a subquery:
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
This can be rewritten as:
SELECT t1.* FROM t1,t2 WHERE t1.id=t2.id;
The queries:
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2); SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
Can be rewritten as:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
A LEFT [OUTER] JOIN
can be faster than an
equivalent subquery because the server might be able to
optimise it better -- a fact that is not specific to MySQL
Server alone. Prior to SQL-92, outer joins did not exist, so
subqueries were the only way to do certain things in those
bygone days. Today, MySQL Server and many other modern
database systems offer a whole range of outer joins types.
For more complicated subqueries you can often create temporary
tables to hold the subquery. In some cases, however, this
option will not work. The most frequently encountered of these
cases arises with DELETE
statements, for
which standard SQL does not support joins (except in
subqueries). For this situation there are three options
available:
The first option is to upgrade to MySQL version 4.1.
The second option is to use a procedural programming
language (such as Perl or PHP) to submit a
SELECT
query to obtain the primary keys
for the records to be deleted, and then use these values
to construct the DELETE
statement
(DELETE FROM ... WHERE ... IN (key1, key2,
...)
).
The third option is to use interactive SQL to construct a
set of DELETE
statements automatically,
using the MySQL extension CONCAT()
(in
lieu of the standard ||
operator). For
example:
SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', "'", tab1.pkid, "'", ';') FROM tab1, tab2 WHERE tab1.col1 = tab2.col2;
You can place this query in a script file and redirect
input from it to the mysql
command-line
interpreter, piping its output back to a second instance
of the interpreter:
shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb
MySQL Server 4.0 supports multiple-table
DELETE
s that can be used to efficiently
delete rows based on information from one table or even from
many tables at the same time. Multiple-table
UPDATE
s are also supported from version
4.0.
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] nome_tabela [(nome_coluna,...)] VALUES ((expressão | DEFAULT),...),(...),... [ ON DUPLICATE KEY UPDATE nome_coluna=expressão, ... ] or INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] nome_tabela [(nome_coluna,...)] SELECT ... or INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] nome_tabela SET nome_coluna=(expressão | DEFAULT), ... [ ON DUPLICATE KEY UPDATE nome_coluna=expressão, ... ]
INSERT
insere novos registros em uma tabela
existente. A forma INSERT ... VALUES
da
instrução insere registros baseado em valores especificados
explicitamente. A forma INSERT ... SELECT
insere linhas selecionadas de outra(s) tabela(s). A forma
INSERT ... VALUES
com listas de múltiplos
valores é suportado a partir da versão 3.22.5. A sintaxe
nome_coluna=expressão
é suportada a partir
da verão 3.22.10 do MySQL.
nome_tabela
é a tabela na qual as linhas
serão inseridas. A lista de nome das colunas ou a cláusula
SET
indica para quais colunas a instrução
especifica valor:
Se você não especificar a lista de colunas para
INSERT ... VALUES
ou INSERT ...
SELECT
, os valores para todas as colunas na tabela
devem ser fornecidos na lista VALUES()
ou
pelo SELECT
. Se você não souber a ordem
das colunas nas tabelas, use DESCRIBE
nome_tabela
para descobrir.
Qualquer coluna que não tiver o valor fornecido
explicitamente assumirá o seu valor padrão. Por exemplo,
se você especificar uma lista de colunas que não definem
todas as coolunas na tabela, às colunas não definidas
serão atribuídos o seu valor padrão. Atribuição de
valor padrão é definido em Secção 6.5.3, “Sintaxe CREATE TABLE
”.
Você também pode utilizar a palavra-chave
DEFAULT
para atribuir o valor padrão a
uma coluna (Novo na versão 4.0.3. do MySQL). Fica mais
fácil de se escrever instruções INSERT
que atribuem valor a apenas algumas colunas porque ele
permite que você evite escrever uma lista
VALUES()
incompleta (uma lista que não
inclu um valor para cada coluna da tabela). De outa forma,
você teria que escrever a lista de nomes de colunas
correspondentes a cada valor na lista
VALUES()
.
MySQL sempre tem uma valor padrão para todos os campos. Isto é algo imposto pelo MySQL para estar apto a funcionar com tabelas transacionais e não transcaionais.
Nossa visão é que a verificação do conteúdo dos campos deve ser feita pela application and not in the database server.
Uma expressão
pode se referir a qualquer
coluna que tenha sida definaida anteriormente na lista de
valores. Por exemplo, você pode dizer:
mysql> INSERT INTO nome_tabela (col1,col2) VALUES(15,col1*2);
Mas não:
mysql> INSERT INTO nome_tabela (col1,col2) VALUES(col2*2,15);
Se você especificar a palavra chave
DELAYED
, o servidor coloca a linha ou
linhas a serem inseridas em um buffer, e o cliente que envia
a instrução INSERT DELAYED
então pode
contiuar. Se a tabela está ocupada, o servidor guarda a
linha. Quando a tabela fica livre, ele começa a inserir
linhas, verificando periódicamente para ver se há novos
pedidos de leitura para a tabela. Se houver, a fila de
linhas atrasadas é suspensa até que a tabela fique livre
de novo.
Se você especificar a palavra-chave
LOW_PRIORITY
, a execução do
INSERT
é atrasada até que nenhum outro
cliente esteja lendo a tabela. Isto inclui outros clientes
que começam a ler enquanto clientes existentes já estão
lendo e enquanto a instrução INSERT
LOW_PRIORITY
está esperando. É possível,
consequentemente, para um cliente que envia uma instrução
INSERT LOW_PRIORITY
esperar por um tempo
muito longo (ou mesmo para sempre) em um ambiente de muita
leitura. (É diferente de INSERT DELAYED
,
que deixa o cliente continuar de uma vez. See
Secção 6.4.3.2, “Sintaxe INSERT DELAYED
”. Note que
LOW_PRIORITY
não deve normalmente ser
usado com tabelas MyISAM
ja que elas
disabilitam inserções concorrentes. See
Secção 7.1, “Tabelas MyISAM
”.
Se você especificar a palavra-chave
IGNORE
em um INSERT
com muitas linhas, quqlquer linha que duplicar uma chave
PRIMARY
ou UNIQUE
existente em uma tabela são ignorados e não são
inseridos. Se você não especificar
IGNORE
, a inserção é abortada se
houver quqlquer linhq que duplique um valor de uma chave
existente. Você pode determinar com função
mysql_info()
da API C quantas linhas
foram inseridas nas tabelas.
Se você especificar se uma cláusula ON DUPLICATE
KEY UPDATE
(noca no MySQL 4.1.0), e uma linha que
causasse a duplicação de um valor fosse inserida em uma
chave PRIMARY
ou
UNIQUE
, um UPDATE
da
linha antiga seria realizado. Por exemplo, o comando:
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3)
->ON DUPLICATE KEY UPDATE c=c+1;
no caso da coluna a
ser declarada como
UNIQUE
e ja existir o valor
1
, o exemplo acima seria idêntico a
mysql> UPDATE table SET c=c+1 WHERE a=1;
Nota: se a coluna
b
também for única, o comando
UPDATE
seria escrito como
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
e se a=1 OR b=2
casasse com diversas
linhas, somente uma linha
será atualizada! em geral, deve-se tentar evitar utilizar a
cláusula ON DUPLICATE KEY
em tabelas com
múltiplas chaves UNIQUE
.
Desde o MySQL 4.1.1 pode-se utilizar a função
VALUES(nome_coluna)
para se referir ao
valor da coluna na parte INSERT
do
comando INSERT ... UPDATE
- que é o
valor que seria inserido se não houvesse conflitos de
chaves duplicadas. Esta função é especialmente útil em
inserções de múltiplas linhas. Naturalmente a função
VALUES()
só tem sentido em um comando
INSERT ... UPDATE
e retorna
NULL
no caso de outros comandos.
Exemplo:
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
->ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
O camondo acima e idêntico a
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3)
->ON DUPLICATE KEY UPDATE c=3;
mysql>INSERT INTO table (a,b,c) VALUES (4,5,6)
->ON DUPLICATE KEY UPDATE c=9;
A utilizar ON DUPLICATE KEY UPDATE
, a
opção DELAYED
é ignorada.
Se MySQL foi configurado usando a opção
DONT_USE_DEFAULT_FIELDS
, instruções
INSERT
geram um erro a menos que você
especifique valores explicitamete para todas as colunas que
exigem um valor não-NULL
. See
Secção 2.3.3, “Opções típicas do configure
”.
Você pode encontrar o valor usado por uma coluna
AUTO_INCREMENT
com a função
mysql_insert_id
. See
Secção 12.1.3.32, “mysql_insert_id()
”.
Se você utilizar instruções INSERT ...
SELECT
ou INSERT ... VALUES
com
lista de valores múltiplos, você pode utilizar a função
mysql_info()
da API C para obter informação
sobre a consulta. O formato da string de informação é
mostrado aqui:
Records: 100 Duplicates: 0 Warnings: 0
Duplicates
indica o número de linhas que
não puderam ser inseridas porque duplicariam alguns valores de
índices únicos existentes. Warnings
indica
o número de tentativas de inserção de um valor em uma coluna
que de alguma forma estava problematico. Avisos (Warnings) podem
ocorrer sob qualquer uma das seguintes condições:
Inserir NULL
em uma coluna declarada com
NOT NULL
. A coluna é definida com o seu
valor padrão.
Definir uma coluna numérica com um valor que esteja fora da faixa permitida. O valor é revertido para final apropriado da faixa.
Definir uma coluna numérica com um valor como
'10.34 a'
. O lixo no final é eliminado e
a parte numérica restante é inserida. Se o valor não
fizer sentido como um número, é atribuido
0
a coluna.
Inserir uma string em uma coluna CHAR
,
VARCHAR
, TEXT
, ou
BLOB
e que exceda o tamanho máximo da
coluna. O valor é truncado para o tamanho máximo da
coluna.
Inserir um valor em uma coluna date ou time e que seja inválido para o tipo da coluna. A coluna é preenchida com o valor de zero apropriado para o tipo.
INSERT [LOW_PRIORITY] [IGNORE] [INTO] nome_tabela [(column list)] SELECT ...
Com a instrução INSERT ... SELECT
você
pode inserir muitas linhas rapidamente em uma tabela a partir
de outras tabelas
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;
As seguintes condições servem para uma instrução
INSERT ... SELECT
:
Antes do MySQL 4.0.1, INSERT ... SELECT
operava implicitamente em modo IGNORE
.
A partir do MySQL 4.0.1, você deve especificar
IGNORE
explicitamente para ignorar
registros que causaria violação de chave duplicada.
Antes do MySQL 4.0.14, a tabela alvo da instrução
INSERT
não pode aparecer na cláusula
FROM
da parte SELECT
da consulta. Esta limitação é deixada na versão
4.0.14.
Colunas AUTO_INCREMENT
funcionam da
mesma forma.
Em programas C, Você pode usar a função
mysql_info()
da API C para obter
informação sobre a consulta. See
Secção 6.4.3, “Sintaxe INSERT
”.
Para assegurar que o log binário possa ser usado para
re-criar a tabela original, MySQL não permitirá
inserções concorrentes em um INSERT ...
SELECT
.
Você também pode utilizar REPLACE
em vez
de INSERT
para sobrescrever linhas antigas.
REPLACE
é a contra parte para
INSERT IGNORE
no tratamento de novas linhas
contendo valores de chave únicos que duplicam linhas antigas:
As novas linhas são usadas para substituir as linhas antigas
em vez de descartá-las.
INSERT DELAYED ...
A opção DELAYED
para a instrução
INSERT
é um opção específica do MySQL
que é muito útil se você tiver clientes que não possam
esperar que o INSERT
se complete. Este é
um problema comum quando você utiliza o MySQL para fazer log
e você também execute periodicamente instruções
SELECT
e UPDATE
que
levem muito tempo para completar. DELAYED
foi intriduzido no MySQL versão 3.22.15. Ela é uma extensão
do MySQL ao SQL-92.
INSERT DELAYED
só funciona com tabelas
ISAM
e MyISAM
. Note que
como tabelas MyISAM
suportam
SELECT
e INSERT
concorrentes, se não houver blocos livres no meio do arquivo
de dados, você raramente precisará utilizar INSERT
DELAYED
com MyISAM
. See
Secção 7.1, “Tabelas MyISAM
”.
Quando você utiliza INSERT DELAYED
, o
cliente irá obter um OK de uma vez e a linha será inserida
quando a tabela não estiver sendo usada por outra thread.
Outro grande benefício do uso de INSERT
DELAYED
e que inserções de muitos clientes são
empacotados juntos e escritos em um bloco. Isto é muito mais
rápido que se fazer muitas inserções seperadas.
Note que atualmente as linhas enfileirdas só são armazenadas
em memória até que elas sejam inseridas na tabela. Isto
significa que se você matar o mysqld
com
kill -9
ou se o mysqld
finalizar inesperadamente, as linhas enfileiradas que não
forma escritas em disco são perdidas.
A seguir temos uma descrição em detalhes do que acontece
quando você utiliza a opção DELAYED
com
INSERT
ou REPLACE
. Nesta
descrição, a ``thread'' e a thread que recebe um comando
INSERT DELAYED
e ``handler'' é a thread
que trata todas as instruções INSERT
DELAYED
de uma tabela particular.
Quando uma thread executa uma instrução
DELAYED
em uma tabela, uma thread
handler é criada para processar todas as instruções
DELAYED
para a tabela, se tal handler
ainda não existir.
A thread verifica se o handler já adquiriu uma trava
DELAYED
; se não, ele diz a thread
handler para fazê-lo. A trava DELAYED
pode ser obtida mesmo se outras threads tiver uma trava de
LEITURA
ou ESCRITA
na tabela. De qualquer forma, o handler irá esperar por
todas as travas ALTER TABLE
ou
FLUSH TABLES
para se assegurar que a
estrutura da tabela está atualizada.
A thread executa a instrução INSERT
,
mas em vez de escrever a linha na tabela, ela põe uma
cópia da linha final na fila que é gerenciada pela
thread handler. Quaisquer erros de sintaxe são
notificados pela thread e relatadas ao programa cliente.
O cliente não pode relatar o número de duplicatas ou o
valor AUTO_INCREMENT
para a linha
resultante; ele não pode obtê-los do servidor, pois o
INSERT
retorna antes da operação de
inserção ser completada. Se você utiliza a API C, a
função mysql_info()
não irá
retornar nada significante, pela mesma razão.
O log binário é atualizado pela thread handler quando a linha é inserida na tabela. No caso de inserção de múltiplas linhas, o log binário é atualizado quando a primeira linha é inserida.
Depois que todas as linhas
delayed_insert_limit
são escrita, o
handle verifica se alguma instrução
SELECT
está pendente. Se estiver, ele
permite que ela seja executada antes de continuar.
Quando o handler não tiver mais linhas na fila, a tabela
é destravada. Se nunhum comando INSERT
DELAYED
novo é recebido dentro de
delayed_insert_timeout
segundos, o
handler termina.
Se mais que delayed_queue_size
estão
pendentes em uma fila handler específica, a thread
requisitando INSERT DELAYED
espera até
que haja espaçõ na fila. Isto é feito para assegurar
que o servidor mysqld
não utilize toda
a memória área de memória de atraso.
A thread handler irá aparecer na lista de processos do
MySQL process list com delayed_insert
na coluna Command
. Ela será finalizada
se você executar um comando FLUSH
TABLES
ou matá-la com KILL
thread_id
. No entanto, primeiro ela armazenará
todas as linhas enfileiradas na tabela antes de sair.
Durante este tempo ela não aceitará nenhum comando
INSERT
novo da outra thread. Se você
executar um comando INSERT DELAYED
depois disto, uma nova thread handler será criada.
Note que o mostrado acima significa que o comando
INSERT DELAYED
tem prioridade maior que
um comando INSERT
normal se já houver
um handler INSERT DELAYED
em
execução! Outro comando de atualização terá que
esperar até que a fila INSERT DELAYED
esteja vazia, alguém finalize a thread handler (com
KILL thread_id
), ou alguém execute
FLUSH TABLES
.
As seguintes variáveis de estado fornecem informção
sobre comandos INSERT DELAYED
:
Variável | Significado |
Delayed_insert_threads | Número de threads handler |
Delayed_writes | Números de linhas escrita com INSERT DELAYED |
Not_flushed_delayed_rows | Número de linhas esperando para serem escritas |
Você pode visualizar estas variáveis com a instrução
SHOW STATUS
ou executando um comando
mysqladmin extended-status
.
Note que INSERT DELAYED
é mais lento que
um INSERT normal se a tabela não estiver em uso. Também há
uma sobrecarga adicional para o servidor tratar um thread
separada para cada tabela na qual você utiliza
INSERT DELAYED
. Isto significa que você
só deve usar INSERT DELAYED
quando você
estiver certo de necessita dele!
UPDATE [LOW_PRIORITY] [IGNORE] nome_tabela SET nome_coluna1=expr1 [, nome_coluna2=expr2 ...] [WHERE definição_where] [ORDER BY ...] [LIMIT row_count] ou UPDATE [LOW_PRIORITY] [IGNORE] nome_tabela [, nome_tabela ...] SET nome_coluna1=expr1 [, nome_coluna2=expr2 ...] [WHERE definição_where]
UPDATE
atualiza uma coluna em registros de
tabelas existentes com novos valores. A cláusula
SET
indica quais colunas modificar e os
valores que devem ser dados. A cláusula
WHERE
i, se dada, especifica quais linhas
devem ser atualizadas. Senão todas as linhas são atualizadas.
Se a cláusula ORDER BY
é especificada, as
linhas serão atualizada na ordem especificada.
Se você especificar a palavra-chave
LOW_PRIORITY
, a execução de
UPDATE
e atrasada até que nenhum outro
cliente esteja lendo da tabela.
Se você especificar a palavra-chave IGNORE
,
a instrução não será abortada memso se nós obtermos erros
de chaves duplicadas durante a atualização. Linhas que causem
conflitos não serão atualizadas.
Se você acessa um coluna de nome_tabela
em
uma expressão, UPDATE
utiliza o valor atual
da coluna. Por exemplo, a seguinte instrução define a coluna
age
com o valor atual mais um:
mysql> UPDATE persondata SET age=age+1;
Atribuiçãoes UPDATE
são avaliadas da
esquerda para a direitat. Por exemplo, a seguinte instrução
dobra a coluna age
e então a incrementa:
mysql> UPDATE persondata SET age=age*2, age=age+1;
Se você define uma coluna ao valor que ela possui atualmente, o MySQL notará isto é não irá atualizá-la.
UPDATE
retorna o número de linhas que forma
realmente alteradas. No MySQL Versão 3.22 ou posterior, a
função mysql_info()
da API C retorna o
número de linhas encontradas e atualizadas e o número de
avisos que ocorreram durante o UPDATE
.
A partir do MySQL versão 3.23, você pode utilizar
LIMIT row_count
para restringir o escopo do
UPDATE
. Uma cláusula
LIMIT
funciona da seguinte forma:
Antes do MySQL 4.0.13, LIMIT
é uma
restrição que afeta as linhas. A instrução para assim
que altera row_count
linhas que
satisfaçam a cláusula WHERE
.
Da versão 4.0.13 em diante, LIMIT
é uma
restrição de linhas correspondentes. A instrução para
assim que ela encontrar row_count
linhas
que satisfaçam a cláusula WHERE
, tendo
elas sido alteradas ou não.
Se uma cláusula ORDER BY
é utilizada
(disponível no MySQL 4.0.0), as linhas serão atualizadas nesta
ordem. Isto só é util em conjunto com
LIMIT
.
A partir da MySQL Versão 4.0.4, você também pode realizar
operações UPDATE
que cobrem múltiplas
tabelas:
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;
O exemplo mostra um inner join usando o operador de vírgula,
mas instruções UPDATE
multi-tabelas podem
usar qualquer tipo de join permitida na instrução
SELECT
, como LEFT JOIN
.
Nota: você não pode utilizar ORDER BY
ou
LIMIT
com multi-tabelas
UPDATE
.
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name [WHERE definição_where] [ORDER BY ...] [LIMIT row_count] ou DELETE [LOW_PRIORITY] [QUICK] [IGNORE] table_name[.*] [, table_name[.*] ...] FROM tabelas-referentes [WHERE definição_where] ou DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM nome_tabela[.*] [, nome_tabela[.*] ...] USING tabelas-referentes [WHERE definição_where]
DELETE
deleta linhas de
nome_tabela
que satisfaçam a condição dada
por definição_where
, e retorna o número de
registros deletados.
Se você exeecutar um DELETE
sem cláusula
WHERE
, todas as linhas são deletadas. Se
você o fizer no modo AUTOCOMMIT
, isto irá
funcionar como TRUNCATE
. See
Secção 6.4.6, “Sintaxe TRUNCATE
”. No MySQL 3.23,
DELETE
sem uma cláusula
WHERE
retornará zero como o número de
registros afetados.
Se você realmente quiser saber quantos registros são deletados
quando você deletar todas as linhas mesmo sofrendo uma com a
queda da velocidade, você pode utilizar uma instrução
DELETE
desta forma:
mysql> DELETE FROM nome_tabela WHERE 1>0;
Note que isto é muito mais lento que DELETE FROM
nome_tabela
sem cláusula WHERE
,
pois ele deleta uma linha de cada vez.
Se você especificar a palavra-chave
LOW_PRIORITY
, a execução do
DELETE
é atrasda até que nenhum outro
cliente esteja lendo da tabela.
Para tabelas MyISAM
, Se você especificar a
palavra QUICK
, o mecanismo de armazenamento
não irá fundir os índices excluídos durante a deleção, o
que pode aumentar a velocidade de certos tipos de deleção.
A velocidade das operações de deleção também pode ser
afetadas pelos fatores discutidos em
Secção 5.2.12, “Performance das Consultas que Utilizam DELETE
”.
A opção IGNORE
faz com que o MySQL ignore
todos os erros durente o processo de deleção dos registros.
Erros encontrados durante o estágio de análise são
processados da maneira comum. Erros que são ignorados devido ao
uso desta opção são retornados como aviso. Esta opção
aparece pela primeira vez na versão 4.1.1.
Em tabelas MyISAM
, registros deletados são
mantidos em uma lista encadeada e operções
INSERT
subsequentes reutilizam posições de
registros antigos. Para recuperar espeços não utilizados e
reduzir o tamanho do arquivo, utilize a instrução
OPTIMIZE TABLE
ou o utiliztário
myisamchk
para reorganizar as tabelas.
OPTIMIZE TABLE
é mais fácil, mas
myisamchk
é mais rápido. Veja
Secção 4.6.1, “Sintaxe de OPTIMIZE TABLE
” e
Secção 4.5.6.10, “Otimização de Tabelas”.
O primeiro formato de delção de multi-tabelas é suportado a partir do MySQL 4.0.0. O segundo formato de deleção multi-tabelas é suportado a partir do MySQL 4.0.2.
A idéia é que apenas linhas coincidentes da tabelas listadas
antes de
FROM
ou antes da cláusula
USING
são deletadas. O efeito é que você
pode deletar l;inhas de muitas tabelas ao mesmo tempo e também
ter tabelas adicionais que são utilizadas para busca.
O .*
depois do nome da tabela existe apenas
para ser compatível com o Access
:
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id ou DELETE FROM t1,t2 USING t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
No cso acima nós deletamos linhas coincidente apenas na tabela
t1
e t2
.
O exemplo mostra um inner join usando o operador de vírgula,
mas instruções UPDATE
multi-tabelas podem
usar qualquer tipo de join permitida na instrução
SELECT
, como LEFT JOIN
.
Se uma cláusula ORDER BY
é utilizada
(disponível no MySQL 4.0.0), as linhas serão deletadas naquela
ordem. Isto só é útil se usado em conjunto com
LIMIT
. Por exemplo:
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp LIMIT 1
Isto irá deletar as entradas antigas (por
timestamp
) onde as linhas casam com a
cláusula WHERE
.
A opção específica do MySQL LIMIT
row_count
para DELETE
diz ao
servidor o número máximo de linhas a serem deletadas antes do
controle retornar ao cliente. Isto pode ser usado para assegurar
que uma comando DELETE
específico mão
tomará muito tempo, Você pode simplesmente repetir o comando
DELETE
até que o número de linhas afetadas
seja menor que o valor LIMIT
.
No MySQL 4.0, você pode especificar múltiplas tabelas na
instrução DELETE
para deletar linhas de uma
ou mais tabelas dependendo de uma condição particular em
várias tabelas. No entanto você não pode utilizar
ORDER BY
ou LIMIT
em uma
multi-tabela DELETE
.
TRUNCATE TABLE nome_tabela
Na versão 3.23 TRUNCATE TABLE
é mapeada
para COMMIT; DELETE FROM table_name
. See
Secção 6.4.5, “Sintaxe DELETE
”.
TRUNCATE TABLE
difere de DELETE FROM
...
do seguinte modo:
Operações truncate apagam e recriam a tabela, o que é muito mais rápido que deletar registros um a um.
Operações truncate não são seguras a transação; você iráobter um erro se você tiver uma transação ativa ou ativar um travamento de tabela.
O número de linhas apagadas não é retornado.
Uma vez que o arquivo de definição
nome_tabela.frm
deja válido, a tabela
pode ser recriada deta forma, mesmo se o arquivo de dados ou
de índice estiver corrompido.
TRUNCATE
é uma extensão Oracle SQL. Esta
instrução foi adicionada no MySQL 3.23.28, embora da versão
3.23.28 a 3.23.32, a palavra chave TABLE
deva
ser omitida.
REPLACE [LOW_PRIORITY | DELAYED] [INTO] nome_tabela [(nome_coluna,...)] VALUES (expressão,...),(...),... ou REPLACE [LOW_PRIORITY | DELAYED] [INTO] nome_tabela [(nome_coluna,...)] SELECT ... ou REPLACE [LOW_PRIORITY | DELAYED] [INTO] nome_tabela SET nome_coluna=expressão, nome_coluna=expressão,...
REPLACE
funciona exatamente como o
INSERT
, exceto que se um registro antigo na
tabela tem o mesmo valor que um novo registro em um índice
UNIQUE
ou PRIMARY KEY
, o
registro antigo é deletado antes que o novo registro seja
inserido. See Secção 6.4.3, “Sintaxe INSERT
”.
Em outras palavras, você não pode acessar os valores do
registro antigo em uma instrução REPLACE
.
Em algumas versões antigas do MySQL aparentemente você podia
fazer isto, mas era um bug que já foi arrumado.
Par aestar apto a utilizar REPLACE
você deve
ter privilégios INSERT
e
DELETE
para a tabela.
Quando você utilizar um comando REPLACE
,
mysql_affected_rows()
retornará 2 se a nova
linha substituir uma linha antiga. Isto é porque uma linha foi
inserida depois que a linha duplicada foi deletada.
Este fato torna fácil determinar se REPLACE
adicionou ou subsitituiu uma linha: verifique se o valor de
linhas afetadas é 1 (adicionado) ou 2 (substituido).
Note que a menos que a tabela utilize índices
UNIQUE
ou PRIMARY KEY
,
utilizar um comando REPLACE
replace não faz
sentido. Ele se torna equivalente a um
INSERT
, porque não existe índice a ser
usado para determinar se uma nova linha duplica outra.
Seqgue aqui o algoritmo usado em mais detalhes: (Ele também é
usado com LOAD DATA ... REPLACE
.
- Insere a linha na tabela - Enquanto ocorrer erro de chave duplicada para chaves primária ou única - Reverte as chaves alteradas - Le as linha conflitantes da tabela através do valor da chave duplicada - Deleta as linhas conflitantes - Tenta inserir o chave primária e única original na árvore
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE nome_tabela [FIELDS [TERMINATED BY '\t'] [[OPTIONALLY] ENCLOSED BY ''] [ESCAPED BY '\\' ] ] [LINES [STARTING BY ''] [TERMINATED BY '\n'] ] [IGNORE número LINES] [(nome_coluna,...)]
A instrução LOAD DATA INFILE
lê linhas de
uma arquivo texto para uma tabela em uma velocidade muito alta.
Se a palavra-chave LOCAL
é especificada, ela
é interpretada com respeito ao fim da conexão do cliente.
Quando LOCAL
é especificado, o arquivo é
lido pelo programa cliente na máquina cliente e enviada ao
servidor. Se LOCAL
não é especificada, o
arquivo deve estar localizado na máquina servidora e é lida
diretamente pelo servidor (LOCAL
está
disponível no MySQL Versão 3.22.6 ou posterior).
Por razões de segurança, ao ler arquivos textos no servidor,
os arquivos devem também estar no diretório de banco de dados
ou serem lidos por todos. Também, para utilizar LOAD
DATA INFILE
em arquivos do servidor, você deve ter
privilégio FILE
na máquina servidora. See
Secção 4.3.7, “Privilégios Fornecidos pelo MySQL”.
A partir do MySQL 3.23.49 e MySQL 4.0.2 (4.0.13 no Windows)
LOCAL
só funcionará se o seu servidor e o
seu cliente forem habilitados para permitir isto. Por exemplo so
o mysqld
foi iniciado com
--local-infile=0
, LOCAL
não
irá funcionar. See Secção 4.3.4, “Detalhes de Segurança com LOAD DATA LOCAL
”.
Se você especificar a palavra-chave
LOW_PRIORITY
, a execução da instrução
LOAD DATA
é atrasada até nenhum outro
cliente estar lendo a tabela.
Se você especificar a palavra-chave
CONCURRENT
com uma tabela
MyISAM
, outras threads podem retornar dados
da tabela enquanto LOAD DATA
está
executando. Utilizar esta opção irá afetar o desempenho de
LOAD DATA
um pouco, mesmo se nenhuma outra
thread utilizar a tabela ao mesmo tempo.
Utilizar LOCAL
será um pouco mais lento que
deixar o servidor acessar os arquivos diretamente, pois o
conteúdo do arquivo deve ser enviado pela conexão da máquina
cliente até a máquina servidora. Por outro lado, você não
precisa de ter o privilégio FILE
para
carregar arquivos locais.
Se você estiver utilizando uma versão do MySQL anterior a
3.23.24, você não poderá ler de um FIFO com LOAD
DATA INFILE
. Se você precisar ler de um FIFO (por
exemplo a saída de gunzip), utilize LOAD DATA LOCAL
INFILE
.
Você também pode carregar arquivo de dados utilizado o
utilitário mysqlimport
; ele opera enviando
um comando LOAD DATA INFILE
para o servidor.
A opção --local
faz com que
mysqlimport
leia ao arquivo de dados a partir
da máquina cliente. Você pode especificar a opção
--compress
para conseguir melhor desempenho
sobre redes lentas se o cliente e o servidor suportar protocolos
compactados.
Ao localizar arquivos na máquina servidora, o servidor utiliza as segintes regras:
Se um caminho absoluto é dado, o servidor utiliza o caminho desta forma.
Se um caminho relativo com um ou mais componentes é dados, o servidor busca o arquivo em relação ao diretório de dados do servidor.
Se um nome de arquivo sem nenhum componente é dado, o servidor procura pelo arquivo no diretorio de banco de dados do banco de dados atual.
Note que estas regras significam que um arquivo chamado
./myfile.txt
é lido no diretório de dados
do servidor, enquanto um arquivo chamado
myfile.txt
lê o diretório de dados do
naco de dados atual. Por exemplo, a seguinte instrução
LOAD DATA
lê o arquivo
data.txt
do diretório de dados de
db1
pois db1
é o banco de
dados atual, mesmo que a instrução carrega explicitamente o
arquivo em uma tabela no banco de dados db2
:
mysql>USE db1;
mysql>LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;
As palavras-chave REPLACE
e
IGNORE
controlam o tratamento de entrada de
registros que duplicam linhas existentes em valores de chave
única.
Se você especificar REPLACE
, as linhas
inseridas substituirão as linhas existentes (em outras
palavras, linhas que tiverem o mesmo valor de um índice
primário ou único como linhas existentes). See
Secção 6.4.7, “Sintaxe REPLACE
”.
Se você especificar IGNORE
, registros
inseridos que duplicam uma linha existente em um valor de chave
única será ignorados. Se você não especificar nenhuma das
opções, o comportamento depende de se a palavra chave
LOCAL
é especificada ou não. Sem
LOCAL
, um erro ocorre quando um valor de
chave duplicada é encontrado, e o resto do arquivo texto é
ignorado. Com LOCAL
o comportamento padrão
é o mesmo de quando IGNORE
for especificado,
isto é porque o servidor não tem como parar no meio da
operação.
Se você quiser ignorar as restrições de chaves estrangeiras
durante a carga você pode faze SET
FOREIGN_KEY_CHECKS=0
antes de executar LOAD
DATA
.
Se você utiliza LOAD DATA INFILE
em uma
tabela MyISAM
vazia, todos os índices
não-únicos são criados em um batch separado (como em
REPAIR
). Isto normalmente torna LOAD
DATA INFILE
muito mais rápido quando você tem
diversos índices. Normalmente isto é muito rápido mas em
casos extremos você pode tornar o índice mais rápido ainda
desligando-os com ALTER TABLE .. DISABLE KEYS
e usando ALTER TABLE .. ENABLE KEYS
para
recriar os índices. See Secção 4.5.6, “Utilizando myisamchk
para Manutenção de Tabelas e Recuperação em Caso de Falhas”.
LOAD DATA INFILE
é o complemento de
SELECT ... INTO OUTFILE
. See
Secção 6.4.1, “Sintaxe SELECT
”. Para gravar dados de uma tabela em um
arquivo, use SELECT ... INTO OUTFILE
. Para
ler o arquivo de volta em uma tabela, use LOAD DATA
INFILE
. A sintaxe das cláusulas
FIELDS
e LINES
é a mesma
para ambos os comandos. Ambas as cláusulas são opicionais, mas
FIELDS
deve preceder LINES
se ambos são especificados.
Se você especificar uma cláusula FIELDS
,
cada uma das subcláusulas (TERMINATED BY
,
[OPTIONALLY] ENCLOSED BY
, e ESCAPED
BY
) também são opicionais, exceto pelo fato de que
você deve especificar pelo menos uma delas.
Se você não especificar uma cláusula
FIELDS
, o padrão é o mesmo que se você
tivesse escrito isto:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
Se você não especificar uma cláusula
LINES
, o padrão é o mesmo que se você
tivesse escrito isto:
LINES TERMINATED BY '\n'
Nota: Se você gerou o arquivo
texto no Windows, você deve alterar o mostrado acima para:
LINES TERMINATED BY '\r\n'
já que o Windows
utiliza dois caracteres como um terminador de linha. Alguns
programas como wordpad
, pode usar
\r
como terminador de linha.
Se todas as linas que você deseja ler tem um prefixo comum que
você quer saltar, você pode usar LINES STARTING BY
prefix_string
.
Em outras palavras, o padrão faz com que LOAD DATA
INFILE
funcione da seguinte maneira ao se ler uma
entrada:
Procure pelo limite da linha em linhas novas.
Se LINES STARTING BY prefix
for usado,
lê até que o prefixo seja encontrado e começa a ler o
caracter seguinte ao prefixo. Se a linha não inclui o
prefico e;a será saltada.
Quebre a linha em campos na tabulações.
Não espere que os campos estejam entre aspas.
Interprete a ocorrência de tabulações, novas linhas ou
‘\
’ precedidos por
‘\
’ como caracteres literias
que são parte dos valores dos campos.
Inversamente, os padrões fazem SELECT ... INTO
OUTFILE
funcionar da seguinte forma ao escrever as
saídas:
Escreva tabulações entre os campos.
Não coloque campos entre aspas.
Utilize ‘\
’ para considerar
como parte dos campos instâncias de tabulação, nova linha
ou ‘\
’ que estejam dentro dos
valores dos campos.
Escreva novas linhas no fim de cada linha.
Note que para escrever FIELDS ESCAPED BY
'\\'
, você deve especificar duas barras invertidas
para que o valor seja lido como uma única barra invertida.
A opção IGNORE número LINES
pode ser
utilizado para ignorar linhas no inicio do arquivo. Por exemplo,
você pode usar IGNORE 1 LINES
para saltar
uma linha de cabeçalho contendo nomes de colunas:
mysql> LOAD DATA INFILE "/tmp/file_name" INTO TABLE test IGNORE 1 LINES;
Quando você utiliza SELECT ... INTO OUTFILE
em conjunto com LOAD DATA INFILE
para
escrever os dados de um banco de dados em um arquivo e então
ler o arquivo de volta no banco de dados posteriormente, as
opções para tratamento de linhas e campos para ambos os
comandos devem coincidir. Senão, LOAD DATA
INFILE
não irá interpretar o conteúdo do arquivo de
forma apropriada. Suponha que você utilize SELECT ...
INTO OUTFILE
para escrever um arquivo com os campos
separados por vírgulas:
mysql>SELECT * INTO OUTFILE 'data.txt'
->FIELDS TERMINATED BY ','
->FROM ...;
Para ler o arquivo delimitado com vírgula de volta, a instrução correta seria:
mysql>LOAD DATA INFILE 'data.txt' INTO TABLE table2
->FIELDS TERMINATED BY ',';
Se você tentasse ler do arquivo com a instrução abaixo, não
iria funcionar pois ela instrui LOAD DATA
INFILE
a procurar por tabulações entre campos:
mysql>LOAD DATA INFILE 'data.txt' INTO TABLE table2
->FIELDS TERMINATED BY '\t';
O resultado desejado é que cada linha de entrada fosse interpretada como um único campo.
LOAD DATA INFILE
pode ser usado para ler
arquivos obtidos de fontes externas. Por exemplo, um arquivo no
formato dBASE terá campos separados por vírgulas e entre aspas
duplas. Se as linhas no arquivo são terminadas por com uma nova
linha, o comando mostardo aqui ilustra as opções do tratamento
de campos e linhas que você usaria pra carregar o arquivo. the
file:
mysql>LOAD DATA INFILE 'data.txt' INTO TABLE nome_tabela
->FIELDS TERMINATED BY ',' ENCLOSED BY '"'
->LINES TERMINATED BY '\n';
Qualquer uma das opções de tratamento de campos e linhas podem
especificar uma string vazia (''
). Se não
for vazio, os valores de FIELDS [OPTIONALLY] ENCLOSED
BY
e FIELDS ESCAPED BY
devem ser um
caracter simples. Os valores de FIELDS TERMINATED
BY
e LINES TERMINATED BY
podem ser
mais de uma caracter. Por exemplo, para escrever linhas
terminadas pelos par retorno de carro/alimentação de linha, ou
para ler um arquivo contendo tais linhas, especifique uma
cláusula LINES TERMINATED BY '\r\n'
.
Por exemplo, para ler um arquivo de piadas, que são separadas
com uma linha de %%
, em uma tabela SQL, você
pode fazer:
CREATE TABLE jokes (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, joke TEXT NOT NULL); LOAD DATA INFILE "/tmp/jokes.txt" INTO TABLE jokes FIELDS TERMINATED BY "" LINES TERMINATED BY "\n%%\n" (joke);
FIELDS [OPTIONALLY] ENCLOSED BY
controla a
citação dos campos. Para saida (SELECT ... INTO
OUTFILE
), se você omitir a palavra
OPTIONALLY
, todos os campos estarão entra o
caracter ENCLOSED BY
. Um exemplo de tal
saída (usando vírgula como delimitador de campo) é mostrado
abaixo:
"1","a string","100.20" "2","a string containing a , comma","102.20" "3","a string containing a \" quote","102.20" "4","a string containing a \", quote and comma","102.20"
Se você especificar OPTIONALLY
, o caracter
ENCLOSED BY
só é usados para delimitar
campos CHAR
e VARCHAR
:
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a \" quote",102.20 4,"a string containing a \", quote and comma",102.20
Note que a ocorrência de caracter ENCLOSED
BY
dentro do valor do campo é indicado colocando um
caracter ESCAPED BY
antes dele. Note também
que se você especificar um valor ESCAPED BY
vazio, é possível gerar saídas que não poderão ser lidas
aprorpiadamente por LOAD DATA INFILE
. Por
exemplo, a saída mostrada seria apareceria como a seguir se o
caracter de escape fosse vazio. Observe que o segundo campo na
quarta linha contém uma vírgula seguida de aspas, o que
(erroneamente) parece terminar o campo:
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a " quote",102.20 4,"a string containing a ", quote and comma",102.20
Para entrada, o caracter ENCLOSED BY
, se
presente, será eliminado do fim dos valores dos campos. (Isto
é verdade se OPTIONALLY
for especificado;
OPTIONALLY
não tem efeito na interpretação
da entrada). A ocorrência de caracteres ENCLOSED
BY
precedido pelo caracter ESCAPED
BY
são interpretados como parte do campo atual.
Se o campo começa com o caracter ENCLOSED
BY
, instâncias daquele caracter são reconhecidos
como terminação de um valor do campo apenas se seguido pelo
campo ou sequência de linah TERMINATED BY
.
Para evitar ambiguidade, ocorrências do caracter
ENCLOSED BY
dentro de um valor de campo pode
ser duplicado e será interpretado como uma única instância do
caracter. Por exemplo, se ENCLOSED BY '"'
for
especificado, aspas serão tratadas como mostrado abaixo:
"The ""BIG"" boss" -> The "BIG" boss The "BIG" boss -> The "BIG" boss The ""BIG"" boss -> The ""BIG"" boss
FIELDS ESCAPED BY
controla como escrever ou
ler caracteres especiais. Se o caracter FIELDS ESCAPED
BY
não estivaer vazio, ele será usado para preceder
o seguinte caracter de saída:
O caracter FIELDS ESCAPED BY
O caracter FIELDS [OPTIONALLY] ENCLOSED
BY
O primeiro caracter dos valores FIELDS TERMINATED
BY
e LINES TERMINATED BY
ASCII 0
(o que é escrito seguido de um
caracter de escape é ASCII '0'
, não o
byte de valor zero).
Se o caracter FIELDS ESCAPED BY
estiver
vazio, nenhum caracter será ``escapado''. Provavelmente não é
uma boa idéia especificar um caracter de escape vazio,
principalmente se os valores dos campos em seus conter qualquer
caracter na lista dada.
Para entradas, se o caracter FIELDS ESCAPED
BY
não estiver vazio, as ocorrências daquele
caracter são eliminadas e o caracter seguinte é tomado como
parte do valor do campo. As exceções são um
‘0
’ ou
‘N
’ ``escapado'' (por exemplo,
\0
ou \N
se o caracter de
escape for ‘\
’). Estas sequencias
são interpretadas como os ASCII 0
(um byte
de valor zero) e NULL
. Veja abaixo as regras
no tratamento de NULL
.
Para maiores informações sobre a sintaxe
‘\
’-escape, veja
Secção 6.1.1, “Literais: Como Gravar Strings e Numerais”.
Em certos casos, as opções de tratamento de campoe e linhas se interagem:
Se LINES TERMINATED BY
é uma string
vazia e FIELDS TERMINATED BY
não é
vazio, as linhas também serão terminadas com
FIELDS TERMINATED BY
.
Se os valores FIELDS TERMINATED BY
e
FIELDS ENCLOSED BY
são ambos vazios
(''
), um formato de linha de tamanhos
fixos (sem delimitadores) é utilizada. Com formato de
linhas de tamanho fixo, nenhum deliitador é usado entre os
campos (mas você ainda pode ter um terminador de linha).
Valores de colunas são escritos e lidos usando o tamanho
definido das colunas. Por exemplo, se uma coluna é
declarada como INT(7)
, os valores das
colunas são escritos utilizando campos de 7 caracteres. Na
saída, os valores das colunas são obtidos lendo 7
caracteres.
LINES TERMINATED BY
ainda é usado para
separar linhas. Se uma linha não contém todos os campos, o
resto dos campos serão configurados com o seu valor
padrão. Se você não tiver um terminador de linha, você
deve defini-lo com ''
. Neste caso o
arquivo texto deve conter todos os campos para cada linha.
O formato de linhas de tamanho fixo também afetam o
tratamento de valores NULL
; veja abixo.
Note que este formato não funciona se você estiver
utilizando um conjunto de caracteres mulyi-byte.
O tratamento do valor NULL
varia, dependendo
das opções de FIELDS
e
LINES
que voce usar:
Para os valores FIELDS
e
LINES
padrões, NULL
é escrito como \N
para saída e
\N
é lido como NULL
para as entradas (assumindo que o caracter ESCAPED
BY
é ‘\
’).
Se FIELDS ENCLOSED BY
não for vazio, um
campo contendo a palavra literal NULL
como seu valor é lido como um valor NULL
(isto difere da palavra NULL
entre os
caracteres FIELDS ENCLOSED BY
, a qual é
lida como a string 'NULL'
).
Se FIELDS ESCAPED BY
for vazio,
NULL
é escrito como a palavra
NULL
.
Com os formatos de tamanho fixos (que acontecem quando
FIELDS TERMINATED BY
e FIELDS
ENCLOSED BY
estiverem ambos vazios),
NULL
é escrito como uma string vazia.
Note que isto faz com que os valores NULL
e uma string vazia na tabela serão indistingüíveis quando
escritas no arquivo pois elas são ambas escritas como
strings vazias. Se você precisar estar saber diferenciar as
duas ao ler o arquivo de volta, você não deve utilizar o
formato de tamanho fixo.
Alguns casos não são suportados por LOAD DATA
INFILE
:
Linhas de tamanho fixo (FIELDS TERMINATED
BY
e FIELDS ENCLOSED BY
vazios)
e colunas BLOB
ou
TEXT
.
Se você especificar um separador que é igual ao prefixo do
outro, LOAD DATA INFILE
não poderá
interpretar a entratada apropriadamente. Por exemplo, a
seguinte cláusula FIELDS
causaria
problemas:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
Se FIELDS ESCAPED BY
estiver vazio, um
valor de campo que contém uma ocorrência de
FIELDS ENCLOSED BY
ou LINES
TERMINATED BY
seguido por valores FIELDS
TERMINATED BY
fará com que LOAD DATA
INFILE
pare de ler um campo ou linha antes do
esperado. Isto ocorre porque LOAD DATA
INFILE
não pode determinar apropriadamente onde o
valor de campo ou linha acaba.
A oseguinte exemplo carrega todas as colunas da tablea
persondata
:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
Nenhuma lista de campo é especificada, assim LOAD DATA
INFILE
espera linhas de entradas que contenha um campo
para cada coluna da tabela. Os valores padrões de
FIELDS
e LINES
são
usados.
Se você deseja carregar somente algumas das colunas das tabelas, especifique uma lista de campos:
mysql>LOAD DATA INFILE 'persondata.txt'
->INTO TABLE persondata (col1,col2,...);
Você deve especificar uma lista de campos se a ordem dos campos no arquivo de entrada diferem da ordem das colunas na tabela. Senão o MySQL não poderá dizer como combinar os campos da entrada nas colunas da tabela.
Se uma linha tiver poucos campos, as colunas para os quais o
campo de entrada não estiverem presentes serão definidas com o
valor padrão. Atribuição de valor padrão é descrito em
Secção 6.5.3, “Sintaxe CREATE TABLE
”.
Um valor de campo vazio é interpretado de forma diferente de que se o valor do campo estiiver faltando:
Para tipos string, a coluna é definida com uma string vazia.
Para tipos numéricos, a coluna é definida com
0
.
Para tipos de data e hora, a coluna é definida com o valor ``zero'' apropriado para o tipo. See Secção 6.2.2, “Tipos de Data e Hora”.
Note que estes são os mesmos valores que resultam se você
atribuir uma string vazia explicitamente a um tipo string,
numérico, de data ou de hora em uma instrução
INSERT
ou UPDATE
.
Colunas TIMESTAMP
só são definidas com a
hora e data atual se houver um valor NULL
para a coluna (isto é, \N
), ou (apenas para
a primeira coluna TIMESTAMP
) se a coluna
TIMESTAMP
esta a esquerda da lista de campos
quando esta for especificada.
Se uma linha de entrada tiver muitos campos, os campos extras
serão ignorados e o número de avisos é incrementado. Note que
antes do MySQL 4.1.1 o aviso é apenas um número que indica que
alguma coisa deu errado. No MySQL 4.1.1 você pode fazer
SHOW WARNINGS
para obter mais informações
sobre o que deu errado.
LOAD DATA INFILE
considera todas as entradas
como strings, assim você não pode utiliar valores numéricos
para colunas ENUM
ou SET
do mesmo modo que você pode com instruções
INSERT
. Todos os valores
ENUM
e SET
devem ser
específicados como strings!
Se você estiver usando a API C, você pode obter informações
sobre a consulta chamando a função
mysql_info()
da API C quando a consulta
LOAD DATA INFILE
terminar. O formato da
string de informação é mostrado aqui:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
Avisos ocorrem sob as mesmas circuntâncias que quando são
inseridos via instrução INSERT
(see
Secção 6.4.3, “Sintaxe INSERT
”), exceto que LOAD DATA
INFILE
também gera avisos quando houver poucos ou
muitos campos na linha de entrada. Os avisos não são
armazenados em nenhum local; o número de avisos só pode ser
utilizado como uma indicação se tudo correr bem.
Se você obter avisos e quiser saber exatamente porque eles
ocorreram, um modo de se fazer isto é utilizar SELECT
... INTO OUTFILE
em outro arquivo e camporá-lo ao
arquivo de entrada original.
Se você precisar que LOAD DATA
leia de um
pipe, você pode utilizar o seguinte truque:
mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
Se você estiver usando uma versão do MySQL a anterior a
3.23.25 você só poderá fazer o descrito acima com
LOAD DATA LOCAL INFILE
.
No MySQL 4.1.1 você pode usar SHOW WARNINGS
para conseguir a lista do primeiros
max_error_count
avisos. See
Secção 4.6.8.9, “SHOW WARNINGS | ERRORS
”.
Para mais informações sobre a eficiência de
INSERT
versus LOAD DATA
INFILE
e a melhora na velocidade de LOAD DATA
INFILE
, See Secção 5.2.10, “Performance das Consultas que Utilizam INSERT
”.
HANDLER nome_tabela OPEN [ AS alias ] HANDLER nome_tabela READ nome_indice { = | >= | <= | < } (valor1,valor2,...) [ WHERE ... ] [LIMIT ... ] HANDLER nome_tabela READ nome_indice { FIRST | NEXT | PREV | LAST } [ WHERE ... ] [LIMIT ... ] HANDLER nome_tabela READ { FIRST | NEXT } [ WHERE ... ] [LIMIT ... ] HANDLER nome_tabela CLOSE
A instrução HANDLER
fornece acesso direto a
interface do mecanismo de armazenamento de tabelas
MyISAM
.
A primeira forma da instrução HANDLER
abre
uma tabela, tornando a acessível através de subsequentes
instruções HANDLER ... READ
. Este objeto de
tabela não é copartilhada com outras threads e não serão
fechadas até que as chamadas de thread HANDLER
nome_tabela CLOSE
ou a thread termine.
A segunda forma busca um registro (ou mais, especificado pela
cláusula LIMIT
) onde o índice especificado
satisfaz os valores dados e a condição
WHERE
é encontrada. Se você tiver um
índice multi-coluna, especifique as colunas do índice como uma
lista separadas por vírgulas. Especifique o valor de todas as
colunas no índice, ou especifique valores para o prefixo mais a
esquerda das colunas índices. Suponha que um índice inclui
três colunas chamadas col_a
,
col_b
, e col_c
, nesta
ordem. A instrução HANDLER
pode especificar
valores para todas as três colunas no índice, ou para as
colunas no prefixo mais a esquerda. Por exemplo:
HANDLER ... index_name = (col_a_val,col_b_val,col_c_val) ... HANDLER ... index_name = (col_a_val,col_b_val) ... HANDLER ... index_name = (col_a_val) ...
A terceira forma busca uma linha (ou mais, especificado pela
cláusula LIMIT
) da tabela na ordem do
índice, correspondendo a condição WHERE
.
A quarta forma (sem especificação de índice) busca um
registro (ou mais, especificado pela cláusula
LIMIT
) da tabela na ordem natural da linhas
(como armazenado no arquivo de dados) de acordo com a condição
WHERE
é mais rápido que HANDLER
nome_tabela READ nome_indice
quando é necessária uma
varredura completa da tabela.
HANDLER ... CLOSE
fecha uma tabela que foi
aberta com HANDLER ... OPEN
.
Nota: Se você estiver utilizando a interface
HANDLER
para PRIMARY KEY
você deve se lembrar de colocar o nome entre aspas:
HANDLER tbl READ `PRIMARY` > (...)
HANDLER
é uma instrução de baixo nível.
Por exemplo, ela não fornece consitência. Isto é,
HANDLER ... OPEN
NÃO pega uma imagem
instântanea da tabela, e NÃO
trava a tabela. Isto significa que depois que um
HANDLER ... OPEN
é feito, os dados da tabela
podem ser modificados (por esta ou outra thread) e estas
modificações podem aparecer apenas parcialmente nas buscas
HANDLER ... NEXT
ou HANDLER ...
PREV
.
As razões para se utilizar esta interface em vez do SQL normal são:
Ela é mais rápida que SELECT
porque:
Um mecanismo de armazenamento designado é alocado pela
thread em HANDLER OPEN
.
Existe menos análise envolvida.
Nào existe sobrecaga de otimização e verificação de consultas.
A tabela utilizada não precisa estar travada em pedidos de dois handlers.
A interface handler não precisa fornecer uma aprência consistente dos dados (por exemplo, dirty-reads são permitidas), assim o mecanismo de armazenamento pode fazer otimizações que o SQL normalmente não permite.
É muito mais fácil portar aplicações que usam interface como ISAM para o MySQL.
Ele permite se fazer uma travessia em um banco de dados de uma maneira que não é facil (em alguns casos impossível) de fazer com SQL. A interface handler é um modo mais natural de mostrar dados ao trabalhar com aplicações que fornecem uma interface interativa com o usuário para o banco de dados.
DO expressão, [expressão, ...]
Executa a expressão mas não retorna nenhum resultado. Este é
um modo curto de SELECT expressão,
expressão
, mas tem a vantagem de ser rápida quando
você não se preocupa com o resultado.
Ele é útil principalmente com funções que tem efeitos em um
dos lados, como RELEASE_LOCK
.
CREATE DATABASE [IF NOT EXISTS] nome_bd
CREATE DATABASE
cria um banco de dados com o
nome dados.
As regras para os nomes de banco de daddos permitidos são daods
em Secção 6.1.2, “Nomes de Banco de dados, Tabela, Índice, Coluna e Alias”. Um erro ocorre se o banco de
dados já existir e você não especificou IF NOT
EXISTS
.
Banco de dados no MySQL são implementados como diretórios
contendo arquivos que correspondem a tabelas no banco de dados.
Por não haver tabelas em um banco de dados quando ele é
criado, a instrução CREATE DATABASE
apenas
cria um diretório sob o diretório de dados do MySQL.
Você também pode criar banco de dados com
mysqladmin
. See
Secção 4.9, “Utilitários e Scripts do Lado do Cliente MySQL”.
DROP DATABASE [IF EXISTS] nome_bd
DROP DATABASE
deleta todos as tabelas no
banco de dados e deleta o banco de dados. Se você fizer um
DROP DATABASE
em um banco de dados ligado
simbolicamente, o link e o banco de dados original são
deletados. Tenha cuidado com este
comando!
DROP DATABASE
retorna o número de arquivos
que foram removidos do diretorio de banco de dados. Para tabelas
MyISAM
, isto é três vezes o número de
tabelas, pois cada tabela corresponde a um arquivo
.MYD
, um arquivo .MYI
e um arquivo .frm
.
O comando DROP DATABASE
remove do diretório
de banco de dados dado todos os arquivos com a seguinte
extensão:
Ext | Ext | Ext | Ext |
.BAK | .DAT | .HSH | .ISD |
.ISM | .ISM | .MRG | .MYD |
.MYI | .db | .frm |
Todos os subdiretórios que consistem de 2 digitos (diretórios
RAID
) também são removidos.
No MySQL Versão 3.22 ou posterior, você pode utilizar a
palavra chave IF EXISTS
para prevenir da
ocorrência de um erro se o banco de dados não existir.
Você também pode deletar um banco de dados com
mysqladmin
. See
Secção 4.9, “Utilitários e Scripts do Lado do Cliente MySQL”.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nome_tabela [(definição_create,...)] [table_options] [select_statement] ou CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nome_tabela [(]LIKE nome_antigo_tabela[)]; definição_create: nome_coluna tipo [NOT NULL | NULL] [DEFAULT valor_padrão] [AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT 'string'] [definição_referência] | [CONSTRAINT [symbol]] PRIMARY KEY (index_col_name,...) | KEY [nome_indice] (index_nome_coluna,...) | INDEX [nome_indice] (index_nome_coluna,...) | [CONSTRAINT [symbol]] UNIQUE [INDEX] [index_name] (index_col_name,...) | FULLTEXT [INDEX] [nome_indice] (index_nome_coluna,...) | [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [definição_referência] | CHECK (expr) tipo: TINYINT[(tamanho)] [UNSIGNED] [ZEROFILL] | SMALLINT[(tamanho)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(tamanho)] [UNSIGNED] [ZEROFILL] | INT[(tamanho)] [UNSIGNED] [ZEROFILL] | INTEGER[(tamanho)] [UNSIGNED] [ZEROFILL] | BIGINT[(tamanho)] [UNSIGNED] [ZEROFILL] | REAL[(tamanho,decimais)] [UNSIGNED] [ZEROFILL] | DOUBLE[(tamanho,decimais)] [UNSIGNED] [ZEROFILL] | FLOAT[(tamanho,decimais)] [UNSIGNED] [ZEROFILL] | DECIMAL(tamanho,decimais) [UNSIGNED] [ZEROFILL] | NUMERIC(tamanho,decimais) [UNSIGNED] [ZEROFILL] | CHAR(tamanho) [BINARY | ASCII | UNICODE] | VARCHAR(tamanho) [BINARY] | DATE | TIME | TIMESTAMP | DATETIME | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT | TEXT | MEDIUMTEXT | LONGTEXT | ENUM(value1,value2,value3,...) | SET(value1,value2,value3,...) index_nome_coluna: nome_coluna [(tamanho)] [ASC | DESC] definição_referência: REFERENCES nome_tabela [(index_nome_coluna,...)] [MATCH FULL | MATCH PARTIAL] [ON DELETE opção_referência] [ON UPDATE opção_referência] opção_referência: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT opções_tabela: table_option [table_option] ... opções_tabela: TYPE = {BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM } | AUTO_INCREMENT = # | AVG_ROW_LENGTH = # | CHECKSUM = {0 | 1} | COMMENT = 'string' | MAX_ROWS = # | MIN_ROWS = # | PACK_KEYS = {0 | 1 | DEFAULT} | PASSWORD = 'string' | DELAY_KEY_WRITE = {0 | 1} | ROW_FORMAT = { DEFAULT | DYNAMIC | FIXED | COMPRESSED } | RAID_TYPE = { 1 | STRIPED | RAID0 } RAID_CHUNKS=# RAID_CHUNKSIZE=# | UNION = (table_name,[table_name...]) | INSERT_METHOD = { NO | FIRST | LAST } | DATA DIRECTORY = 'caminho absluto para o diretório' | INDEX DIRECTORY = 'caminho absluto para o diretório' | DEFAULT CHARACTER SET character_set_name [COLLATE collation_name] instrução_select: [IGNORE | REPLACE] [AS] SELECT ... (Alguma instrução válida)
CREATE TABLE
cria uma tabela com op nome dado
no banco de dados atual.
As regras para nomes de tabelas permitidos são dados em Secção 6.1.2, “Nomes de Banco de dados, Tabela, Índice, Coluna e Alias”. Por padrão a tabela é criada no banco de dados atual. Um erro ocorre se não houver o banco de dados atual ou se a tabela já existir.
No MySQL Versão 3.22 ou posterior, o nome de tabela pode ser
especificado como nome_bd.nome_tabela
para
criar a tabela em um banco de dados específico. Ele funciona
sem se preoocupar se existe um banco de dados atual.
A partir do MySQL Versão 3.23, você pode usar a palavra-chave
TEMPORARY
qaundo você criar uma tabela. A
tabela temporária é visível apenas a para a conexão atual, e
será automaticamente deletada quando a conexão é fechada.
Isto significa que duas conexões diferentes podem usar o mesmo
nome de tabela temporária sem conflitos outras ou com uma
tabela existente com o mesmo nome. (A tabela existente é
escondida até que a tabela temporária seja deletada). A partir
do MySQL 4.0.2 você deve ter o privilégio CREATE
TEMPORARY TABLES
para poder criar tabelas
temporárias.
No MySQL Versão 3.23 ou posterior você pode utilizar as
palavras-chaves IF NOT EXISTS
para que não
ocorra um erro se a tabela já existir. Note que não há
verificação de que a tabela existente tem uma estrutura
idêntica a aquela indicada pela instrução CREATE
TABLE
A partir da versão 4.1.0, o atributo SERIAL
pode ser usado com um alias para BIGINT NOT NULL
AUTO_INCREMENT UNIQUE
. Este é um recuros para
compatibilidade.
Como no MySQL 3.23, você pode criar uma tabela de autra
adicionando uma instrução SELECT
no fim da
instrução CREATE TABLE
:
CREATE TABLE new_tbl SELECT * FROM orig_tbl;
Os índices não são transportados para a nova tabela, e
algumas conversões de tipos de coluna podem ocorrer. Por
exemplo, o atributoAUTO_INCREMENT
não está
preservado e colunas VARCHAR
podem se tornar
colunas CHAR
.
Quando criar uma tabela com CREATE ...
SELECT
, de um apelido para qualquer chamada de
função ou expressões em uma consulta. Se você não o fizer,
a instrução CREATE
pode falhar ou resultar
em nomes de colunas indesejáveis.
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;
No MySQL 4.1, você pode especificar explicitamente o tipo para uma coluna gerada:
CREATE TABLE foo (a tinyint not null) SELECT b+1 AS 'a' FROM bar;
No MySQL 4.1 você pode utilizar LIKE
para
criar uma tabela baseada em uma definição de outra tabela. No
MySQL 4.1 você também pode especificar o tipo para uma coluna
gerada:
CREATE TABLE new_tbl LIKE orig_tbl;
Cada tabela nome_tabela
é representada por
algum arquivo no diretório de banco de dados. No caso das
tabelas tipo MyISAM
você irá obter:
CREATE TABLE ... LIKE
não copia nenhuma
opção de tabela DATA DIRECTORY
ou
INDEX DIRECTORY
que foi especificada para a
tabela original.
Arquivo | Proposito |
nome_tabela.frm | Arquivo de formato (definição) da tabela. |
nome_tabela.MYD | Arquivo de dados |
nome_tabela.MYI | Arquivo Índice |
Para mais informações de propriedades de varios tipo de coluna, veja Secção 6.2, “Tipos de Campos”:
Se nem NULL
nem NOT
NULL
for especificado, a coluna é tratada como se
NULL
fosse especificado.
Uma coluna integer pode ter o atributo adicional
AUTO_INCREMENT
. Quando você insere um
valor de NULL
(recomendado) ou
0
em uma coluna
AUTO_INCREMENT
indexada, a coluna é
definida com o valor da próxima sequência. Normalmente ele
é valor+1
, onde valor
é o maior valor para a coluna column atualmente na tabela.
A sequência de AUTO_INCREMENT
começa
com 1
. See
Secção 12.1.3.32, “mysql_insert_id()
”.
A partir do MySQL 4.1.1, especificando o parâmetro
NO_AUTO_VALUE_ON_ZERO
para a opção do
servidor --sql-mode
ou a variável do
servidor sql_mode
permite que você
aramzene 0
nas colunas
AUTO_INCREMENT
como 0
,
em vez de gerar uma nova sequência de valores. See
Secção 4.1.1, “Opções de Linha de Comando do mysqld
”.
Se você deletar a linha contendo o valor máximo para uma
coluna AUTO_INCREMENT
, o valor será
reutilizado por uma tabela ISAM
, ou
BDB
, mas não por tabelas
MyISAM
ou InnoDB
. Se
você deletar todas as linhas na sua tabela com
DELETE FROM nome_tabela
(sem um
WHERE
) no modo
AUTOCOMMIT
, a sequencia será reiniciada
em todos os tipos de tabela, exceto
InnoDB
. See
Secção 7.5.12.5, “Como Funciona uma Coluna AUTO_INCREMENT
no InnoDB”.
Nota: Só pode haver uma
coluna AUTO_INCREMENT
por tabela, e ela
deve ser indexada e não pode ter uma valor
DEFAULT
. No MySQL Versão 3.23, uma
coluna AUTO_INCREMENT
funcionará
corretamente apenas se conter apenas valores positivos.
Inserir um número negativo é considerado como a inserção
de um número positivo muito grande. Isto ocorre para evitar
problemaa de precisão quando os números vão de positivo
para negativo e também para assegurar que não se obtenha,
acidentalmente, uma coluna AUTO_INCREMENT
que contenha 0.
Em tabelas MyISAM
e
BDB
você pode especificar colunas
AUTO_INCREMENT
secundárias em uma chave
ulti-coluna. See Secção 3.6.9, “Usando AUTO_INCREMENT
”.
Para tornar MySQL compatível com alguns aplicativos ODBC,
você pode encontrar o valor
AUTO_INCREMENT
da última linha inserida
com a seguinte consulta:
SELECT * FROM nome_tabela WHERE auto_col IS NULL
Valores NULL
são tratados em colunas
TIMESTAMP
de modo diferente de outros
tipos de colunas. Você não pode armazenar um
NULL
literal em uma coluna
TIMESTAMP
; definindo a coluna com
NULL
lhe atribui a a data e a hora atual.
Como colunas TIMESTAMP
se comportam desta
forma, os atributos NULL
e NOT
NULL
não se aplicam de modo normal e são
ignorados se você os especificar.
Por outro lado, tornar o uso de colunas
TIMESTAMP
mais fácil para os clientes
MySQL, o servidor relata que tal coluna pode ter o valor
NULL
atribuído (a que é verdade), mesmo
que TIMESTAMP
nunca contenham, realmente,
um valor NULL
. Você pode ver isto quando
você utiliza DESCRIBE nome_tabela
para
obter informações sobre sua tabela.
Note que definir uma coluna TIMESTAMP
com
0
não é o mesmo que definí-la com
NULL
, porque 0
é um
valor TIMESTAMP
válido.
Um valor padrão (DEFAULT
) tem que ser
constante, ele não pode ser uma função ou uma expressão.
Se nenhum valor DEFAULT
é especificado
para uma coluna, o MySQL atribuirá um automaticamente, como
a seguir.
Se a coluna aceitar NULL
como um valor, o
valor padrão é NULL
.
Se a coluna é declarada como NOT NULL
, o
valor padrão depende do tipo de coluna:
Para tipos numéricos não declarados com o atributo
AUTO_INCREMENT
, o padrão é
0
. Para uma coluna
AUTO_INCREMENT
, o valor padrão é o
próximo valor na sequência.
Para tipos date e time diferentes de
TIMESTAMP
, o padrão é o valor zero
apropriado para o tipo. Para a primeira coluna
TIMESTAMP
na tabela, o padrão é a
data e hora atuais. See
Secção 6.2.2, “Tipos de Data e Hora”.
Para tipos string diferentes de ENUM
,
o valor padrão é uma string vazia. Para
ENUM
, o padrão é o primeiro valor
enumerado.
Valores padrões devem ser constantes. Isto significa, por
exemplo, que você não pode definir o padrão de uma coluna
date como o valor de funções como NOW()
or CURRENT_DATE
.
Um comentário para uma coluna pode ser especificado com a
opção COMMENT
. O comentário é
mostrado pela instrução SHOW CREATE
TABLE
e por SHOW FULL COLUMNS
.
Esta opção está disponível a partir do MySQL 4.1. (Ela
é perimitida mas ignorada em versões anteriores.)
KEY
é normalmente um sinônimo para
INDEX
. A partir da versão 4.1, o
atributo de chave PRIMARY KEY
também
pode ser especificado apenas como KEY
.
Isto foi implementado para compatibilidade com outros bancos
de dados.
No MySQL,uam chave UNIQUE
só pode ter
valores distintos. Um erro ocorre se você tantar adicionar
uma nova linha com uma chave que coincida com uma já
existente.
PRIMARY KEY
é uma chave única
(KEY
) onde todas as colunas chaves devem
ser definidas como NOT NULL
. Se elas não
forem explicitamente declaradas como NOT
NULL
, isto será feito implicitamente e sem aviso.
No MySQL a chave é chamada PRIMARY
. Uma
tabela pode ter apenas uma PRIMARY KEY
.
Se você não tiver uma PRIMARY KEY
e
alguma aplicação perguntar pela PRIMARY
KEY
em sua tabela, o MySQL retornará a primeira
chave UNIQUE
, que não possui nenhuma
coluna NULL
, como a PRIMARY
KEY
.
Uma PRIMARY KEY
pode ser um índice
multi-coluna. Porém, você não pode criar um índice
multi-coluna usando o atributo de chave PRIMARY
KEY
em uma especificação de coluna. Fazendo
assim apenas colunas simples poderão ser marcadas como
primárias. Você deve utilizar uma cláusula
PRIMARY KEY(index_nome_coluna, ...)
separada.
Um índice UNIQUE
é aquele no qual todos
os valores no índice devem ser distintos. A exceção a
isto é que se for permtido conter valores
NULL
em uma coluna no índice, ele pode
conter múltiplos valores NULL
. Este
exceção não se aplica a tabelas BDB
,
que permitem apenas um único NULL
.
Se a chave PRIMARY
ou
UNIQUE
consistir de apenas uma coluna e
ela é do tipo inteiro, você também poderá se referir a
ela como _rowid
(novo na versão
3.23.11).
Se você não atribuir um nome ao índice que não é um
PRIMARY KEY
, ele terá o mesmo nome da
prmeira index_nome_coluna
, com um sufixo
opicional (_2
, _3
,
...
) para torná-lo único. Você pode
nome de índices para uma tabela usando SHOW INDEX
FROM nome_tabela
. See
Secção 4.6.8.1, “Recuperando Informações sobre Bancos de Dados, Tabelas, Colunas e Índices”.
Apenas os tipos de tabelas MyISAM
,
InnoDB
, e BDB
suportam
índices em coluna que possam ter valores
NULL
. Nos outros casos você deve
declarar tais colunas NOT NULL
ou um erro
será retornado.
Com a sintaxe nome_coluna(length)
em uma
especificação de índice, você pode criar um índice que
utiliza apenas os primeiros length()
bytes de uma coluna CHAR
ou
VARCHAR
. Isto pode tornar o arquivo de
índices muito menor. See Secção 5.4.4, “Índices de Colunas”.
Apenas os tipos de tabela MyISAM
e (a
partir do MySQL 4.0.14) InnoDB
suportam
índice em colunas BLOB
e
TEXT
. Ao colocar um índice em uma coluna
BLOB
ou TEXT
você
sempre DEVE especificar o tamanho do índice, até 255
bytes. Por exemplo:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
Uma especificação index_col_name
pode
finalizar com ASC
ou
DESC
. Esta palavras chaves são
permitidas para estensão futura para especificar o
armazenamento do valor do índice em crescente ou
decrescente. Atualmente elas são analisadas mas ignoradas;
valores de índice são sempre armazenados em ordem
crescente.
Quando você utiliza ORDER BY
ou
GROUP BY
com uma coluna
TEXT
ou BLOB
, o
servidor ardena valores usando apenas o número inicial de
bytes, indicado pela variável do servidor
max_sort_length
. See
Secção 6.2.3.2, “Os Tipos BLOB
e TEXT
”.
No MySQL Versão 3.23.23 ou posterior, você também pode
criar índices FULLTEXT
especiais. Eles
são usados para busca full-text. Apenas o tipo de tabela
MyISAM
suporta índices
FULLTEXT
. Eles só podem ser criados em
colunas CHAR
, VARCHAR
,
e TEXT
. A indexação sempre ocorre sobre
toda a coluna; índices parciais não são suportados. Veja
Secção 6.8, “Pesquisa Full-text no MySQL” para detalhes de
operação.
No MySQL Versão 3.23.44 ou posterior, tabelas
InnoDB
suportam verificação de chaves
estrangeiras. See Secção 7.5, “Tabelas InnoDB
”. Note que a
sintaxe FOREIGN KEY
no
InnoDB
é mais restrita que a sintaxe
apresentada acima. As colunas da tabela indicada devem ser
nomeadas explicitmente. O InnoDB suporta ambas as ações
ON DELETE
e ON UPDATE
em chaves esrtrangiras nos MySQL 3.23.50 e 4.0.8,
respectivamente. Veja a seção InnoDB
do
manual para a sintaxe precisa. See
Secção 7.5.5.2, “Restrições FOREIGN KEY
”. Para
outros tipos de tabelas, MySQL Server analisa as sinatxes
FOREIGN KEY
, CHECK
e
REFERENCES
no comando CREATE
TABLE
, mas sem tal ação ser tomada. See
Secção 1.8.4.5, “Chaves Estrangeiras”.
Para tabelas ISAM
e
MyISAM
, cada coluna
NULL
tem um bit extra, arredondado para o
byte mais próximo. O tamanho máximo de um registro em
bytes pode ser calculado como a seguir:
tamanho da linha = 1 + (soma do tamanho da coluna) + (números de coluna NULL + delete_flag 7)/8 + (número de colunas de tamanho variável)
delete_flag
é 1 para tabelas com formato
de registro estático. Tabelas estáticas usam um bit no
registro para um parâmetro que indica se o linha foi
deletada. delete_flag
é 0 para tabelas
dinâmicas porque este parâmetro é armazenado no
cabeçalho da linha dinâmica.
Estes cálculos não se aplicam à tabelas
InnoDB
, para a qual o tamanho do
armazenamento não é diferente para colunas
NULL
comparados a colunas NOT
NULL
.
A opçao opção_tabela
e
SELECT
só são implmentadas no MySQL
Versão 3.23 e acima.
A opção TYPE
para especificar o tipo de
tabela possui os seguintes valores:
Tipo de tabela | Descrição |
BDB ou BerkeleyDB | Tabelas de transação segura com bloqueio de página. See
Secção 7.6, “Tabelas BDB ou BerkeleyDB ”. |
HEAP | Os dados desta tabela são armazenados apenas na memória. See
Secção 7.4, “Tabelas HEAP ”. |
ISAM | O mecanismo de armazenamento original. See Secção 7.3, “Tabelas ISAM ”. |
InnoDB | Tabelas com transações eguras com bloqueio de linha. See
Secção 7.5, “Tabelas InnoDB ”. |
MERGE | Uma coleção de tabelas MyISAM usadas como uma tabela. See
Secção 7.2, “Tabelas MERGE ”. |
MRG_MyISAM | Um apelido para tabelas MERGE |
MyISAM | O novo mecanismo de armazenamento portável binário que substitui o
ISAM. See Secção 7.1, “Tabelas MyISAM ”. |
See Capítulo 7, Tipos de Tabela do MySQL.
Se um tipo de tabela é especificado, e este tipo não está
disponível, MySQL irá usar MyISAM
. Por
exemplo, se uma definição de tabela inclui a opção
TYPE=BDB
mas o MySQL não suporta tabelas
BDB
, a tabela será criada como uma
tabela MyISAM
. Isto torna possível de se
ter uma configuração de replicação onde você tem
tabelas transacionaisno master mas as tabelas criadas no
slave são não transacionais (para obter mais velocidade).
No MySQL 4.1.1 você obtém um aviso se o tipo de tabela
especificado não é aceito.
Os outros tipos de tabelas são utilizados para otimizar o comportamento da tabela. Na maioria dos casos, você não precisa especificar nenhuma delas. As opções funcionam com todos os tipos, a menos que haja indicação:
Opção | Descrição |
AUTO_INCREMENT | O próximo valor AUTO_INCREMENT que você quer
definir em sua tabela (apenas
MyISAM ; para definir o primeiro
valor auto incrementeem uma tabela InnoDB insira uma
linha com um valor de menos um e delete esta linha). |
AVG_ROW_LENGTH | Uma aproximação do tamanho médio de linha em sua tabela. Você só precisa definí-la para tabelas grnades com tamanho de registros variáveis. |
CHECKSUM | Defina com 1 se você quiser manter um checksum para todas as linha
(deixa a tabela um pouco mais lenta para
atualizações, mas fica mais fácil encontrar
tabelas corrompidas) (apenas
MyISAM ). |
COMMENT | Um comentário de 60 caracteres para a sua tabela. |
MAX_ROWS | Número máximo de linhas que você deseja armazenar na tabela. |
MIN_ROWS | Número mínimo de linha que você planeja armazenar na tabela. |
PACK_KEYS | Defina com 1 se você quiser um índice menor, Normalmente torna a
atualização mais lenta e a leitura mais rápida
(apenas MyISAM e
ISAM ). Definr com 0 irá
desabilitar empacotamento das chaves. Definir com
DEFAULT (MySQL 4.0) dirá ao
mecanismo de armazenamento para empacotar apenas
colunas
CHAR /VARCHAR
longas. |
PASSWORD | Criptografa o arquivo .frm com uma senha. Esta
opção não fa nada na versão padrão do MySQL. |
DELAY_KEY_WRITE | Defina com 1 se quiser atrasar a atualização das chaves da tabela até
que a tabela seja fechada (apenas
MyISAM ). |
ROW_FORMAT | Define como as linhas devem ser armazenadas. Atualmente esta opção só
funciona com tabelas MyISAM , as
quais suportam os formatos de linha
DYNAMIC e
FIXED . See
Secção 7.1.2, “Formatos de Tabelas MyISAM ”. |
Quando você utiliza uma tabela MyISAM
,
MySQL usa o produto de MAX_ROWS *
AVG_ROW_LENGTH
para decidir o tamanho da tabela
resultante. Se você não especificar qualquer uma das
opções acima, o tamanho máximo de uma tabela será 4G (ou
2G se o seu sistema operacional só suporta tabelas de 2G).
A razão para isto é apenas manter o tamanho dos ponteiros
baixo para tornar o índice menor e mais rápido se você
realmente não precisa de tabelas grandes.
Se você não utilizar PACK_KEYS
, o
padrão é só empacotar strings, não números. Se você
utilizar PACK_KEYS=1
, números também
serão empacotados.
Ao empacotar chaves numéricas binárias, o MySQL usará a
compactação prefixada. Isto significa que você só terá
grandes benefícios disto se você tiver muitos números
iguais. Compactação prefixada significa que toda a chave
precisa de um byte extra para indicar quantos bytes das
caves anteriores são o mesmo da próxima chave (note que o
ponteiro para a linha é armazenado na ordem do byte mais
alto em primeiro diretamente depois da chave, para aumentar
compactação). Isto significa que se você tiver muitas
chaves iguais em duas linhas consecutivas, todas os chaves
``iguais'' seguintes irão normalmente ter apenas 2 bytes
(incluindo o ponteiro para a linha). Compare isto isto ao
caso comum onde as chaves seguintes irão levar
tamanho_armazenamento_chave + tamanho_ponteiro (nomralmente
4). Por outro lado, se todas as chaves são totalmente
diferente, você usará 1 byte por chave, se a chave não
puder ter valores NULL
. (Neste caso o
tamanho da chave empacotada será armazenado no mesmo byte
que é usado para marcar se a chave é
NULL
.)
No MySQL 3.23, Se você especificar um
SELECT
depois de uma instrução
CREATE
, MySQL criará novos campos para
todos os elemento em SELECT
. Por exemplo:
mysql>CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
->PRIMARY KEY (a), KEY(b))
->TYPE=MyISAM SELECT b,c FROM test2;
Isto irá criar uma tabela MyISAM
com
três colunas, a, b e c. Note que as colunas da instrução
SELECT
são inseridas do lado correto da
tabela, nào sobreposta nela. Considere o seguinte exemplo:
mysql>SELECT * FROM foo;
+---+ | n | +---+ | 1 | +---+ mysql>CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>SELECT * FROM bar;
+------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec)
Para cada linha na tabela foo
, uma linha
é inserida em bar
com os valores de
foo
e os valores padrões para a nova
coluna.
CREATE TABLE ... SELECT
não irá criar
automaticamente nenhum índice para você. Isto é feito
intencionalmente para deixar o comando o mais flexível
possível. Se você quiser ter índices em uma tabela
criada, você deve especificá-lo antes da instrução
SELECT
:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Se ocorrer qualquer erro durante enquanto os dados são copiados para a tabela, ele será automaticamente deletado.
Você pode preceder o SELECT
por
IGNORE
ou REPLACE
para
indicar como tratar registros que duplicam valores de chave
única. Com IGNORE
, novos registros que
duplicam um registro existente em um valor de chave única
são descartados. Com REPLACE
, novos
registros substituem registros que tem o mesmo valor de
chave única. Se nem IGNORE
nem
REPLACE
são especificados, valir de
chave unica duplicados resultam em erro.
Para assegurar que o log binário/atualização pode ser
usado para recriar a tabela original, MySQL não permitirá
inserções concorrentes durante um CREATE TABLE
... SELECT
.
A opção RAID_TYPE
irá ajudá-lo a
exceder o limite de 2G/4G limit para arquivo de dados MyISAM
(não o arquivo de índice) em sistemas operacionais que
não suportam arquivos grandes. Note que esta opção não
é recomendada para sistema de arquivos que suportam
arquivos grandes!
Você pode obter mais velocidade da gargalo de E/S colocando
diretorios RAID
em diferentes discos
físicos. RAID_TYPE
funcionará em
qualquer sistema operacional, desde que você tenha
configurado o MySQL com --with-raid
. Por
agora o único RAID_TYPE
permitido é
STRIPED
(1
e
RAID0
são utilizados para isto).
Se você especificar RAID_TYPE=STRIPED
para tabeals MyISAM
,
MyISAM
criará subdiretórios
RAID_CHUNKS
chamados 00, 01, 02 no
diretório de banco de dados. Em cada um destes diretórios
MyISAM
criará uma
nome_tabela.MYD
. Ao escrever dados no
arquivo de dados, o manipulador RAID
irá
mapear o primeiro RAID_CHUNKSIZE
*1024
bytes para o primeiro arquivo e os próximos
RAID_CHUNKSIZE
*1024 bytes para o
próximo arquivo.
UNION
é utilizado quando você quer
utilizar uma coleção de tabelas identicas como uma. Isto
só funciona com tabelas MERGE
. See
Secção 7.2, “Tabelas MERGE
”.
No momento você precisa ter privilégios
SELECT
, UPDATE
e
DELETE
nas tabelas mapeadas para uma
tabela MERGE
. Todas as tabelas mapeadas
devem estar no mesmo banco de dados na tabela
MERGE
.
Se você quiser inserir dados em uma tabela
MERGE
, você tem que especificar com
INSERT_METHOD
na tabela onde o registro
deve ser inserido. INSERT_METHOD
é uma
opção útil somente para tabelas MERGE
.
See Secção 7.2, “Tabelas MERGE
”. Esta opção foi introduzida no
MySQL 4.0.0.
Na tabela criada a chave PRIMARY
será
colocado primeiro, seguida de todas a chaves únicas
(UNIQUE
) e então das chaves normais.
Isto ajuda o otimizador MySQL para priorizar qual chave
utilizar e também a detectaa mais rapidamente chaves
únicas (UNIQUE
) duplicadas.
Utilizando DATA DIRECTORY='directorio'
ou
INDEX DIRECTORY='directorio'
você pode
especificar onde o mecanismo de armazenamento deve colocar
os seus arquivos de tabelas e índices. Note que
``diretório'' deve ser um caminho completo para o
diretório (não um caminho relativo).
Isto só funciona para tabelas MyISAM
no
MySQL
4.0, quando não estiver usando a
opção --skip-symlink
. See
Secção 5.6.1.2, “Utilizando Links Simbólicos para Tabelas”.
Em alguns casos, MySQL altera sem aviso uma especificação de
coluna dada em uma instrução CREATE
TABLE
. (Isto também pode ocorrer com ALTER
TABLE
.):
Colunas VARCHAR
com um tamanho menor
que quatro são alteradas para CHAR
.
Se qulquer coluna em uma tabela tem um tamanho variável,
toda a linha é de tamanho varável como resultado.
Consequentementem se uma tabela contém qualquer coluna de
tamanho variável (VARCHAR
,
TEXT
, ou BLOB
),
todas as colunas CHAR
maior que três
caracteres são alteradas para colunas
VARCHAR
. Isto não afeta como você
utiliza as colunas; no MySQL, VARCHAR
é apenas um modo diferente de armazenar caracteres. O
MySQL realiza esta conversão porque ela salva espaço e
torna as operções de tabela mais rápidas. See
Capítulo 7, Tipos de Tabela do MySQL.
A partir da versão 4.1.0, se um campo
CHAR
ou VARCHAR
com
uma especificação de tamanho maior que 255 é convertido
para TEXT
. Este é um recurso para
compatibilidade.
O tamanho do display TIMESTAMP
deve ser
para e na faixa de 2 a 14. Se você especificar um tamanho
de display de 0 opu maior que 14, o tamaho é convertido
para 14. Tamanhos de valor ímpar na faixa de 1 a 13 são
convertidos para o número para mais próximo acima.
Você não pode armazenar um NULL
literal em uma coluna TIMESTAMP
;
definí-la com NULL
a atribui a data e
hora atual. Por colunas TIMESTAMP
comportarem deste modo, os atributos
NULL
e NOT NULL
não
se aplicam no modo normal e são ignorados se você
especificá-los. DESCRIBE nome_tabela
sempre indica que a uma coluna
TIMESTAMP
pode ser atribuído valores
NULL
.
MySQL mapeia certos tipos de colunas utilizados por outros produtos de banco de dados para tipos MySQL. See Secção 6.2.5, “Usando Tipos de Colunas de Outros Mecanismos de Banco de Dados”.
Se você quiser ver se o MySQL utiliza um tipo de coluna
diferente do especificado, axecute uma instrução
DESCRIBE nome_tabela
depois de criar ou
alterar a sua tabela.
Outras alterações de tipos de colunas podem ocorrer se você
compactar a tabela utilizando myisampack
.
See Secção 7.1.2.3, “Características de Tabelas Compactadas”.
ALTER [IGNORE] TABLE nome_tbl especificação_alter [, especificação_alter ...] especificação_alter: ADD [COLUMN] definição_create [FIRST | AFTER nome_coluna ] | ADD [COLUMN] (definição_create, definição_create,...) | ADD INDEX [nome_indice] (index_nome_col,...) | ADD [CONSTRAINT [symbol]] PRIMARY KEY (index_col_name,...) | ADD [CONSTRAINT [symbol]] UNIQUE [index_name] (index_col_name,...) | ADD FULLTEXT [index_name] (index_col_name,...) | ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [definição_referncia] | ALTER [COLUMN] nome_col {SET DEFAULT literal | DROP DEFAULT} | CHANGE [COLUMN] nome_col_antigo definição_create [FIRST | AFTER nome_coluna] | MODIFY [COLUMN] definição_create [FIRST | AFTER nome_coluna] | DROP [COLUMN] nome_col | DROP PRIMARY KEY | DROP INDEX nome_indice | DISABLE KEYS | ENABLE KEYS | RENAME [TO] nome_nova_tbl | ORDER BY col | CHARACTER SET character_set_name [COLLATE collation_name] | table_options
ALTER TABLE
lhe permite alterar a estrutura
da tabela existente. Por exemplo, você pode adicionar ou
deletar colunas, criar ou remover índices, alterar o tipo de
coluna existentes, ou renomear coluna ou tabelas. Você também
pode alterar o comentário para a tabela e tipo de tabela. See
Secção 6.5.3, “Sintaxe CREATE TABLE
”.
Se você utilizar ALTER TABLE
para alterar a
especificação da coluna, mas DESCRIBE
tbl_name
indicar que a sua coluna não foi alterada,
é possível que o MySQL tenha ignorado ou a sua modificação
por uma das razões descritas em
Secção 6.5.3.1, “Alteração de Especificações de Colunas”. Por exemplo, se você
tentar alterar uma coluna VARCHAR
para
CHAR
, MySQL ainda usará
VARCHAR
se a tabela conter outras colunas de
tamanho variável.
ALTER TABLE
funciona fazendo uma cópia
temporária da tabela original. A alteração é realizada na
cópia, assim a tabela original é deletada e a nova tabela é
renomeada. Isto é feito de tal forma que todas as
desnecessáriaatualizações são automaticamente redirecionadas
para a nova tabela sem nenhuma atualização errada. Enquanto o
ALTER TABLE
é executado, a tabela original
pode ser lida por outros clientes. Atualizações e escrita na
tabela são guardadas até a nova tabela estar pronta.
Note que se você utilizar qualquer outra opção de
ALTER TABLE
, exceto
RENAME
, o MySQL irá sempre criar um a tabela
temporária, mesmo se os dados não precisarem realmente serem
copiados (como quando você altera o nome de uma coluna).
Planejamos corrigir isto no futuro, mas como não se faz
ALTER TABLE
com tanta frequência, isto não
é de alta prioridade em nosso TO DO. Para tabelas MyISAM, vOcê
pode aumentar a velocidade na parte da recriação dos índices
(que a parte mais lenta do processo recriação) atribuindo um
alto valor à variável
myisam_sort_buffer_size
.
Para utilizar ALTER TABLE
, você precisa
dos privilégios ALTER
,
INSERT
e CREATE
na
tabela.
IGNORE
é uma extensão do MySQL ao
SQL-92. Ele controla como o ALTER TABLE
funciona se houver duplicação em chaves únicas na nova
tabela. Se IGNORE
não é especificado, a
cópia é abortada e retornada. Se IGNORE
for especificado, para linhas com duplicatas em chaves
únicas, somente a primera linha é usada; as outras são
deletadas.
Você pode executar múltiplas cláusulas
ADD
, ALTER
,
DROP
e CHANGE
em uma
única instrução ALTER TABLE
. Esta é
uma extensão do MySQL ao SQL-92, que permite paenas uma
cláusula de cada por instrução ALTER
TABLE
.
CHANGE col_name
, DROP
col_name
, e DROP INDEX
são
extensões do MySQL ao SQL-92.
MODIFY
é uma extensão do Oracle para
ALTER TABLE
.
A palavra opcional COLUMN
é uma palavra
puramente desnecessária e pode ser omitida.
Se você utilizar ALTER TABLE nome_tbl RENAME TO
novo_nome
sem nenhuma outra opção, MySQL
simplesmente renomeia os arquivos correspondentes a tabela
nome_tbl
. Não há necessidade de se
criar uma tabela temporária. See
Secção 6.5.5, “Sintaxe RENAME TABLE
”.
Cláusulas definição_create
usam a
mesma sintaxe para ADD
e
CHANGE
assim como para CREATE
TABLE
. Note que a sintaxe inclui o nome da coluna,
não apenas o tipo da coluna. See
Secção 6.5.3, “Sintaxe CREATE TABLE
”.
Você pode renomear ma coluna usando uma cláusula
CHANGE nome_col_antiga
definições_create
. Para tal, especifique o nome
das colunas antiga e da nome e o tipo que a coluna atual
possui. Por exemplo, para renomear uma coluna
INTEGER
de a
para
b
, faça assim:
mysql> ALTER TABLE t1 CHANGE a b INTEGER;
Se você quiser mudar um tipo de coluna, mas não o nome, a
sintaxe CHANGE
ainda exige dois nomes de
colunas, mesmo que sejam o mesmo. Por exemplo:
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
No entanto, como no MySQL Versão 3.22.16a, você também
pode utilizar MODIFY
para alterar um tipo
de coluna sem renomeá-lo:
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
Se você utilizar CHANGE
ou
MODIFY
para reduzir uma coluna na qual
exista um índice em parte da coluna (por exemplo, se você
tiver um índice nos primeiros 10 caracteres de uma coluna
VARCHAR
), você não poderá reduzir a
coluna para um tamanho menor que o número de caracteres
indexados.
Quando você altera um tipo de coluna usando
CHANGE
ou MODIFY
,
erter os dados para o novo tipo da melhor forma possível.
No MySQL Versão 3.22 ou posterior você pode utilizar
FIRST
ou ADD ... AFTER
nome_col
para aadicionar uma coluna em uma
posição específica na linha da tabela. O padrão é
adicionar a coluna no fim. A partir do MySQL Versão 4.0.1,
você pode também utilizar as palavras-chave
FIRST
e AFTER
em
CHANGE
ou MODIFY
.
ALTER COLUMN
especifica um novo valor
padrão para uma coluna ou remover o valor padrão antigo.
Se o padrão antigo é removido e a coluna pode ser
NULL
, o novo padrão é
NULL
. Se a coluna não pode ser
NULL
, MySQL atribui um valor padrão,
como descrito em Secção 6.5.3, “Sintaxe CREATE TABLE
”.
DROP INDEX
remove um índice. Esta é uma
extensão do MySQL ao SQL-92. See
Secção 6.5.8, “Sintaxe DROP INDEX
”.
Se colunas forem removidas de uma tabela, as colunas também são removidas de qualquer índice do qual eles fazem parte. Se todas as colunas que compõe um índice são excluídas, o índice também é excluído.
Se uma tabela contém apenas uma coluna, a coluna não pode
ser excluída. Se o que você pretende é remover a tabela,
use DROP TABLE
.
DROP PRIMARY KEY
deleta o índice
primário. Se tal índice não existe, ele apaga o prmeiro
índice único (UNIQUE
) na tabela. (MySQL
marca a primeira chave única (UNIQUE
)
como PRIMARY KEY
se nenhuma
PRIMARY KEY
foi especificada
explicitamente.)
Se você adicionar UNIQUE INDEX
ou
PRIMARY KEY
a uma tabela, elas são
armazenadas antes de qualquer índice não
UNIQUE
para que possa detectar cahves
duplicadas o mais rápido possível.
ORDER BY
lhe permite criar a nova tabela
com as linhas em uma ordem específica. Note que a tabela
não permanecerá nesta ordem depois de insrções e
deleções. Em algunas casos, isto pode tornar a ordenação
mais para o MySQL se a tabela estiver ordenada pela coluna
que você escolheu. Esta opção é útil principalmente
quando você sabe qeu na maioria das vezes você irá
inserir os registros em certa ordem; utilizando esta opção
depois de grandes mudanças na tabela, você obterá melhor
desempenho.
Se você utilizar ALTER TABLE
em uma
tabela MyISAM
, todos os índices que não
são únicos são criados em um grupo separado (como em
REPAIR
). Isto deve tornar ALTER
TABLE
muito mais rápido quando você tiver
vários índices.
A partir do MySQL 4.0 o
recurso acima pode ser ativado explicitamente.
ALTER TABLE ... DISABLE KEYS
faz o MySQL
parar de atualizar chaves que não são únicas em tabelas
MyISAM
. ALTER TABLE ... ENABLE
KEYS
deve ser usado para recriar índices
perdidos. Como o MySQL faz isso com um algoritmo especial
que é muito mais rápido que inserir chaves uma a uma,
disabilitar chaves podem trazer um aumento de velocidade
considerável em inserções volumosas.
Com a função mysql_info()
da API C,
você pode saber quantos registros foram copiados, e (quando
IGNORE
for usado) quantos registros foram
deletados devido a duplicação de valores de chaves
únicas.
As cláusulas FOREIGN KEY
,
CHECK
e REFERENCES
não fazem nada, exceto para tipos de tabela InnoDB que
suportam ... ADD [CONSTRAINT [symbol]] FOREIGN KEY
(...) REFERENCES ... (...)
e ... DROP
FOREIGN KEY ...
. See
Secção 7.5.5.2, “Restrições FOREIGN KEY
”. A sintaxe
para outros tipos de tabela só é fornecido para
comptibilidade, para tornar fácil portar o código de outro
servidor SQL e executar aplicações que criam tabelasd com
referências. See Secção 1.8.4, “Diferenças do MySQL em Comparação com o SQL-92”.
ALTER TABLE
ignora as opções de tabela
DATA DIRECTORY
e INDEX
DIRECTORY
.
Se você quiser alterar todas as colunas CHAR/VARCHAR/TEXT para um novo conjunto de caracteres (por exemplo, depois de atualizar do MySQL 4.0.x para o 4.1.1) você pode fazer:
ALTER TABLE table_name CHARACTER SET character_set_name;
Note que o seguinte comando só irá alterar o
default character set
para uma tabela:
ALTER TABLE table_name DEFAULT CHARACTER SET character_set_name;
O default character set
é o conjunto de
caracteres que é usado se você não especificar o conjunto
de caracteres para uma nova coluna que você adicionar a
tabela (por exemplo com ALTER TABLE ... ADD
coluna
).
Aqui temos um exemplo que mostra alguns dos usos de
ALTER TABLE
. Nós começamos com uma tabela
t1
que é crida como mostrado aqui:
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
Para renomear a tabela de t1
para
t2
:
mysql> ALTER TABLE t1 RENAME t2;
Para alterar a coluna a
de
INTEGER
para TINYINT NOT
NULL
(deixando o mesmo nome), e alterar a coluna
b
de CHAR(10)
para
CHAR(20)
e renomeá-la de
b
para c
:
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
Para adicionar um nova coluna TIMESTAMP
chamada d
:
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
Para adicionar um índice na coluna d
, e
tornar a colua a
a chave primária:
mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
Para remover a coluna c
:
mysql> ALTER TABLE t2 DROP COLUMN c;
Para adiciomar um nova coluna inteira
AUTO_INCREMENT
chamada c
:
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
ADD INDEX (c);
Note que nós indexamos c
, porque colunas
AUTO_INCREMENT
devem ser indexadas e também
por isso declaramos c
como NOT
NULL
, pois colunas indexadas não podem ser
NULL
.
Quando você adicionar uma coluna
AUTO_INCREMENT
, valores de coluna são
preenchidos com sequência de números automaticamente para
você. Você pode definir o primeiro número da sequência
executando SET INSERT_ID=valor
antes de
ALTER TABLE
ou usando a opção de tabela
AUTO_INCREMENT=valor
. See
Secção 5.5.6, “Sintaxe de SET
”.
Com tabelas MyISAM tables, se você não alterar a coluna
AUTO_INCREMENT
, a sequência de números não
será afetada. Se você excluir uma coluna
AUTO_INCREMENT
e adicionar outra coluna
AUTO_INCREMENT
, a numeração iniciará a
partir do 1 novamente.
RENAME TABLE nome_tabela TO novo_nome_tabela[, nome_tabela2 TO novo_nome_tbl2,...]
A renomeação é feita automicamente, o que significa que nenhuma outra thread pode acessar qualquer uma das tabelas enquanto a renomeação está sendo exectuda. Isto torna possível substituir uma tabela por uma tabela vazia:
CREATE TABLE tabela_nova (...); RENAME TABLE tabela_antiga TO tabela_backup, tabela_nova TO tabela_antiga;
A renomeação é feita da esquera para a direita, o que significa que se você quiser trocar os nomes das tabelas, você deve fazer:
RENAME TABLE tabela_antiga TO tabela_backup, tabela_nova TO tabela_antiga, tabela_backup TO tabela_nova;
Desde que dois banco de dados estejam no mesmo disco você pode renomear de um banco de dados para outro:
RENAME TABLE bd_atual.nome_tabela TO outro_bd.nome_tabela;
Quando você executa RENAME
, você não pode
ter nenhuma tabela bloqueada ou transações ativas. Você
também deve ter o privilégio ALTER
e
DROP
na tabela original e o privilégio
CREATE
e INSERT
na nova
tabela.
Se o MySQL encontrar qualquer erro uma renomeação multi-tabela, ele fará um renomeação reversa para todas a tabelas renomeadas para retornar tudo ao estado original.
RENAME TABLE
foi adicionado no MySQL 3.23.23.
DROP [TEMPORARY] TABLE [IF EXISTS] nome_tabela [, nome_tabela,...] [RESTRICT | CASCADE]
DROP TABLE
remove uma ou mais tabelas. Todos
os dados e definições de tabela são
removidos, assim
tenha cuidado com este comando!
No MySQL Versão 3.22 ou posteriorm você pode usar a
palavra-chave IF EXISTS
para prevenir um erro
de ocorrer se não existir a tabela. Na versão 4.1 consegue-se
um NOTA
para todas as tabelas não esistentes
se for usado IF EXISTS
. See
Secção 4.6.8.9, “SHOW WARNINGS | ERRORS
”.
RESTRICT
e CASCADE
são
permitidos para portação se tornar tornar mais fácil. No
momento eles não fazem nada.
Nota: DROP
TABLE
fará automaticamente um commit da transação
ativa atualmente (exceto se você estiver usando a versão 4.1 e
a palavra-chave TEMPORARY
.
A opcão TEMPORARY
é ignorada na versão
4.0. Na versão 4.1 esta opção funciona como a seguir:
Só apaga tabelas temporárias.
INão finaliza uma transação em execução.
Nenhum direito de acesso é verificado.
Usar TEMPORARY
é uma boa maneira de
assegurar que você não apague uma tabela real.
CREATE [UNIQUE|FULLTEXT] INDEX nome_indice ON nome_tabela (index_col_name,...) index_col_name: col_name [(length)] [ASC | DESC]
A instrução CREATE INDEX
não faz nada em
versões do MySQL anterior a 3.22. Na versão 3.22 ou
posteriores, CREATE INDEX
é mapeado para uma
instrução ALTER TABLE
para criar índices.
See Secção 6.5.4, “Sintaxe ALTER TABLE
”.
Normalmente você cria todos os índices em uma tabela ao mesmo
tempo em que a própria tabela é criada com CREATE
TABLE
. See Secção 6.5.3, “Sintaxe CREATE TABLE
”.
CREATE INDEX
lhe permite adicionar índices a
tabelas existentes.
Uma lista de colunas na forma (col1,col2,...)
cria um índice com múltiplas colunas. Valores de índice são
formados concatenando os valores de colunas dadas.
Para colunas CHAR
e
VARCHAR
, índices que utilizam apenas parte
da coluna podem ser criados, usando a sintaxe
nome_coluna(length)
para indexar os primeiros
length()
bytes de cada valor da coluna. (Para
colunas BLOB
e TEXT
, um
prefixo length é exigido; length()
pode ter
um valor até 255 caracteres.) A instrução mostrada aqui cria
um índice usando os primeiros 10 caracteres da coluna
name
:
mysql> CREATE INDEX part_of_name ON customer (name(10));
Como a maioria dos nomes normalmente diferem nos primeiros 10
caracteres, este índice não deve ser muito menor que um
índice criado com toda a coluna name
. Além
disso, usar colunas parciais como índices pode fazer o arquivo
de índice muito menor, o que pode economizar muito espaço em
disco e pode também aumentar a velocidade de operações
INSERT
!
Note que você pode adicionar um índice em uma coluna que pode
ter valores apenas se você estiver usando o MySQL Versão
3.23.2 ou mais novo e estiver usando os tipos de tabelas
MyISAM
, InnoDB
, ou
BDB
. Você só pode adicionar um índice em
uma coluna BLOB
/ TEXT
se
você estiver usando o MySQL Versão 3.23.2 ou mais novo e
estiver usando os tipos de tablea MyISAM
ou
BDB
, ou MySQL Versão 4.0.14 ou mais novo e o
tipo de tabela InnoDB
. Para um índice em uma
coluna BLOB
/TEXT
, o
tamanho do prefixo sempre deve ser especificado.
Uma especificação index_col_name
pode
finalizar com ASC
ou DESC
.
Esta palavras chaves são permitidas para estensão futura para
especificar o armazenamento do valor do índice em crescente ou
decrescente. Atualmente elas são analisadas mas ignoradas;
valores de índice são sempre armazenados em ordem crescente.
Para mais detalhes sobre como o MySQL utiliza índices, veja Secção 5.4.3, “Como o MySQL Utiliza Índices”.
Indíces FULLTEXT
só podem indexar colunas
CHAR
, VARCHAR
e
TEXT
, e apenas em tabelas
MyISAM
. Índices FULLTEXT
estão disponíveis no MySQL Versão 3.23.23 e posterior.
Secção 6.8, “Pesquisa Full-text no MySQL”.
DROP INDEX nome_indice ON nome_tabela
DROP INDEX
apaga o índice chamado
nome_indice
da tabela
nome_tabela
. DROP INDEX
não faz nada nem versões do MySQL anteriores a 3.22. Na
versão 3.22 ou posterior, DROP INDEX
é
mapeada em uma instrução ALTER TABLE
para
apagar o índice. See Secção 6.5.4, “Sintaxe ALTER TABLE
”.
USE nome_db
A instrução USE nome_bd
diz ao MySQL para
usar o banco de dados nome_bd
como padrão
para as consultas subsequentes. O banco de dados continua como o
atual até o final da sessão ou até outra instrução
USE
ser executada:
mysql>USE db1;
mysql>SELECT COUNT(*) FROM mytable; # seleciona de db1.mytable
mysql>USE db2;
mysql>SELECT COUNT(*) FROM mytable; # seleciona de db2.mytable
Torna um banco de dados particular como o atual não significa
que a instrução USE
não o permita acessar
tabelas em outros bancos de dados. O exemplo seguinte acessa a
tabela author
do banco de dados
db1
e a tabela editor
do
banco de dados db2
:
mysql>USE db1;
mysql>SELECT author_name,editor_name FROM author,db2.editor
->WHERE author.editor_id = db2.editor.editor_id;
A instrução USE
é fornecida para
compatibilidade com o Sybase.
{DESCRIBE | DESC} nome_tabela [nome_coluna | meta_carac]
DESCRIBE
á um atalho para SHOW
COLUMNS FROM
. See
Secção 4.6.8.1, “Recuperando Informações sobre Bancos de Dados, Tabelas, Colunas e Índices”.
DESCRIBE
fornece informação sobre as
colunas da tabela. nome_coluna
deve ser um
nome de coluna ou uma string contendo os meta caracteres
‘%
’ e
‘_
’ do SQL para ter a saída
apenas com nomes que corespondam com a string. Não é
necessário colocar a string entre aspas.
Se os tipos de colunas são diferentes do esperado baseado nas
instruções CREATE TABLE
, note que algumas
vezer o MySQL altera o tipo das colunas. See
Secção 6.5.3.1, “Alteração de Especificações de Colunas”.
Esta instrução é fornecida para compatibilidade com Oracle.
A instrução SHOW
fornece informação
similar. See Secção 4.6.8, “Sintaxe de SHOW
”.
Por padrão, MySQL é executado em modo autocommit. Isto significa que assim que você executa uma instrução que atualiza (modifica) uma tabela, o MySQL armaena a atualização no disco.
Se você estiver usando tabelas com segurança a transação
(como InnoDB
\ ou BDB
),
você pode colocar o MySQL em modo não autocommit com o
seguinte comando:
SET AUTOCOMMIT=0
Depois de disabilitar o modo autocommit configurando a variável
AUTOCOMMIT
com zero, você deve utilizar
COMMIT
para armazenar suas alterações em
disco ou ROLLBACK
se você deseja ignorar as
alterações que você fez desde o início da sua transação.
Se você quiser disabilitar o modo autocommit para uma única
série de instruções, você pode utiliar a instrução
START TRANSACTION
:
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summmary=@A WHERE type=1; COMMIT;
BEGIN
e BEGIN WORK
podem
ser usados em vez de START TRANSACTION
para
iniciar uma transação. START TRANSACTION
foi adicionado no MySQL 4.0.11; ele é uma sintaxe do SQL-99 e
é o modo recomendado de iniciar umaa transação an ad-hoc.
BEGIN
e BEGIN WORK
estão
disponíveis a partir do MySQL 3.23.17 e 3.23.19,
respectivamente.
Note que se você estiver usando tabelas sem segurança a transação, quaisquer alterações serão armazenadas de uma vez, se considerar o status do modo autocommit.
Se você executar uma instrução ROLLBACK
depois de atualizar uma tabela não-transacional, você obterá
um erro (ER_WARNING_NOT_COMPLETE_ROLLBACK
),
como um aviso. Todas as tabelas seguras a transação serão
restauradas mas qualquer tabela se segurança a transação não
sofrerão alterações.
Se você estiver usando START TRANSACTION
ou
SET AUTOCOMMIT=0
, você deve usar o log
binário do MySQL para backup no lugar do antigo log de
atualização. Transações são armazenadas no log binário em
um bloco, sobre COMMIT
, para assegurar que
transações nas quais foram feitas rolled back não foram
armazenadas. See Secção 4.10.4, “O Log Binário”.
Você pode alterar o nível isolação para transações com
SET TRANSACTION ISOLATION LEVEL
. See
Secção 6.7.6, “Sintaxe SET TRANSACTION
”.
Não se pode fazer o roll back de algumas instruções. Em geral, elas incluem instruções DDL (data definition language), como aquelas que criam ou removem banco de dados, ou aquelas que criam, apagam ou alteram tabelas.
Você pode desejar projetar as suas transações para não
incluir estas instruções. Se você executar uma instrução da
quale não se pode fazer roll back em uma transação, e então
outra intruções falhar posteriormente, o efeito total da
transação não pode ser desfeito usando uma instrução
ROLLBACK
.
Os seguintes comandos finalizam uma transação implicitamente
(como se você tivesse feito um COMMIT
antes
de executar o comando):
Comando | Comando | Comando |
ALTER TABLE | BEGIN | CREATE INDEX |
DROP DATABASE | DROP INDEX | DROP TABLE |
LOAD MASTER DATA | LOCK TABLES | RENAME TABLE |
SET AUTOCOMMIT=1 | START TRANSACTION | TRUNCATE |
UNLOCK TABLES
também finaliza uma
transação se qualquer tabela estiver atualmente bloqueada.
Antes do MySQL 4.0.13, CREATE TABLE
finaliza
uma transação se o log binário está habilitado.
Transações não podem ser aninhadas. Isto é uma consequência
do COMMIT
implícito realizado por qualquer
transação atual quando você envia uma instrução
START TRANSACTION
ou um de seus sinônimos.
A partir do MySQL 4.0.14 e 4.1.1. o InnoDB
suporta os comando SQL SAVEPOINT
e
ROLLBACK TO SAVEPOINT
.
SAVEPOINT identificador
Esta instrução configura um savepoint de uma transação cujo
nome é identificador
. Se a transação atual
já tiver um savepoint com o mesmo nome, o savepointy antigo é
deletado é o novo é definido.
ROLLBACK TO SAVEPOINT identificador
Esta instrução faz o roll back de uma transação até o
savepoint indicado. Modificações feitas nesta transação
após o savepoint foram definidas como desfeitas no roll back,
mas o InnoDB
não libera o lock de linha que
forma arnmazenados na memória depois do savepoint. (Note que
para uma nova linha inserida, a informação do lock é
carregada pala ID da transação armazenada na linha; o lock
não é armazenado separadamente na memória. Neste caso, o lock
de linha é liberado no undo.) Sevapoints que foram definidos
após o sevepoint indicado são deletados.
Se o comando retorna o seguinte erro, significa que não existem savepoints como o nome especificado.
ERROR 1181: Got error 153 during ROLLBACK
Todos os savepoints da transação atual são deletados se você
executar um COMMIT
ou um
ROLLBACK
que não chamou um savepoint.
LOCK TABLES nome_tabela [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [, nome_tabela [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} ...] ... UNLOCK TABLES
LOCK TABLES
bloqueia tabelas para a thread
atual. UNLOCK TABLES
libera qualquer trava
existente para a thread atual. Todas as tabela que estão
bloqueadas pela thread atual são implicitamente desbloquadas
quando a thread executa um outro LOCK TABLES
,
ou quando a conexão ao servidor é fechada.
Para usar LOCK TABLES
no MySQL 4.0.2 você
precisa do privilégio global LOCK TABLES
e
um privilégio SELECT
nas tabelas envolvidas
No MySQL 3.23 você precisa ter os privilégios
SELECT
, insert
,
DELETE
e UPDATE
para as
tabelas.
A razão principal para utilizar LOCK TABLES
é para emular transações ou obter mais velocidade ao
atualizar tabelas. Isto é explicado em mais detalhes
posteriormente.
Se uma thread obtem uma trava de leitura
(READ
) em uma tabela, aquela thread (e todas
as outras threads) só poderão ler da tabela. Se uma thread
obter uma trava de escrita (WRITE
) na tabela,
apenas a thread que bloqueou poderá ler ou escrever na tabela.
Outras threads serão bloqueadas.
A diferença entre READ LOCAL
e
READ
é que READ LOCAL
permite que instruções INSERT
não
conflitantes sejam executadas enquanto a trava está ativa.
Isto, no entatnto, não pode ser usado se você for manipular o
arquivo de banco de dados fora do MySQL enquanto a trava estiver
ativa.
Quando você usa LOCK TABLES
, você deve
travar todas as tabelas que você for usar e utilizar o mesmo
alias que estiver utilizando em suas consultas! Se você estiver
usando uma tabela várias vezes em uma consulta (com aliases),
você deve obter um trava para cada alias.
Bloqueio de escrita (WRITE
) normalmente têm
maior prioridade que bloqueio de leitura
(READ
), para assegurar que atualizações
são processadas assim que possível. Isto significa que se uma
thread obtida um bloqueio de leitura (READ
) e
outra thread requisitar um bloqueio de escrita
(WRITE
), bloqueios de leitura
(READ
) subsequentes irão esperar até a
thread de escrita (WRITE
) tiver obtido a
trava e a liberado. Você pode usar travas LOW_PRIORITY
WRITE
para permitir que outras threads obtenham
bloqueios de leitura (READ
) enquanto a thread
estiver esperando pela trava de escrita
(WRITE
). Você só deve utilizar bloqueios
LOW_PRIORITY WRITE
se você estiver certo que
haverá um momento onde nenhuma thread terá bloqueio de leitura
(READ
).
LOCK TABLES
funciona da seguinte maneira:
Ordene todas as tabelas a serem travadas em uma ordem definida internamente (do ponto do usuário a ordem é indefinida).
Se uma tabela é bloqueada com uma trava de leitura e de escrita, coloque a trava de escrita antes da trava de leitura.
Bloqueie uma tabela por vez até que a thread obtenha todas as travas.
Esta política assegura que as tabelas sejam bloqueadas sem deadlock. Há no entanto outra coisa da qual é preciso estar ciente neste esquema:
Se cocê estiver usando uma trava de escita
LOW_PRIORITY WRITE
em uma tabela, significa
apenas que o MySQL irá esperar por esta trava particular até
que não haja mais treads fazendo um bloqueio de leitura
(READ
). Quando a thread tiver obtido a trava
de escrita (WRITE
) e está esperando ppo
obter o trava para a próxima tabela na lista de tabelas
bloqueadas, todas as outras threads irão esperar que a trva de
escrita (WRITE
) seja liberada. Se isto tornar
um sério problema com sua aplicação, você deve converter
algumas de suas tabellas para tabelas com segurança em
transações.
Você pode matar com segurança um thread que está esperando
por um bloqueio de tabela com KILL
. See
Secção 4.6.7, “Sintaxe de KILL
”.
Note que você não deve travar
nenhuma tabela que você esteja usando com INSERT
DELAYED
. Isto é porque este é o caso que o
INSERT
é feito por uma thread separada.
Normalmente, você não tem que travar tabelas, já que todas as
instruções UPDATE
são atomicas; nenhuma
outra thread pode interferir com qualquer outra executando uma
instrução SQL. Existem poucos casos em que você gostaria de
travar as tabelas de qualquer forma:
Se você for executar operações em um grupo de tabelas, é
muito mais rápido travar as tabelas que você for utilizar.
O lado ruim é que nenhuma outra thread pode atualizar uma
tabela travada para leitura (READ
)
(incluindo aquela que guarda o lock) e nenhuma outra thread
pode ler uma tabela bloqueada para escrita
(WRITE
) além daquele que guarda o lock.
A razão de algumas coisas serem rápidas sob LOCK
TABLES
é que o MySQL não irá descarregar a
cache de tabelas bloqueadas até que UNLOCK
TABLES
seja chamado (normalmente a cache de chaves
é descarregada a cada instrução SQL). Isto aumenta a
velocidade de inserção, atualização e deleção) em
tabelas MyISAM
.
Se você estiver usando um mecanismo de armazenamento no
MySQL que não suporte transações, você deve usar
LOCK TABLES
se você quiser se assegurar
que nenhuma outra thread venha entre um
SELECT
e um UPDATE
. O
exemplo mostrado aqui exige LOCK TABLES
para ser executado com segurança:
mysql>LOCK TABLES trans READ, customer WRITE;
mysql>SELECT SUM(value) FROM trans WHERE customer_id=some_id;
mysql>UPDATE customer SET total_value=sum_from_previous_statement
->WHERE customer_id=some_id;
mysql>UNLOCK TABLES;
Sem LOCK TABLES
, existe uma chance que
outra thread possa inserir uma nova linha na tabela
trans
entre a execução das instruções
SELECT
e UPDATE
.
Utilizando atualizações incrementais (UPDATE customer
SET value=value+new_value
) ou a função
LAST_INSERT_ID()
i, você pode evitar o uso de
LOCK TABLES
em muitos casos.
Você também pode resolver alguns casos usando as funções de
bloqueio a nível de usuário GET_LOCK()
e
RELEASE_LOCK()
. Estas travas são salvas em
uma tabela hash no servidor e implementado com
pthread_mutex_lock()
e
pthread_mutex_unlock()
para alta velocidade.
See Secção 6.3.6.2, “Funções Diversas”.
Veja Secção 5.3.1, “Como o MySQL Trava as Tabelas”, para mais informações sobre política de bloqueios.
Você pode trocar todas as tabelas em todos os banco de dados
com trava de leitura com o comando FLUSH TABLES WITH
READ LOCK
. See Secção 4.6.4, “Sintaxe de FLUSH
”. Este é um
modo muito conveiente de tirar backups se você tiver um sistema
de arquivos, como Veritas, que pode tirar snapshots.
NOTE: LOCK
TABLES
mão é seguro com transações e fará um
commit implicitamente em qualquer transação ativa antes de
tentar travar as tabelas.
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
Define o nível de isolação da transação para global, toda a sessão ou a próxima transação.
O comportamento padrão é definir o nível de isolação para a
próxima (não iniciada) transação. Se você usa a
palavra-chave GLOBAL
, a instrução define o
nivel de transação padrão globalmente para todas as novas
conexões criadas a partir deste ponto (mas não existe
conexão). Você precisa do privilégio SUPER
para fazer isto. Usar a palavra-chave SESSION
define o nível de transação padrão para todas a transações
futuras relaizadas na conexão atual.
Para a descrição de cada nível de isolação da transação
do InnoDB
, veja
Secção 7.5.9.1, “InnoDB e SET ... TRANSACTION ISOLATION LEVEL ...
”. O InnoDB suporta
cada um destes níveis a partir do MySQL 4.0.5. O nível padrão
é REPEATABLE READ
.
Você pode definir o nível de isolação global padrão para o
mysqld
com
--transaction-isolation=...
. See
Secção 4.1.1, “Opções de Linha de Comando do mysqld
”.
MATCH (col1,col2,...) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION] )
A partir da versão 3.23.23, MySQL tem suporte para indexação e
busca full-text. Índices full-text no MySQL são um índice do
tipo FULLTEXT
. Índices
FULLTEXT
são usados apenas com tabelas
MyISAM
e podem ser criadas a partir de colunas
CHAR
, VARCHAR
ou
TEXT
durante um CREATE TABLE
ou adicionados posteriormente com ALTER TABLE
ou CREATE INDEX
. Para banco de dados maiores,
será muito mais rápido carregar seus dados em uma tabela que
não tnha índices FULLTEXT
, que criar o
índice com ALTER TABLE
(ou CREATE
INDEX
). Carregar dados em uma tabela que já tenha um
índice FULLTEXT
será muito mais lento.
Pesquisa full-text é realizada com a função
MATCH()
.
mysql>CREATE TABLE articles (
->id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
->title VARCHAR(200),
->body TEXT,
->FULLTEXT (title,body)
->);
Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO articles VALUES
->(NULL,'MySQL Tutorial', 'DBMS stands for DataBase ...'),
->(NULL,'How To Use MySQL Efficiently', 'After you went through a ...'),
->(NULL,'Optimizing MySQL','In this tutorial we will show ...'),
->(NULL,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
->(NULL,'MySQL vs. YourSQL', 'In the following database comparison ...'),
->(NULL,'MySQL Security', 'When configured properly, MySQL ...');
Query OK, 6 rows affected (0.00 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql>SELECT * FROM articles
->WHERE MATCH (title,body) AGAINST ('database');
+----+-------------------+------------------------------------------+ | id | title | body | +----+-------------------+------------------------------------------+ | 5 | MySQL vs. YourSQL | In the following database comparison ... | | 1 | MySQL Tutorial | DBMS stands for DataBase ... | +----+-------------------+------------------------------------------+ 2 rows in set (0.00 sec)
A função MATCH()
realiza um busca de
linguagem natural por uma string contra uma coleção de texto (um
conjunto de uma ou mais colunas incluídas em um índice
FULLTEXT
). A string pesquisada é dada como o
argumento de AGAINST()
. A busca é realizada na
forma caso-insensitivo. Para cada uma das linhas da tabela,
MATCH()
retorna um valor relevante, isto é,
uma medida de similaridade entre a string pesquisada e o texto
naquela nas colunas identificadas na lista
MATCH()
.
Quando MATCH()
é utilizado na cláusula
WHERE
(veja exemplo acima) as linhas retornadas
são automaticamente ordenadas com a maior relevância primerio.
Valores de relevância são números de ponto flutuante não
negativos. Relevância zero significa nenhuma similaridade.
Relevância é computado baseada no número de palavras na linha,
o número de palavras única naquela linha, o número de palavras
na coleção e o número de documentos (linhas) que contenham uma
palavra particular.
Também é possível realizar uma busca no modo booleano. Isto é explicado posteriormente nesta seção.
O exemplo precedente é uma ilustrção básica mostrando como
usar a função MATCH()
. Linhas são retornodas
em ordem decrescente de relevância.
O próximo exemplo mostra como retornar o valores de relevância
explicitamente. Como nem a cláusula WHERE
nem
a ORDER BY
estão presentes, as linhas são
retornadas fora de ordem.
mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles;
+----+-----------------------------------------+
| id | MATCH (title,body) AGAINST ('Tutorial') |
+----+-----------------------------------------+
| 1 | 0.64840710366884 |
| 2 | 0 |
| 3 | 0.66266459031789 |
| 4 | 0 |
| 5 | 0 |
| 6 | 0 |
+----+-----------------------------------------+
6 rows in set (0.00 sec)
O exemplo seguinte é mais complexo. A consulta retorna a
relevância e ainda ordena as linhas em ordem decrescente de
relevância. Para conseguir este resultado, você deve especificar
MATCH()
duas vezes. Isto não irá causar
sobrecarga adicional, pois o otimizador MySQL irá notar que duas
chamadas MATCH()
são idênticas e invocam o
código da busca full-text apenas uma vez.
mysql>SELECT id, body, MATCH (title,body) AGAINST
->('Security implications of running MySQL as root') AS score
->FROM articles WHERE MATCH (title,body) AGAINST
->('Security implications of running MySQL as root');
+----+-------------------------------------+-----------------+ | id | body | score | +----+-------------------------------------+-----------------+ | 4 | 1. Never run mysqld as root. 2. ... | 1.5055546709332 | | 6 | When configured properly, MySQL ... | 1.31140957288 | +----+-------------------------------------+-----------------+ 2 rows in set (0.00 sec)
Desde a versão 4.1.1, pesquisas full-text suportam expansão de consulta (em particular, sua variante ``blind query expansion''). Ela é geralmente útil quando uma frase pesquisada é muito curta, o que normalmente significa que um usuário está confiando em um conhecimento contido, que a pesquisa full-text normalmente perde. Por exemplo, um usuario pesquisanado por ``database'' podem realmente significar que ``MySQL'', ``Oracle'', ``DB2'', ``RDBMS'' são todas frases que devem coincidir com ``databases'' e devem ser encontrados também. Isto é conhecimento contido. Blind query expansion (also known as automatic relevance feedback) works by performing the search twice, where the search phrase for the second search is the original search phrase concatenated with the few top found documents from the first search. Thus, if one of these documents contained the word ``databases'' and the word ``MySQL'', then the second search will find the documents that contain the word ``MySQL'' but not ``database''. Another example could be searching for books by Georges Simenon about Maigret, when a user is not sure how to spell ``Maigret''. Then, searching for ``Megre and the reluctant witnesses'' will find only ``Maigret and the Reluctant Witnesses'' without query expansion, but all books with the word ``Maigret'' on the second pass of a search with query expansion. Note: because blind query expansion tends to increase noise significantly, by returning non-relevant documents, it's only meaningful to use when a search phrase is rather short.
O MySQL utiliza um analizados muito simples para separar texto em
palavras. Uma ``palavra'' é uma sequência de caracteres
consistindo de letras, digitos,
‘'
’, e
‘_
’. Qualquer ``palavra'' presente
na lista de palavra de parada ou for muito curta é ignorada. O
tamanho padrão mínimo das palavras que serão encontradas pela
pesquisa full-text é de quatro caracteres. Isto pode ser alterado
como descrito em Secção 6.8.2, “Ajuste Fino de Pesquisas Full-text no MySQL”.
Toda palavra correta na lista de coleções e na consulta é pesada de acordo com sua significância na consulta ou coleção. Deste modo, uma palavra que está presente em vários documentos terá peso menor (e poderá ter até mesmo um peso zero), já que ele têm um valor semântico baixo nesta coleção particular. Por outro lado, se a palavra é rara, ela receberá um peso alto. O peso das palavras são então combinados para computar a relevância das linhas.
Tal técnica funciona melhor com coleções grandes (de fato, ela é cuidadosamente ajustado deste modo). Para tabelas muito pequenas, a distribuição das palavras não refletem adequadamente seus valores semânticos, e este modelo pode algumas vezes produzir resultados bizarros.
mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL');
Empty set (0.00 sec)
A busca pela palavra MySQL
não produz
resultados no exemplo acima, porque esta palavra está presente em
mais da metade das linhas. Como tal, ela é efetivamente tratada
como palavra de parada (isto é, uma palavra com valor semântico
zero). Este é o comportamento mais desejável --- uma consulta de
linguagem natural não deve retornar toda segunda linha de uma
tabela de 1 GB.
Uma palavra que casa com metade dos registros em uma tabela tem menos chance de encontrar dosumentos relevantes. De fato, é muito mais provável encontrar vários documentos irrelevantes. Todos nós sabemos que isto acontece com muita frequência quando tentamos encontrar alguma coisa na internet com um mecanismo de busca. É com esta razão que estes registros tem sido atribuído com um baixo valor semântico neste banco de dados particular.
Na versão 4.0.1, MySQL também pode realizar buscas full-text
booleanas usando o modificador IN BOOLEAN MODE
.
mysql>SELECT * FROM articles WHERE MATCH (title,body)
->AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
+----+------------------------------+-------------------------------------+ | id | title | body | +----+------------------------------+-------------------------------------+ | 1 | MySQL Tutorial | DBMS stands for DataBase ... | | 2 | How To Use MySQL Efficiently | After you went through a ... | | 3 | Optimizing MySQL | In this tutorial we will show ... | | 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | | 6 | MySQL Security | When configured properly, MySQL ... | +----+------------------------------+-------------------------------------+
Esta consulta recupera todos os registros que contenham a palavra
MySQL
(note: o ponto inicial de 50% não é
utilizado), mas que não contenha
a palavra YourSQL
. Note que a pesquisa em modo
booleano não ordena os registros automaticamente em ordem
decrescente de relevância. Você pode ver isto no resultado da
consulta anterior, onde a linha com a maior relevância (aquela
que contém MySQL
duas vezes) é listada por
último, não em primeiro. Um busca full-text booleana também
pode funcionar mesmo sem um índice FULLTEXT
,
no entanto ela seria lenta.
A busca full-text booleana suporte potencialmente as seguintes operações:
+
Um sinal de mais precedente indica que esta palavra deve estar presente em cada linha retornada.
-
Um sinal de menos precedente indice que esta palavra não deve estar presente em qualquer linha retornada.
Por padrão (quando nem mais nem menos é especificado) a
palavra é opcional, mas as linhas que a contém serão
avaliadas positivamente. Isto define o comportamento de
MATCH() ... AGAINST()
sem o modificados
IN BOOLEAN MODE
.
< >
Estes dois operadores são usados para alterar a
contribuição de uma palvara no valor de relevância que á
tribuído a um registro. O operador <
reduz a contribuição e o operador >
a
aumenta. Veja o exemplo abaixo.
( )
Parenteses são usado para agrupar palavras em subexpressões.
~
Um til precedente atua como um operador de negação, tornando
a contribuição da palavra para a relevância da linha ser
negativa. Ele é útil para marcar palavras "ruidosas". Linhas
com tais palavras terão uma avaliação mais baixa que
outras, mas não será excluída, como seria com o operador
-
.
*
Um asterisco é um operador de truncamento. Diferente dos outros operadores, ele deve ser inserida ao fim da palavra, não deve ser precedente.
"
A frase que é colocada entre aspas duplas
"
, coincidem apenas com linhas que contenha
esta frase literalmente, como foi
digitada.
E aqui estão alguns exeplos:
apple banana
encontra linhas que contenha pela menos uma destas palavras.
+apple +juice
... ambas as palavras.
+apple macintosh
... palavra ``apple'', mas avaliada mais alto se também conter ``macintosh''.
+apple -macintosh
... palavra ``apple'' mas não ``macintosh''.
+apple +(>turnover <strudel)
... ``apple'' e ``turnover'', ou ``apple'' e ``strudel'' (em qualquer ordem), mas avalia ``apple pie'' melhor que ``apple strudel''.
apple*
... ``apple'', ``apples'', ``applesauce'', e ``applet''.
"some words"
... ``some words of wisdom'', mas não ``some noise words''.
Pesquisas full-text são suportadas apenas por tabelas
MyISAM
.
Pesquisas full-text pode ser usadas com UCS-2 (mas funcionam com UTF-8 a partir do MySQL 4.1.1).
Todos os parâmetros da função MATCH()
devem ser colunas da mesma tabela que é parte do mesmo
índice FULLTEXT
, a menos que
MATCH()
esteja IN BOOLEAN
MODE
.
Todas as colunas no índice FULLTEXT
devem ter o mesmo conjunto de caracter.
A lista de coluna MATCH()
deve casar
exatamente a lista de colunas em algum definição de
índice FULLTEXT
para a tabela, a menos
que este MATCH()
seja IN BOOLEAN
MODE
.
O argumento para AGAINST()
deve ser uma
string constante.
Infelizmente, pesquisas full-text ainda possui poucos parâmetros de ajuste, embora adicionar alguns seja de grande prioridade no TODO. Se você tiver uma distribuição fonte do MySQL (see Secção 2.3, “Instalando uma distribuição com fontes do MySQL”), você pode exercer maior controle sobre o comportamenteo de pesquisas full-text.
Note que o busca full-text foi cuidadosamente ajustada para a melhor busca efetiva. Mofificar o comportamento padrão irá, na maioria dos casos, apenas tornar os resultados de busca piores. Não alteren o fonte do MySQL a menos que você saiba o que está fazendo!
A descrição das variáveis full-text na lista a seguir devem ser configuradas no servidor na inicialização. Você não pode modificá-los dinamicamente enquanto o servidor estiver em execução.
O tamanho mínimo de palavras a serem indexadas é definido
pela variavel ft_min_word_len
do MySQL.
See Secção 4.6.8.4, “SHOW VARIABLES
”.
(Esta variável só está disponível a partir do MySQL versão 4.0.)
O valor padrão é quatro caracteres. Altere-o para o valor
de sua preferência e reconstrua os seus índices
FULLTEXT
. Por exemplo, se você quiser
pesquisar palavras de três caracteres, você pode definir
esta variável colocando a seguinte linha no arquivo de
opções:
[mysqld] ft_min_word_len=3
Então reinicie o servidor e reconstrua seus índices
FULLTEXT
.
A lista de palavras de parada pode ser carregada do arquivo
especificado pela variável
ft_stopword_file
. See
Secção 4.6.8.4, “SHOW VARIABLES
”. Reconstrua o seu índice
FULLTEXT
depois de modificar a lista de
palavras de parada. (Esta varável só está disponível a
partir do MySQL versão 4.0.10 e posterior)
O ponto inical de 50% é determinado pelo esquema de pesagem
particular escolhido. Para disabilitá-lo, altere a seguinte
linha em myisam/ftdefs.h
:
#define GWS_IN_USE GWS_PROB
Para:
#define GWS_IN_USE GWS_FREQ
Então recompile o MySQL. Não há necessidade de
reconstruir o índice neste caso.
Note: fazendo isto você
diminui em muito a
habilidade do MySQL fornecer valores de relevância
adequados para a função MATCH()
. Se
você realmente precisa buscar por tais palavras comuns,
seria melhor fazê-lo utilizando IN BOOLEAN
MODE
, que não observa o poonto inicial de 50%.
Algumas vezes o mantedor do mecanismo de busca gostaria de
alterar os operadores usados por busca full-text boolanas.
Eles são definidos pela variável
ft_boolean_syntax
. See
Secção 4.6.8.4, “SHOW VARIABLES
”. Ainda, esta variável é
somente leitura; este valor está definido em
myisam/ft_static.c
.
Para mudanças full-text que exigem que você reconstrua seu
índice FULLTEXT
, o modo mais fácil de
fazê-lo para uma tabela MyISAM
é usar a
seguinte instrução, a qual reconstroi o arquivo de índice:
mysql> REPAIR TABLE nome_tabela QUICK;
Fazer todas as operações com índices
FULLTEXT
mais
rápidas.
Operadores de proximidade
Supporte para "always-index words". Elas poderiam ser quaisquer strings que o usuário quisesse tratar como palavra, os exemplos são "C++", "AS/400", "TCP/IP", etc.
Suporte a busca full-text em tabelas
MERGE
.
Suporte a UCS-2.
Tornar a lista de palavras de parada dependente da linguagem dos dados.
Stemming (dependente da linguagem dos dados. é claro).
Pre-analizadores de UDF genéricas fornecidas pelo usuário.
Tornar os modelos mais flexíveis (adicionando algum
parâmetro ajsutável a FULLTEXT
em
CREATE/ALTER TABLE
).
A partir da versão 4.0.1, O servidor MySQL
dispões do recurso Query Cache
(cache de
consultas). Quando em uso, o cache de consultas armazena o textop
de uma consulta SELECT
junto com o resultado
correspondente que foi enviado para o cliente. Se uma consulta
identica é recebida mais tarde, o servidor retornará o resultado
da cache de consultas ao invés de analisar e executar a mesma
consulta novamente.
NOTE: A cache de consulta não retornam dados antigos. Quando o dado é modificado, qualquer entrada relevante na cache de consulta é atualizado.
A cache de consultas é extremamente útil em um ambiente onde (algumas) tabelas não mudam com frequência e você tem várias consultas idênticas. Esta é uma situação típica em muitos servidores web que utilizam muito conteúdo dinâmico.
Abaixo está algumas performances de dados da cache de consultas. (Estes resultado foram gerados rodando o pacote de benchmark do MySQL em um Linux Alpha 2 x 500 MHz com 2 GB RAM e uma cache de consultas de 64 MB):
Se todas as consultas que você estiver realizando forem simples (tais como selecionar um registro de uma tabela com um registro); mas ainda diferente daquelas em que as consultas não são armazendas, a sobrecarga de ter a cache de consultas ativa é de 13%. Este pode ser considerado como o cenário de pior caso. No entanto, na vida real, consultas são muito mais complicadas que nosso exemplo simples, assim a sobrecarga é, normalmente, significantemente menor.
Buscas depois de uma linha em uma tabela de uma linha é 238% mais rápido. Isto pode ser considerado perto do mínimo de ganho a ser esperado para uma consulta que está armazenada.
Se você quiser disabilitar o codigo da cache de consulta
defina query_cache_size=0
. Disabilitando o
código da cache de consultas não haverá nenhuma sobrecarga
notável. (cache de consultas pode ser excluído do código
com ajuda da opção de coniguração
--without-query-cache
)
Consultas são comparadas antes da análise, logo
SELECT * FROM nome_tabela
e
Select * from nome_tabela
são consideradas consultas diferentes pela cache de consulta, assim consultas precisam ser exatamente a mesma (byte a byte) para serem vistas como idênticas. Além disso, uma consulta pode ser vista como diferente se, por exemplo, um cliente estiver usando um novo formato de protocolo de comunicação ou um conjunto de caracteres diferente de outro cliente.
Cansultas que utilizam banco de dados diferentes, utilizam versões de protocolos diferentes ou que usam conjunto de caracters padrão diferentes são considerados consultas diferentes e armazenadas separadamente.
A cache funciona para consultas do tipo SELECT
SQL_CALC_FOUND_ROWS ...
e SELECT FOUND_ROWS()
...
porque o número de registros encontrados também
é armazenado na cache.
Se o resultado da consulta foi retornado da cache de consultas,
então o estado da variável Com_select
não
irá ser aumentado, mas Qcache_hits
será.
See Secção 6.9.4, “Estado e Manutenção da Cache de Consultas”.
Se uma tabela é alterada (INSERT
,
UPDATE
, DELETE
,
TRUNCATE
, ALTER
ou
DROP TABLE|DATABASE
), então todas as caches
de consulta que utilizam esta tabela (possivelmente atarvés de
uma tabela MRG_MyISAM
!) se torna inválida e
é removida da cache.
Tabelas InnoDB
transacionais que foram
alteradas serão invalidadas quando um COMMIT
é realizado.
No MySQL 4.0 a cache de consulta está disbilitada dentro da
transação (ela não retorna resultados), mas a partir da
versão 4.1.1 as caches de consultas funcionarão com tabelas
InnoDB
dentro da transação (ela usará o
número da versão da tabela para detectar se a data é atual ou
não).
Antes da versão 5.0, consultas com comentários na mesma linha não podem ser trazidas da cache (mas elas serão colocadas na cache se satisfazerem outras condições).
Uma consulta não pode ser armazenada em cache se contem uma das funções:
Função | Função | Função |
Funções Definidas por Usuarios | CONNECTION_ID | FOUND_ROWS |
GET_LOCK | RELEASE_LOCK | LOAD_FILE |
MASTER_POS_WAIT | NOW | SYSDATE |
CURRENT_TIMESTAMP | CURDATE | CURRENT_DATE |
CURTIME | CURRENT_TIME | DATABASE |
ENCRYPT (com um parâmetro) | LAST_INSERT_ID | RAND |
UNIX_TIMESTAMP (sem parâmetros) | USER | BENCHMARK |
Um consulta não pode ser armazenada em cache se conter
variáveis, referenciar o banco de dados do sistema mysql, for
da forma SELECT ... IN SHARE MODE
,
SELECT ... INTO OUTFILE ...
, SELECT
... INTO DUMPFILE ...
ou da forma SELECT *
FROM AUTOINCREMENT_FIELD IS NULL
(para retornar a ID
da ultima inserção - ODBC contorna este problema).
No entanto, FOUND_ROWS()
retornará o valor
correto, mesmo se a consulta precedente foi buscada da cache.
No caso de uma consulta não utilizar qualquer tabela, ou utilizar tabelas temporárias, ou se o usuário tiver um privilégio de coluna para qualquer tabela chamada, esta consulta não será armazenada em cache.
Antes de uma consulta ser trazida da cache de consulta, o MySQL irá verificar se o usuário com privilégio SELECT para todos os banco de dados e tabelas envolvidos. Se este não for o caso, o resultado em cache não será usado.
A cache de consultas adiciona algumas variáveis do sistema
MySQL
para mysqld
os quais
podem ser definidos em um arquivo de configuração, na linha de
comando ao iniciar mysqld
.
query_cache_limit
Não armazene em cache
resultados que são maiores que isto. (Padrão 1M).
query_cache_min_res_unit
Esta variável está presente a partir da versão 4.1.
O resultado de uma consulta (os dados que também são
enviados ao cliente) é armazenado na cache de consulta
durante o recuperação do resultado. Consequentemente o
dado normalmente não é tratado em um grande bloco. A cache
de de conaultas aloca blocos para armazenar o dado em
demanda, assim quando um bloco é preenchido, um novo bloco
é alocado. Como a operação de alocação de memória é
caro, a cache de consulta aloca blocos com um tamanho
mínimo de query_cache_min_res_unit
.
Quando a consulta é executada, o último bloco do resultado
é cortado para o tamanho atual do dado, assim a memória
sem uso é liberada.
O valor padrão de
query_cache_min_res_unit
é 4 KB o
qual deve ser adequada para a maioria dos casos.
Se você tiver várias consultas com resultados
pequenos, o tamanho padrão do bloco pode levar a
fragmentação de memória (indicado por um grande
número de blocos livres
(Qcache_free_blocks
), que podem fazer
a cache de consultas deletar consultas da cache devido a
perda de memória)
(Qcache_lowmem_prunes
)). Neste caso
você deve diminuir
query_cache_min_res_unit
.
Se você tem muitas consultas com resultados grandes
(veja Qcache_total_blocks
e
Qcache_queries_in_cache
),você pode
aumentar a performance aumentadno
query_cache_min_res_unit
. No entanto,
seja cuidadoso para não torná-lo muito grande (veja o
ponto anterior).
query_cache_size
A quantidade de memória
(especificada em bytes) alocada para armazenar resultados de
consultas antigas. Se ele for 0, a cache de consultas está
desbilitada (padrão).
query_cache_type
Pode ser atribuido
(apenas numérico) com
Opção | Descrição |
0 | (OFF, não armazene ou retorne resultados) |
1 | (ON, armazene todos os resultados, exceto consultas SELECT
SQL_NO_CACHE ... ) |
2 | (DEMAND, armazene apenas cconsultas SELECT SQL_CACHE
... ) |
Dentro de uma thread (conexão), o comportamento da cache de consulta pode ser alterado do padrão. A sintaxe é a seguinte:
QUERY_CACHE_TYPE = OFF | ON | DEMAND
QUERY_CACHE_TYPE = 0 | 1 | 2
Opção | Descrição |
0 or OFF | Não armazene ou recupere resultados |
1 or ON | Aramazene todos os resultados exceto consultas SELECT
SQL_NO_CACHE ... . |
2 or DEMAND | Armazene apenas consultas SELECT SQL_CACHE ... . |
Existem duas possibilidades de parâmetros relacionados a cache
de consultas que podem ser especificados em uma consulta
SELECT
:
Opção | Descrição |
SQL_CACHE | Se QUERY_CACHE_TYPE é DEMAND ,
permite que a query seja armazenada em cache. Se
QUERY_CACHE_TYPE é
ON , este é o padrão. Se
QUERY_CACHE_TYPE é
OFF , não faz nada. |
SQL_NO_CACHE | Faz esta consulta não armazenável em cache, não permite que esta consulta seja armazenada em cache. |
Com o comando FLUSH QUERY CACHE
você pode
desfragmentar a cache de consultas para melhor utilizar a
memória. Este comnado não removerá qualquer consulta da
cache. FLUSH TABLES
também descarrega a
cache de consultas.
O camnado RESET QUERY CACHE
remove todas os
resultados de consultas da cache de consultas.
Você pode verificar se a cache de consltas está presente em sua versão do MySQL:
mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
1 row in set (0.00 sec)
Você pode monitorar o desempenho da cache de consultas com
SHOW STATUS
:
Variável | Descrição |
Qcache_queries_in_cache | Número de consultas registrada na cache. |
Qcache_inserts | Número de consultas adicionadas na cache. |
Qcache_hits | Número de acertos da cache. |
Qcache_lowmem_prunes | Número de consultas que foram deletadas da cache devido a memória baixa. |
Qcache_not_cached | N;úmero de consultas não armazenadas em cache (não armazenáveis, ou
devido a QUERY_CACHE_TYPE ). |
Qcache_free_memory | Quantidade de memória livre para cache de consultas. |
Qcache_free_blocks | Número de blocos de memória livre na cache de consultas |
Qcache_total_blocks | Número total de blocos na cache de consultas. |
Número total de consultas = Qcache_inserts
+
Qcache_hits
+
Qcache_not_cached
.
A cache de consultas utiliza blocos de tamanhos variáveis,
assim Qcache_total_blocks
e
Qcache_free_blocks
podem indicar
fragmentação de memória da cache de consultas. Depois de um
FLUSH QUERY CACHE
apenas um único (grande)
bloco livre permanece.
Nota: Toda consulta precisa de um mínimo de 2 blocos (um para o texto da consulta e um ou mais para o resultado da conulta). Também, cada tabela que é usada por uma consulta precisa de um bloco, mas se duas ou mais consultas usam a mesma tabela, apenas um bloco precisa ser alocado.
Você pode utilizar a variável de estado
Qcache_lowmem_prunes
para ajustar o tamanho
da cache de consultas. Ela conta o número de consultas que são
removidas da cache para liberar memória para armazenar novas
consultas. A cache de consultas utiliza uma estratégia
least recently used
(LRU
)
para decidir quais consultas serão removidas da cache.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.