quinta-feira, fevereiro 01, 2007

Iniciando com MySQL

Comecei a desenvolver um projeto para uma aca-
demia onde pratico jiu-jitsu. Bom o "projeti-
nho" não é revolucionário, é só uma forma de
cadastro de alunos e controle de pagamento das
mensalidades.
A linguagem usada eu ainda vou decidir, prova-
velmente ficará entre ASP e JSP a disputa :)
mas a base de dados eu já decidi que ficará em
um SGBD MySQL e o sistema rodará sobre Windows.


Porque MySQL?

Não vejo motivos para não usá-lo na verdade.
O único problema que eu encontrei na versão que
estou usando (5.0.24) é o não suporte a CHECK
CONSTRANTS, de resto ele suporta tudo e é ex-
tremamente rápido, ainda mais para um sistema
com as características deste que será 90% uti-
lizado para consultas e inserções de dados.


Iniciando.

Bom eu venho da escola Oracle (e para mim não
existe SGBD que o bata) então tive que dar uma
pesquisada em como fazer algumas coisas e tal
e é isso que comprartilharei aqui no blog com
quem mais precisar.


Instalando.

Não vou entrar nesse ponto, é como instalar
qualquer coisa no Windows - NEXT, NEXT, NEXT -
o único ponto a ser visto é definir uma senha
segura para o usuário root.


Nosso ponto de partida.

O que precisamos depois de instalar o SGBD pa-
ra podermos começar? Uma base de dados!
Vamos criar uma base de dados então. O MySQL já
vem com uma base de dados de testes chamada
test, mas como o objetivo aqui é começar a fa-
zer tudo que fariamos se fossemos começar a
desenvolver nossos sistemas... lá vamos nós:

Lembra da senha do root? Então em um console
vá para a pasta de instalação do MySQL e entre
no diretório bin. Agora execute:

shell> mysql -u root -p
Enter password: senha123

Saída no console:
Welcome to the MySQL monitor. Commands end
with ; or \g.
Your MySQL connection id is 1 to server
version: 5.0.24a-community-nt

Type 'help;' or '\h' for help. Type '\c' to
clear the buffer.

Para criar uma base de dados:

mysql> CREATE DATABASE TESTE;

Saída no console: Query OK, 1 row affected (0.00 sec)


Alterando a base de dados que estamos usando.

Agora vamos usar a base de dados:

mysql> USE TESTE
Saída no console: Database changed


Criando uma tabela.

De nada adianta criarmos uma base se não tiver-
mos alguma(s) tabela(s) para brincarmos. Vamos
fazer um teste com chaves primárias, estrangei-
ras, procedimentos, selects com join, alterar
tabelas, criar gatilhos, etc... um exemplo um
pouco mais completo para um suposto sistema de
envio de mensagens.

1) Criar a tabela CONTATO:

mysql> CREATE TABLE CONTATO(
CODCONTATO INT NOT NULL,
NOMECONTATO VARCHAR(100) NOT NULL
) ENGINE = INNODB;

Saída no console: Query OK, 0 rows affected (0.02 sec)

INNODB é uma engine que suporta chaves e outras
funções de bancos integros.

2) Alterar a tabela adicionando uma chave pri-
mária e um índice a tabela:

mysql> ALTER TABLE CONTATO ADD PRIMARY KEY (CODCONTATO);

Saída no console: Query OK, 0 rows affected (0.44 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> ALTER TABLE CONTATO ADD INDEX (CODCONTATO);

Saída no console: Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0

Nossos contatos devem ter código seqüencial
calculado pelo sistema, nada melhor do que cri-
armos uma trigger neste ponto.

3) Criar o gatilho de inserção:

mysql> DELIMITER //

mysql> CREATE TRIGGER BIF_CONTATO BEFORE INSERT ON CONTATO
FOR EACH ROW

BEGIN

DECLARE novoCodigo INT;

SELECT IFNULL(MAX(CodContato), 0) + 1
INTO novoCodigo
FROM Contato;

SET NEW.CodContato = novoCodigo;

END;
//

Saída no console: Query OK, 0 rows affected (0.01 sec)

mysql> DELIMITER ;

A mudança de delimitador de linha serve para
que o MySQL não interprete o ';' nos comandos
que listamos dentro de um gatilho, procedimen-
to, etc...

