Referência de Linguagem do MariaDB - Databases - Software - Computers

Referência de Linguagem do MariaDB

Índice

Estrutura da Linguagem
Literais: Como Gravar Strings e Numerais
Nomes de Banco de dados, Tabela, Índice, Coluna e Alias
Caso Sensitivo nos Nomes
Variáveis de Usuário
Variáveis de Sistema
Sintaxe de Comentários
Tratamento de Palavras Reservadas no MySQL
Tipos de Campos
Tipos Numéricos
Tipos de Data e Hora
Tipos String
Escolhendo o Tipo Correto para uma Coluna
Usando Tipos de Colunas de Outros Mecanismos de Banco de Dados
Exigências de Armazenamento dos Tipos de Coluna
Funções para Uso em Cláusulas SELECT e WHERE
Operadores e Funções de Tipos não Especificados
Funções String
Funções Numéricas
Funções de Data e Hora
Funções de Conversão
Outras Funções
Funções e Modificadores para Usar com Cláusulas GROUP BY
Manipulação de Dados: SELECT, INSERT, UPDATE e DELETE
Sintaxe SELECT
Sintaxe de Subquery
Sintaxe INSERT
Sintaxe UPDATE
Sintaxe DELETE
Sintaxe TRUNCATE
Sintaxe REPLACE
Sintaxe LOAD DATA INFILE
Sintaxe HANDLER
Sintaxe DO
Definição de Dados: CREATE, DROP e ALTER
Sintaxe CREATE DATABASE
Sintaxe DROP DATABASE
Sintaxe CREATE TABLE
Sintaxe ALTER TABLE
Sintaxe RENAME TABLE
Sintaxe DROP TABLE
Sintaxe CREATE INDEX
Sintaxe DROP INDEX
Comandos Utilitários Básicos do Usuário MySQL
Sintaxe USE
Sintaxe DESCRIBE (Obtem Informações Sobre Colunas)
Comandos Transacionais e de Lock do MariaDB
Sintaxe de START TRANSACTION, COMMIT e ROLLBACK
Instruções que Não Podem Ser Desfeitas
Instruções que Fazem um Commit Implicito
Sintaxe de SAVEPOINT e ROLLBACK TO SAVEPOINT
Sintaxe LOCK TABLES e UNLOCK TABLES
Sintaxe SET TRANSACTION
Pesquisa Full-text no MySQL
Restrições Full-text
Ajuste Fino de Pesquisas Full-text no MySQL
TODO de Pesquisas Full-text
Cache de Consultas do MariaDB
Como a Cache de Consultas Opera
Configuração da Cache de Consultas
Opções da Cache de Consultas na SELECT
Estado e Manutenção da Cache de Consultas

O MariaDB possui uma interface SQL muito complexa mas intuitiva e fácil de aprender. Este descreve os vários comandos, tipos e funções que você precisa conhecer para usar o MariaDB de maneira eficiente e efetiva. Este também serve como referência para todas as funcionalidades incluídas no MariaDB. Para poder utilizar este eficientemente, você deve achar útil fazer referência aos vários índices.

Estrutura da Linguagem

Literais: Como Gravar Strings e Numerais
Nomes de Banco de dados, Tabela, Índice, Coluna e Alias
Caso Sensitivo nos Nomes
Variáveis de Usuário
Variáveis de Sistema
Sintaxe de Comentários
Tratamento de Palavras Reservadas no MySQL

Literais: Como Gravar Strings e Numerais

Strings
Números
Valores Hexadecimais
Valores NULL

Esta seção descreve as diversas maneiras para gravar strings e números no MariaDB. Ela também cobre as várias nuances e pegadinhas pelas quais você pode passar ao lidar com estes tipos básicos no MariaDB.

Strings

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 MariaDB reconhece a seguinte sequência de escape:

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:

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:

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. Leia Seçã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. Leia Seçã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 MariaDB 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ê.

Números

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.

Valores Hexadecimais

O MariaDB 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';
 -> MariaDB mysql> SELECT 0xa+0;
 -> 10
mysql> SELECT 0x5061756c;
 -> Paul

