Structure Query Language – SQL
Guilherme Pontes – [Link]
1. Domínio dos Atributos
Por domínio, ou tipo, pode-se entender como a maneira como
determinado atributo (ou campo, se tratando de tabelas) armazena seu
dado. Em melhores palavras, cada atributo possui a capacidade de
armazenar um dado pertinente a uma linha (tupla) da tabela. Que dado
é esse? Dados como código, CPF, nome, preço, quantidade, entre
outros, são geralmente armazenados e gerenciados pelos SGBD’s. A
maneira como o atributo nome armazena seus caracteres difere da
maneira como o preço guarda seu valor. Essa maneira, ou forma de
armazenamento é definida pelo domínio do atributo.
Em geral temos tipos como CHAR, para armazenamento de caracteres,
NUMBER, para números, DATE para datas, entre outros. Cada SGBD’s,
apesar de trabalhar com SQL, possui seus próprios tipos de dados.
Veremos adiante alguns dos muitos tipos oferecidos por três bases:
Oracle 10g, MySQL e Firebird.
Onde vou especificar o tipo do atributo? Durante o processo de
criação/modificação das tabelas, o domínio deverá ser especificado logo
após a definição do nome do atributo.
Domínio dos Atributos no MySQL
Sua ideologia é oferecer aos desenvolvedores uma
ferramenta rápida e simplificada, se comparada aos
SGBD’s existentes, contudo, o MySQL, ainda assim
oferece uma grande variedade de tipos. Veremos
abaixo os principais.
O MySQL oferece vários tipos numéricos, contudo, aqui, trabalharemos
com apenas alguns deles. Para maiores esclarecimentos, consulte
[Link]
Tipo Descrição Tamanho
Integer Número inteiro com (default do campo) ou 4 bytes
sem sinal (acrescido da sintaxe
unsigned). No primeiro caso, varia de
-2147483648 até 2147483647. Sem a
presença do sinal, a margem de valores é
de 0 até 429.496.295.
Float Número com vírgula de pequena 4 bytes
precisão. Pode ou não conter o sinal.
Double Número com vírgula de grande precisão. 8 bytes
Trabalha com ou sem a presença da
sintaxe unsigned (sem sinal).
Tipo Descrição Tamanho
Numeric(M,D) Número que varia sua precisão de acordo M+2 bytes
com a definição do usuário. M representa (se D > 0)
a quantidade total (à esquerda e direita da ou
vírgula) de elementos. D representa o M+1 byte
número de casas decimais. (se D = 0)
De forma análoga, focaremos nosso estudo em apenas alguns tipos
usados para armazenar data/hora.
Tipo Descrição Tamanho
Date Armazena datas variando entre 3 bytes
01/01/1001 à 31/12/9999. Deve-se ter
atenção a inclusão (conceito abordado
futuramente) de dados. O formato a ser
seguido entre aspas é: aaaa/mm/dd.
DateTime Usado para armazenar data e hora que 8 bytes
varie entre 01/01/1001 às 0 horas, 0
minutos e 0 segundos à 31/12/9999 às 23
horas, 59 minutos e 59 segundos. Seu
formato é aaaa/mm/dd hh:mm:ss e deve
ser usado entre aspas.
Time Armazena uma hora que obedece ao 3 bytes
seguinte formato (entre aspas): hh:mm:ss
Por fim, para armazenamento de seqüência de caracteres, temos:
Tipo Descrição Tamanho
Char(n) Armazena n caracteres. Neste caso, n bytes
quando especificamos um valor para n, o
campo sempre ocupará n bytes – mesmo
que estes não sejam usados. Por
exemplo: um Char(10) armazenando o
texto ‘casa’ ocupa 10 bytes, mesmo casa
contendo 4 caracteres. n varia de 0 a 255.
VarChar(n) Armazena n caracteres, contudo, ocupa n+1 bytes
exatamente a quantidade de caracteres
usados (acrescidos de um). Quando
temos VarChar(10) armazenando casa,
este campo ocupa 5 bytes.
Text Um texto com no máximo 65535 Tamanho
caracteres. do texto +
2 bytes
Domínio dos Atributos no Firebird
O Firebird também nos oferece quase todos os dados
suportados pela padronização SQL. Veremos abaixo
alguns dos principais tipos suportados. Em geral,
alguns tipos são análogos aos suportados pelo MySQL.
Tipo Descrição Tamanho
Integer Número inteiro. Apresenta uma variação 4 bytes
que vai de -2147483648 a 2147483647. O
Firebird não oferece o recurso unsigned.
Float Número com vírgula de precisão simples. 4 bytes
Double Precision Número com vírgula de alta precisão. 8 bytes
Numeric(M,D) Número de M elementos e D casas M+2 bytes
decimais. M, por especificar o total de (se D > 0)
elementos, sempre será maior que D. ou
M+1 byte
(se D = 0)
Date Armazena datas obedecendo o formato, 4 bytes
entre aspas: mm/dd/aaaa.
Time Armazena hora no formato: ‘hh:mm:ss’. 4 bytes
TimeStamp Armazena hora e data. Deve ser inserido 4 bytes
com aspas e obedece ao seguinte
formato: mm/dd/aaaa hh:mm:ss
Char(n) Seqüência de n caracteres de tamanho n bytes
fixo. Se definirmos 30 caracteres, o
campo ocupará 30 bytes – em qualquer
situação. n varia de 0 a 32767.
VarChar(n) Armazena n caracteres, sendo o máximo n+1 bytes
32767. Seu tamanho varia de acordo com
os caracteres ocupados mais um, ou seja,
se temos VarChar(5) armazenando o
texto ab, estamos ocupando 3 bytes.
Para maiores esclarecimentos, consulte [Link]
Domínio dos Atributos no Oracle
O Oracle facilita a escolha do domínio do
atributo, pois trabalha com poucos tipos.
Contudo, isso não limita a variação de
armazenamento, pois cada um dos tipos
engloba várias possibilidades.
Tipo Descrição
Number(P,S) É capaz de armazenar números inteiros ou de ponto
flutuante (com casas decimais). P representa a
precisão, ou seja, o total de elementos que o número
conterá – somando as casas decimais. S é a escala e
representa a número de casas decimais.
Date Usado para armazenar datas. Obedece ao formato
dd/mm/aaaa e deve estar compreendido entre aspas.
TimeStamp É usado para armazenar data e hora. Seu formato
deve obedecer a seguinte sintaxe:
TIMESTAMP'aaaa-mm-dd hh:mm:ss'
Observe também o uso das aspas.
Char(n) Usado para armazenar caracteres de tamanho fixo.
Deve conter no máximo (n) 2000 elementos. Este
domínio ocupará sempre o valor estipulado em n,
independente do uso destes espaços.
Varchar2(n) Armazena n caracteres. Suporta no máximo 4000
letras. Esta seqüência de caracteres não possui
tamanho fixo, ou seja, mesmo definido varchar2
(1000), o campo ocupará somente o espaço utilizado.
Para maiores referências, consulte [Link]
Estes são os principais tipos adotados nos SGBD’s acima citados.
Veremos agora, os comandos básicos de criação/manutenção das
tabelas de uma base de dados.
2. Criação/Alteração/Exclusão de Tabelas
Com um banco de dados criado, o próximo passo é referente à
manutenção das tabelas. Em geral, todos os SGBD’s trabalham com os
mesmos comandos de criação/alteração/exclusão, variando apenas na
definição dos domínios dos atributos. O estudo aqui apresentado centra-
se na manutenção por meio de comandos SQL e não aborda a adoção
de ferramentas de interação facilitada (como a oferecida pelo Oracle
10g, por exemplo). Em primeiro lugar, veremos a criação de tabelas.
Criação de Tabelas: O processo de criação de tabelas segue, em
geral, a sintaxe apresentada abaixo.
create table nome_da_tabela (
nome_do_atributo1 tipo restricoes,
nome_do_atributo2 tipo restricoes,
...
constraints
);
O processo de criação envolve a nome da tabela e os atributos
(acompanhados ou não de restrições de integridade). Pode-se também
acrescentar a cláusula constraint. Para facilitar o entendimento, observe
o diagrama de estrutura de dados a seguir.
Por conveniência, mostraremos a criação das tabelas acima em apenas
um SGBD, neste caso, o MySQL. Para adaptar os comandos descritos,
deve-se apenas substituir os domínios do MySQL para tipos
equivalentes nos outros SGBD’s.
Criando a tabela clientes no MySQL:
1 create table clientes (
2 codigo integer not null,
3 nome varchar(60) not null,
4 CPF char(14) unique not null,
5 telefone char(14),
6 constraint pk_clientes primary key (codigo)
7 );
Observe que, em quase todos os casos, a cláusula not null está
presente – inclusive na chave primária. Na primeira linha temos o
comando de criação seguido do nome da tabela. Nas linhas 2, 3, 4 e 5
definimos os campos. Por fim, na linha 6, através da cláusula constraint
especificamos que codigo é uma chave primária. Todo comando create
table guardará seus atributos entre parênteses.
Criando a tabela dependentes no MySQL:
1 create table dependentes (
2 cod_cliente integer not null,
3 CPF char(14) not null,
4 nome varchar(60) not null,
5 constraint pk_dependentes
6 primary key (cod_cliente,CPF),
7 constraint fk_dependentes foreign key
(cod_cliente) references clientes(codigo)
);
8
Deve-se destacar a definição de uma chave primária composta e a
presença da chave estrangeira cod_cliente (associada ao campo codigo
da tabela clientes). Observe também que CPF, neste caso, não está
restringido pela cláusula unique, pois a chave primária já garante
existência exclusiva do campo.
O procedimento de alteração das tabelas, similarmente ao processo de
criação, varia apenas os tipos dos campos. Em geral, os três SGBD’s
estudados apresentam a mesma sintaxe.
Mudar o nome da tabela clientes para cli no MySQL:
alter table clientes rename to cli;
Mudar o nome do campo da tabela cli no MySQL:
alter table cli change nome n varchar(60) not null;
Neste caso, o campo nome foi renomeado para n. Observe que o tipo
de a restrição deve ser repetida. Abaixo, temos um exemplo de
modificação do tipo e restrição de um campo da tabela.
Mudar o tipo do campo n da tabela cli no MySQL:
alter table cli change n n char(40) unique not null;
Adicionar um campo no MySQL:
alter table cli add sexo char(1)
check (sexo = ‘M’ or sexo = ‘F’);
Excluir um campo no MySQL:
alter table cli drop column sexo;
Abaixo estamos adicionando uma nova restrição, contudo, deve-se
observar que cli já possui uma chave primária. Este procedimento iria
gerar um ERRO. Se, durante a criação da tabela clientes, a linha 7 fosse
ignorada, este comando seria aceito.
Adicionar restrição no MySQL:
alter table cli add constraint pk_cli
primary key (CPF);
Por não envolver os domínios dos atributos, o procedimento de exclusão
de tabelas é análogo em todos SGBD’s. Deve-se observar que a base
de dados não deixará ocorrer a exclusão da tabela cli antes que a tabela
dependentes seja excluída. Isto ocorre graças a existência da chave
estrangeira em dependentes referenciando cli.
Excluindo uma tabela no MySQL:
drop table dependentes;
Através dos comandos apresentados, podemos criar nossa base de
dados. Adiante, veremos os comandos de manipulação dos dados das
tabelas.