4) Criar o gatilho de atualização:

Não queremos que uma pessoa consiga atualizar
o código do usuário pois esse é a nossa chave
primária sobre o registro, então podemos fazer
um gatilho que dispara a cada atualização na
tabela atribuindo ao registro sempre o seu an-
tigo código.

mysql> DELIMITER //

mysql> CREATE TRIGGER BUF_CONTATO BEFORE UPDATE ON CONTATO
FOR EACH ROW

BEGIN

SET NEW.CodContato = OLD.CodContato;

END;
//

Saída no console: Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;


Inserindo dados e testando a integridade da
base.

Vamos inserir alguns registros na tabela CONTATO:

mysql> INSERT INTO Contato(CODCONTATO, NOMECONTATO) VALUES(0, 'João');

Saída no console: Query OK, 1 row affected
(0.00 sec)

mysql> INSERT INTO Contato(CODCONTATO, NOMECONTATO) VALUES(0, 'Maria');

Saída no console: Query OK, 1 row affected (0.00 sec)

Vamos listar nossos contatos cadastrados:

mysql> SELECT CodContato, NomeContato
FROM Contato;

Saída no console:
+------------+-------------+
| CodContato | NomeContato |
+------------+-------------+
| 1 | João |
| 2 | Maria |
+------------+-------------+
2 rows in set (0.00 sec)

Se tentarmos atualizar o código de qualquer um
dos contatos o SGBD não dará mensagem de erro
mas sim não alterará o registro pois o nosso
gatilho de atualização não permite.

Bom agora sem mais rodeios vamos criar uma ta-
bela de recados:

mysql> CREATE TABLE RECADO(
CODCONTATO INT NOT NULL,
RECADO VARCHAR(500) NOT NULL,
CODREMETENTE INT NOT NULL
) ENGINE = INNODB;

Saída no console: Query OK, 0 rows affected (0.00 sec)

mysql> ALTER TABLE RECADO ADD INDEX (CODCONTATO);

Saída no console: Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> ALTER TABLE RECADO ADD FOREIGN KEY (CODCONTATO) REFERENCES CONTATO(CODCONTATO) ON DELETE CASCADE;

Saída no console: Query OK, 0 rows affected
(0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> ALTER TABLE RECADO ADD FOREIGN KEY (CODREMETENTE) REFERENCES CONTATO(CODCONTATO) ON DELETE CASCADE;

Saída no console: Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0

Notem que temos uma chave estrangeira de uma tabela para outra aqui, ou seja, um recado pertence a um cotato. Tente excluir um contato e todas as suas mensagens vão ser apagadas também.

E vamos inserir dois recados de teste:

mysql> INSERT INTO Recado(CodContato, Recado, CodRemetente) VALUES(2, 'Nao esquece do happy hour hoje!', 1);

Saída no console: Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO Recado(CodContato, Recado, CodRemetente) VALUES(1, 'Ok, irei sem falta.', 2);

Saída no console: Query OK, 1 row affected (0.02 sec)

Ok, agora selecionando os dados de maneira mais
eficaz para podermos ver o que foi mandado.
Nesta instrução relacionaremos a tabela contato
2 vezes para pegar o nome do contato de desti-
natário e remetente do recado:

mysql> SELECT co1.NomeContato Para, rec.Recado,
co2.NomeContato De
FROM Contato co2, Contato co1, Recado rec
WHERE rec.CodContato = co1.CodContato
AND rec.CodRemetente = co2.CodContato;

Saída no console:
+-------+-----------------------------+-------+
| Para | Recado | De |
+-------+-----------------------------+-------+
| Maria | Nao esquece do happy hour | Joao |
| | hoje! | |
| Joao | Ok, irei sem falta. | Maria |
+-------+-----------------------------+-------+
2 rows in set (0.00 sec)

Bom esse é um exemplo bem completo de uso do
MySQL. Agora me resta ir descobrindo o resto e
modelando o sistema.

Em breve: funções e procedimentos.

Leu, gostou, não gostou, quer elogiar ou criti-
car? Comente o post!

Um comentário:

rogerio machado disse...

esse post sobre triggers e FK's que encontrei até agora foi o de mais simples compreensão - Parabéns