No MariaDB (e no MariaDB 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().

Valores NULL

O valor NULL significa sem dados e é diferente de valores como 0 para tipos numéricos ou strings vazias para tipos string. Leia Seçã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). Leia 'Sintaxe LOAD DATA INFILE'.

Nomes de Banco de dados, Tabela, Índice, Coluna e Alias

Nomes de banco de dados, tabela, índice, coluna e apelidos seguem todos as mesmas regras no MariaDB.

Note que as regras foram alteradas desde o MariaDB v3.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. Leia 'Executando o MariaDB 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 'Tratamento de Palavras Reservadas no MySQL'.

Se você estiver executando o MariaDB 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 'Opções de Linha de Comando do mysqld'.

Em versões do MariaDB anteriores a 3.23.6, as regras se nomes eram as seguintes:

É 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 MariaDB 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 MariaDB 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 '.'.

Caso Sensitivo nos Nomes

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. Leia 'Extensões do MariaDB 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 MariaDB 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.

Variáveis de Usuário

O MariaDB 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 '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 MariaDB 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.

Variáveis de Sistema

A partir do MariaDB 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. Leia '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 MariaDB retornará o valor específico da thread (SESSION), se ele existir. Se não, o MariaDB 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. Leia 'Opções de Linha de Comando do mysqld'. Leia 'SHOW VARIABLES'. Leia 'Sintaxe de SET'.

Sintaxe de Comentários

O servidor MariaDB 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 MariaDB analisa o comentário /* ... */:

Estas limitações se aplicam tanto a quando se executa MariaDB interativamente quanto quando se coloca oos comandos em um arquivo e pede para que MariaDB 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 Leia ''--' como Início de Comentário'.

Tratamento de Palavras Reservadas no MariaDB

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 '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 MariaDB 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
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 XOR YEAR_MONTH
ZEROFILL

São as seguintes as novas palavras reservadas do MariaDB 4.0:

CHECK FORCE LOCALTIME
LOCALTIMESTAMP REQUIRE SQL_CALC_FOUND_ROWS
SSL XOR

São as seguintes as novas palavras reservadas do MariaDB 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 MariaDB como nome de campos/tabelas. Isto ocorre porque alguns destes nomes são muito naturais e vários pessoas já o utilizaram.

Tipos de Campos

Tipos Numéricos
Tipos de Data e Hora
Tipos String
Escolhendo o Tipo Correto para uma Coluna
Usando Tipos de Colunas de Outros Mecanismos de Banco de Dados
Exigências de Armazenamento dos Tipos de Coluna

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 MariaDB estão listados abaixo: As seguintes letras são usadas como código nas descrições:

Colchetes ('[' and ']') indicam partes de tipos específicos que são opicionais

Note que se você especificar ZEROFILL para um campo MariaDB 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! Leia 'Funções de Conversão'.

Tipos Numéricos

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. MariaDB 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), MariaDB armazena o valor correspondente ao final daquela faixa.

Como uma extensão do padrão ANSI/ISO SQL92, MariaDB também suporta os tipos integrais TINYINT, MEDIUMINT, e BIGINT como listado nas tabelas abaixo. Outra extensão suportada pelo MariaDB é 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 MariaDB gerar tabelas temporárias para algum join complicado, já que nestes casos o MariaDB 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 MariaDB 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 MariaDB também suporta esta especificação opcional de precisão. Quando FLOAT é usada para uma tipo de coluna sem especificação de precisão, MariaDB 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 MariaDB 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 MariaDB 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, MariaDB 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 MariaDB 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

Tipos de Data e Hora

Assuntos referentes ao ano 2000 (Y2K) e Tipos de Data
Os Tipos DATETIME, DATE e TIMESTAMP
O Tipo TIME
O Tipo YEAR

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 MariaDB 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, MariaDB 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 MariaDB 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.

Assuntos referentes ao ano 2000 (Y2K) e Tipos de Data

O MariaDB tem sua própria segurança para o ano 2000 (see 'Compatibilidade Com o Ano 2000 (Y2K)'), mas os dados entrados no MariaDB 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 MariaDB armazena anos internamente utilizando 4 digitos.

Para tipos DATETIME, DATE, TIMESTAMP e YEAR, MariaDB interpreta datas com valores ambíguos para o ano usando as seguintes regras:

Lembre-se de que essas regras fornecem apenas palpites razoáveis sobre o que a sua data significa. Se a heurística usada pelo MariaDB 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

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. MariaDB 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. MariaDB 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 MariaDB e do modo SQL que o servidor está executando.

Comportamento do TIMESTAMP ao executar no modo MAXDB

Quando o MariaDB 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 MariaDB pode ser executado no modo MAXDB a partir da versão 4.1.1. Leia '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:

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:

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 MariaDB 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 MariaDB pode ser executado no modo MAXDB a partir da versão 4.1.1. Leia 'Opções de Linha de Comando do mysqld'.

Propriedades TIMESTAMP a partir do MariaDB quando não executado no modo MAXDB

No MariaDB 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 MariaDB anteriores.

Propriedades TIMESTAMP antes do MariaDB 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 MariaDB 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:

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 MariaDB 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 MariaDB 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:

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

Esteja ciente de certas dificuldades quando especificar valores de data:

O Tipo TIME

O MariaDB 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:

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 MariaDB 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 MariaDB 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

O tipo YEAR é um tipo de 1 byte usado para representar anos.

O MariaDB 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:

Valores YEAR ilegais são convertidos para 0000.

Tipos String

Os Tipos CHAR e VARCHAR
Os Tipos BLOB e TEXT
O Tipo ENUM
O Tipo SET

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

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 MariaDB, 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 MariaDB 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. Leia 'Alteração de Especificações de Colunas'.

Os Tipos BLOB e TEXT

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. Leia '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:

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.

O Tipo ENUM

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:

Cada enumeração tem um índice:

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.

O Tipo SET

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.

Escolhendo o Tipo Correto para uma 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 MariaDB 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.

Usando Tipos de Colunas de Outros Mecanismos de Banco de Dados

Para facilitar o uso de code para implementações SQL de outras empresas, MariaDB 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, MariaDB relaciona a estrutura de tabela utilizando os tipos equivalentes do MariaDB.

Exigências de Armazenamento dos Tipos de Coluna

As exigências de armazenamento para cada um dos tipos de colunas suportados pelo MariaDB 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. Leia '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, MariaDB pode, sob certas condições, mudar uma coluna de um tipo de tamanho variável para um tipo de tamanho fixo, ou vice-versa. Leia '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. Leia '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. Leia '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.

Funções para Uso em Cláusulas SELECT e WHERE

Operadores e Funções de Tipos não Especificados
Funções String
Funções Numéricas
Funções de Data e Hora
Funções de Conversão
Outras Funções
Funções e Modificadores para Usar com Cláusulas GROUP BY

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 MariaDB 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 MariaDB 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. Leia 'Executando o MariaDB no modo ANSI'.

Para sermos breve, exemplos mostram a saida do programa MariaDB 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

Operadores e Funções de Tipos não Especificados

Parenteses
Operadores de Comparação
Operadores Logicos
Funções de Fluxo de Controle

Parenteses

( ... )

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

Operadores de Comparação

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:

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 MariaDB 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' ...

Operadores Logicos

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.

Funções de Fluxo de Controle

Funções String

Funções de Comparação de Strings
Caso Sensitivo

Funções string retornam NULL se o tamanho do resultado for maior que o parâmetro do servidor max_allowed_packet. Leia '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.

Funções de Comparação de Strings

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.

Caso Sensitivo

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.

Funções Numéricas

Operações Aritiméticas
Funções Matematicas

Operações Aritiméticas

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. Leia 'Funções de Conversão'.

Funções Matematicas

Todas as funções matematicas retornam NULL no caso de um erro.

Funções de Data e Hora

Esta seção descreve as funções que podem ser usadas para manipular valores temporais.

Veja '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.

Funções de Conversão

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:

CAST() e CONVERT() estão disponíveis a partir do MariaDB 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 MariaDB 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 MariaDB 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 MariaDB (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(). Leia '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 MariaDB 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 MariaDB para suportar valores BIGINT apropriadamente. Se você tiver algum código que deseja executar no MariaDB 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 MariaDB antiga ao portar para o MariaDB 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);

Outras Funções

Funções Binárias
Funções Diversas

Funções Binárias

O MariaDB utiliza aritimética BIGINT (64bits) para operações binárias, assim estes operadores possuem uma faixa máxima de 64 bits.

Funções Diversas

Funções e Modificadores para Usar com Cláusulas GROUP BY

Funções GROUP BY
Modificadores GROUP BY
GROUP BY com Campos Escondidos

Funções GROUP BY

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.

Modificadores GROUP BY

No MariaDB, 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:

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 MariaDB 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.

GROUP BY com Campos Escondidos

O MariaDB 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 'As Linhas Armazenando o Group-wise Máximo de um Certo Campo'.

Note que se você estiver usando a versão 3.22 do MariaDB (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 MariaDB você pode fazer:

mysql> SELECT id,FLOOR(value/100) FROM nome_tabela ORDER BY RAND();

Manipulação de Dados: SELECT, INSERT, UPDATE e DELETE

Sintaxe SELECT
Sintaxe de Subquery
Sintaxe INSERT
Sintaxe UPDATE
Sintaxe DELETE
Sintaxe TRUNCATE
Sintaxe REPLACE
Sintaxe LOAD DATA INFILE
Sintaxe HANDLER
Sintaxe DO

Sintaxe SELECT

Sintaxe JOIN
Sintaxe UNION
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.

Sintaxe JOIN

O MariaDB 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 MariaDB 4.0.11.

A última sintaxe LEFT OUTER JOIN mostrada na lista anterior só existe para compatibilidade com ODBC:

Nota: USE/IGNORE/FORCE INDEX afeta apenas os índices usados quando o MariaDB 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 'Como o MariaDB Otimiza LEFT JOIN e RIGHT JOIN'.

Sintaxe UNION

SELECT ...
UNION [ALL]
SELECT ...
 [UNION
 SELECT ...]

UNION foi implementado no MariaDB 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:

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;

Sintaxe de Subquery

A Subquery como um Operando Escalar
Comparações Usando Subquery
Subqueries with ANY, IN, and SOME
Subqueries with ALL
Correlated Subqueries
EXISTS and NOT EXISTS
Row Subqueries
Subqueries in the FROM clause
Subquery Errors
Optimizing Subqueries
Rewriting Subqueries for Earlier MariaDB Versions

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 MariaDB suporta todas as formas de subqueries e operações que o padrão SQL exige, assim como alguns recursos que são especificos do MariaDB. A principal vantagem das subqueries são:

Com versões MariaDB 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 MariaDB.

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 MariaDB anteriores a 4.1, a maioria da subqueries podem ser reescritas corretamente usando join e outros métodos. Leia 'Rewriting Subqueries for Earlier MariaDB Versions'.

A Subquery como um Operando Escalar

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.

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;

Comparações Usando Subquery

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);

Subqueries with ANY, IN, and SOME

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.

Subqueries with ALL

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.

Correlated Subqueries

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 MariaDB 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: MariaDB 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, MariaDB 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.

EXISTS and NOT EXISTS

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 -- MariaDB 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?.

Row Subqueries

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 in the FROM clause

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.

Subquery Errors

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.

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.

Optimizing Subqueries

Development is ongoing, so no optimization tip is reliable for the long term. Some interesting tricks that you might want to play with are:

The above tricks may cause programs to go faster or slower. Using MariaDB 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 MariaDB itself will make are:

  1. MySQL will execute non-correlated subqueries only once, (use EXPLAIN to make sure that a given subquery really is non-correlated),
  2. 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,
  3. 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,

  4. MySQL will enhance expressions of the form

    value {ALL|ANY|SOME} {> | < | >= | <=} (non-correlated subquery)
    

    with an expression involving MIN or MAX (unless NULLs 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 MariaDB Transforms Subqueries in the MariaDB Internals Manual, which you can find by downloading the MariaDB source package and looking for a file named internals.texi.

Rewriting Subqueries for Earlier MariaDB Versions

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 MariaDB 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, MariaDB 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:

MySQL Server 4.0 supports multiple-table DELETEs 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 UPDATEs are also supported from version 4.0.

Sintaxe INSERT

Sintaxe INSERT ... SELECT
Sintaxe INSERT DELAYED
 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 MariaDB.

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ê 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:

Sintaxe INSERT ... SELECT

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:

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.

Sintaxe INSERT DELAYED

INSERT DELAYED ...

A opção DELAYED para a instrução INSERT é um opção específica do MariaDB 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 MariaDB para fazer log e você também execute periodicamente instruções SELECT e UPDATE que levem muito tempo para completar. DELAYED foi intriduzido no MariaDB versão 3.22.15. Ela é uma extensão do MariaDB 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. Leia '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.

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!

Sintaxe UPDATE

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 WHEREi, 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 MariaDB notará isto é não irá atualizá-la.

UPDATE retorna o número de linhas que forma realmente alteradas. Desde o MariaDB v3.22, 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 MariaDB versão 3.23, você pode utilizar LIMIT row_count para restringir o escopo do UPDATE. Uma cláusula LIMIT funciona da seguinte forma:

Se uma cláusula ORDER BY é utilizada (disponível no MariaDB 4.0.0), as linhas serão atualizadas nesta ordem. Isto só é util em conjunto com LIMIT.

A partir da MariaDB 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.

Sintaxe DELETE

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. Leia 'Sintaxe TRUNCATE'. No MariaDB 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 'Performance das Consultas que Utilizam DELETE'.

A opção IGNORE faz com que o MariaDB 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 'Sintaxe de OPTIMIZE TABLE' e 'Otimização de Tabelas'.

O primeiro formato de delção de multi-tabelas é suportado a partir do MariaDB 4.0.0. O segundo formato de deleção multi-tabelas é suportado a partir do MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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.

Sintaxe TRUNCATE

TRUNCATE TABLE nome_tabela

Na versão 3.23 TRUNCATE TABLE é mapeada para COMMIT; DELETE FROM table_name. Leia 'Sintaxe DELETE'.

TRUNCATE TABLE difere de DELETE FROM ... do seguinte modo:

TRUNCATE é uma extensão Oracle SQL. Esta instrução foi adicionada no MariaDB 3.23.28, embora da versão 3.23.28 a 3.23.32, a palavra chave TABLE deva ser omitida.

Sintaxe REPLACE

 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. Leia '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 MariaDB 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

Sintaxe LOAD DATA INFILE

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 MariaDB 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. Leia 'Privilégios Fornecidos pelo MySQL'.

A partir do MariaDB 3.23.49 e MariaDB 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. Leia '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 MariaDB 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:

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). Leia '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. Leia 'Utilizando myisamchk para Manutenção de Tabelas e Recuperação em Caso de Falhas'.

LOAD DATA INFILE é o complemento de SELECT ... INTO OUTFILE. Leia '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:

Inversamente, os padrões fazem SELECT ... INTO OUTFILE funcionar da seguinte forma ao escrever as saídas:

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 INFILEnã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:

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 'Literais: Como Gravar Strings e Numerais'.

Em certos casos, as opções de tratamento de campoe e linhas se interagem:

O tratamento do valor NULL varia, dependendo das opções de FIELDS e LINES que voce usar:

Alguns casos não são suportados por LOAD DATA INFILE:

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 MariaDB 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 'Sintaxe CREATE TABLE'.

Um valor de campo vazio é interpretado de forma diferente de que se o valor do campo estiiver faltando:

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 MariaDB o aviso é apenas um número que indica que alguma coisa deu errado. No MariaDB 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 '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 MariaDB a anterior a 3.23.25 você só poderá fazer o descrito acima com LOAD DATA LOCAL INFILE.

No MariaDB você pode usar SHOW WARNINGS para conseguir a lista do primeiros max_error_count avisos. Leia '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, Leia 'Performance das Consultas que Utilizam INSERT'.

Sintaxe HANDLER

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:

Sintaxe DO

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.

Definição de Dados: CREATE, DROP e ALTER

Sintaxe CREATE DATABASE
Sintaxe DROP DATABASE
Sintaxe CREATE TABLE
Sintaxe ALTER TABLE
Sintaxe RENAME TABLE
Sintaxe DROP TABLE
Sintaxe CREATE INDEX
Sintaxe DROP INDEX

Sintaxe CREATE DATABASE

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 '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 MariaDB 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 MariaDB.

Você também pode criar banco de dados com mysqladmin. Leia 'Utilitários e Scripts do Lado do Cliente MySQL'.

Sintaxe DROP DATABASE

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.

Desde o MariaDB v3.22, 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. Leia 'Utilitários e Scripts do Lado do Cliente MySQL'.

Sintaxe CREATE TABLE

Alteração de Especificações de Colunas
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 '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.

Desde o MariaDB v3.22, 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.

Desde o MariaDB v3.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 MariaDB 4.0.2 você deve ter o privilégio CREATE TEMPORARY TABLES para poder criar tabelas temporárias.

Desde o MariaDB v3.23 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 MariaDB 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, 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 MariaDB você pode utilizar LIKE para criar uma tabela baseada em uma definição de outra tabela. No MariaDB 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 'Tipos de Campos':

Alteração de Especificações de Colunas

Em alguns casos, MariaDB altera sem aviso uma especificação de coluna dada em uma instrução CREATE TABLE. (Isto também pode ocorrer com ALTER TABLE.):

Se você quiser ver se o MariaDB 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. Leia Seção 7.1.2.3, 'Características de Tabelas Compactadas'.

Sintaxe ALTER TABLE

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. Leia '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 MariaDB tenha ignorado ou a sua modificação por uma das razões descritas em 'Alteração de Especificações de Colunas'. Por exemplo, se você tentar alterar uma coluna VARCHAR para CHAR, MariaDB 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 MariaDB 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.

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. Leia '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.

See Seção A.7.1, 'Problemas com ALTER TABLE.'.

Sintaxe RENAME TABLE

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 MariaDB 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 MariaDB 3.23.23.

Sintaxe DROP TABLE

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!

Desde o MariaDB v3.22m 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. Leia '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:

Usar TEMPORARY é uma boa maneira de assegurar que você não apague uma tabela real.

Sintaxe CREATE INDEX

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 MariaDB anterior a 3.22. Na versão 3.22 ou posteriores, CREATE INDEX é mapeado para uma instrução ALTER TABLE para criar índices. Leia '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. Leia '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 MariaDB 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 MariaDB Versão 3.23.2 ou mais novo e estiver usando os tipos de tablea MyISAM ou BDB, ou MariaDB 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 MariaDB utiliza índices, veja 'Como o MariaDB 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 MariaDB Versão 3.23.23 e posterior. 'Pesquisa Full-text no MySQL'.

Sintaxe DROP INDEX

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 MariaDB anteriores a 3.22. Na versão 3.22 ou posterior, DROP INDEX é mapeada em uma instrução ALTER TABLE para apagar o índice. Leia 'Sintaxe ALTER TABLE'.

Comandos Utilitários Básicos do Usuário MariaDB

Sintaxe USE
Sintaxe DESCRIBE (Obtem Informações Sobre Colunas)

Sintaxe USE

USE nome_db

A instrução USE nome_bd diz ao MariaDB 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.

Sintaxe DESCRIBE (Obtem Informações Sobre Colunas)

{DESCRIBE | DESC} nome_tabela [nome_coluna | meta_carac]

DESCRIBE á um atalho para SHOW COLUMNS FROM. Leia '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 MariaDB altera o tipo das colunas. Leia 'Alteração de Especificações de Colunas'.

Esta instrução é fornecida para compatibilidade com Oracle.

A instrução SHOW fornece informação similar. Leia 'Sintaxe de SHOW'.

Comandos Transacionais e de Lock do MariaDB

Sintaxe de START TRANSACTION, COMMIT e ROLLBACK
Instruções que Não Podem Ser Desfeitas
Instruções que Fazem um Commit Implicito
Sintaxe de SAVEPOINT e ROLLBACK TO SAVEPOINT
Sintaxe LOCK TABLES e UNLOCK TABLES
Sintaxe SET TRANSACTION

Sintaxe de START TRANSACTION, COMMIT e ROLLBACK

Por padrão, MariaDB é executado em modo autocommit. Isto significa que assim que você executa uma instrução que atualiza (modifica) uma tabela, o MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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. Leia 'O Log Binário'.

Você pode alterar o nível isolação para transações com SET TRANSACTION ISOLATION LEVEL. Leia 'Sintaxe SET TRANSACTION'.

Instruções que Não Podem Ser Desfeitas

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.

Instruções que Fazem um Commit Implicito

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 MariaDB 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.

Sintaxe de SAVEPOINT e ROLLBACK TO SAVEPOINT

A partir do MariaDB 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.

Sintaxe LOCK TABLES e UNLOCK TABLES

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 MariaDB 4.0.2 você precisa do privilégio global LOCK TABLES e um privilégio SELECT nas tabelas envolvidas No MariaDB 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 MariaDB 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:

  1. Ordene todas as tabelas a serem travadas em uma ordem definida internamente (do ponto do usuário a ordem é indefinida).
  2. Se uma tabela é bloqueada com uma trava de leitura e de escrita, coloque a trava de escrita antes da trava de leitura.
  3. 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 MariaDB 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. Leia '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:

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. Leia 'Funções Diversas'.

Veja 'Como o MariaDB 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. Leia Seçã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.

Sintaxe SET TRANSACTION

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 'InnoDB e SET ... TRANSACTION ISOLATION LEVEL ...'. O InnoDB suporta cada um destes níveis a partir do MariaDB 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=.... Leia 'Opções de Linha de Comando do mysqld'.

Pesquisa Full-text no MariaDB

Restrições Full-text
Ajuste Fino de Pesquisas Full-text no MySQL
TODO de Pesquisas Full-text
MATCH (col1,col2,...) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION] )

A partir da versão 3.23.23, MariaDB tem suporte para indexação e busca full-text. Índices full-text no MariaDB 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 MariaDB Efficiently', 'After you went through a ...'),
 -> (NULL,'Optimizing MySQL','In this tutorial we will show ...'),
 -> (NULL,'1001 MariaDB Tricks','1. Never run mysqld as root. 2. ...'),
 -> (NULL,'MySQL vs. YourSQL', 'In the following database comparison ...'),
 -> (NULL,'MySQL Security', 'When configured properly, MariaDB ...');
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 | MariaDB vs. YourSQL | In the following database comparison ... |
| 1 | MariaDB 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 MariaDB 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 MariaDB as root') AS score
 -> FROM articles WHERE MATCH (title,body) AGAINST
 -> ('Security implications of running MariaDB as root');
+----+-------------------------------------+-----------------+
| id | body | score |
+----+-------------------------------------+-----------------+
| 4 | 1. Never run mysqld as root. 2. ... | 1.5055546709332 |
| 6 | When configured properly, MariaDB ... | 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 MariaDB 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 '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 MariaDB 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, MariaDB 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 | MariaDB Tutorial | DBMS stands for DataBase ... |
| 2 | How To Use MariaDB Efficiently | After you went through a ... |
| 3 | Optimizing MariaDB | In this tutorial we will show ... |
| 4 | 1001 MariaDB Tricks | 1. Never run mysqld as root. 2. ... |
| 6 | MariaDB Security | When configured properly, MariaDB ... |
+----+------------------------------+-------------------------------------+

Esta consulta recupera todos os registros que contenham a palavra MariaDB (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 MariaDB 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:

E aqui estão alguns exeplos:

Restrições Full-text

Ajuste Fino de Pesquisas Full-text no MariaDB

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 MariaDB (see 'Instalando uma distribuição com fontes do MariaDB'), 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 MariaDB 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.

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;

TODO de Pesquisas Full-text

Cache de Consultas do MariaDB

Como a Cache de Consultas Opera
Configuração da Cache de Consultas
Opções da Cache de Consultas na SELECT
Estado e Manutenção da Cache de Consultas

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 MariaDB em um Linux Alpha 2 x 500 MHz com 2 GB RAM e uma cache de consultas de 64 MB):

Como a Cache de Consultas Opera

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á. Leia '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 MariaDB 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 MariaDB 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.

Configuração da Cache de Consultas

A cache de consultas adiciona algumas variáveis do sistema MariaDB para mysqld os quais podem ser definidos em um arquivo de configuração, na linha de comando ao iniciar mysqld.

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 ....

Opções da Cache de Consultas na SELECT

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.

Estado e Manutenção da Cache de Consultas

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 MariaDB:

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.



Anterior Próximo
Otimização do MariaDB Início Tipos de Tabela do MariaDB