banco de dados ii

56
SERVIÇO NACIONAL DE APRENDIZAGEM COMERCIAL CURSO TÉCNICO EM INFORMÁTICA BANCO DE DADOS II

Upload: nelma-regina-dos-santos-teixeira

Post on 11-Feb-2016

22 views

Category:

Documents


2 download

DESCRIPTION

apostila de banco de dados II

TRANSCRIPT

Page 1: Banco de Dados II

SERVIÇO NACIONAL DE APRENDIZAGEM COMERCIAL

CURSO TÉCNICO EM INFORMÁTICA

BANCO DE DADOS II

Page 2: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

CURSO TÉCNICO EM INFORMÁTICA

BANCO DE DADOS II

Profissional responsável pela elaboração do conteúdo:

Prof° Edimar Gusmão Martins

Page 3: Banco de Dados II

SUMÁRIO

1. INTRODUÇÃO .............................................................................................................. 6

2. SQL Procedural ............................................................................................................. 8

2.1. Store Procedures .................................................................................................... 8

2.1.1. Criação, edição e exclusão de Procedures: ..................................................... 9

2.1.2. Procedimentos Condicionais .......................................................................... 13

2.1.3. Parâmetros de Entrada e Saída ..................................................................... 17

2.2. Funções ................................................................................................................ 19

2.2.1. Funções escalares ......................................................................................... 20

2.3. Gatilhos (triggers) ................................................................................................. 23

2.3.1. Operadores NEW e OLD ............................................................................... 26

2.4. Boas Práticas ....................................................................................................... 29

3. Transações ................................................................................................................. 30

3.1. BEGIN ou START TRANSACTION ...................................................................... 31

3.2. COMMIT ............................................................................................................... 32

3.3. ROLLBACK .......................................................................................................... 32

3.4. Na prática ............................................................................................................. 32

3.5. Deadlocks ............................................................................................................. 35

4. Definição e utilização de Visões. ................................................................................. 36

4.1. Criação, Edição, exclusão e Alteração ................................................................. 37

4.2. Manipulação de dados em Visões ........................................................................ 39

5. Estrutura dos dados .................................................................................................... 40

5.1. Introdução............................................................................................................. 40

Page 4: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

5.2. Mecanismos de Armazenamento (Storage engines) ............................................ 40

5.2.1. Arquitetura do MySQL com Storage Engines ................................................ 43

6. Segurança. .................................................................................................................. 45

6.1. Tipos de Segurança ............................................................................................. 45

6.2. Configurando os Privilégios Iniciais do MySQL .................................................... 46

6.2.1. Verificando a senha de root ........................................................................... 47

6.2.2. Configurando senhas ..................................................................................... 47

6.2.3. Configurando Privilégios (GRANT e REVOKE) ............................................. 49

6.2.4. Tipos de privilégios ........................................................................................ 51

6.2.5. Privilégio de dar privilégios (WITH GRANT OPTION) .................................... 54

Page 5: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

1. INTRODUÇÃO

Para ficar mais claro o conteúdo que abordaremos neste e nos próximos

capítulos vamos fazer uma descrição de alguns conceitos: programa, rotina,

sub-rotina, procedimento e gatilho. As seguintes descrições estão de acordo

com a Wikipédia – Enciclopédia livre:

Programa - (programa de computador) é a sequência completa de instruções a

serem executadas por computador, tanto em código-fonte (escrita em

linguagem simbólica) como em código executável (já convertido em linguagem

de máquina). No caso do MySQL, é um programa aplicativo, destinado a

auxiliar o usuário na realização de determinadas tarefas ou atividades

pessoais.

Rotina - é um conjunto de instruções relativas a um cálculo ou função num

programa. Os termos rotina, sub-rotina, procedimento, função e macro são

equivalentes, diferindo mais quanto a contexto, técnicas e formas de uso.

Sub-rotina - é a parte de uma rotina que realiza uma tarefa específica num

programa de computador.

Procedimento - (em relação a um stored procedure) é similar à descrição de

sub-rotina, mas a partir da linguagem SQL é uma coleção de comandos

armazenados que serão utilizador para gerenciar um banco de dados toda vez

que uma determinada tarefa necessite ser realizada.

Função - (reflete um stored function) é similar à descrição de sub-rotina e por

conseguinte à descrição de procedimento.

Gatilho - é similar à descrição de procedimento, sendo um recurso associado a

um banco de dados, que é executado automaticamente quando uma condição

preestabelecida é satisfeita. É utilizado para associar um procedimento

armazenado a um evento de banco de dados.

Page 6: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Tanto uma sub-rotina do tipo stored procedure como uma sub-rotina do

tipo trigger ou uma sub-rotina do tipo function são códigos de programa

executados dentro do programa de gerenciamento de banco de dados

baseados numa linguagem estruturada de script. Uma linguagem estruturada é

tipicamente baseada em três formas clássicas de operação, denominadas:

sequência, decisão e laços de repetição.

A Linguagem estruturada procedimental usada pelo MySQL pode ser

conhecida pela Sigla PL (Procedural Language), a qual possui scripts de

procedimentos compatíveis com a sintaxe SQL:2003 para uso e definição

de stored procedures. O formato adotado para o programa MySQL é

semelhante ao do gerenciador de banco de dados DB2 da IBM. Futuramente

pode se tornar compatível com os padrões PL/SQL da Oracle, Transact-SQL

(conhecida também por T-SQL) da Microsoft e Sybase.

A Linguagem PL/SQL da Oracle (a primeira linguagem de script criada para

auxiliar o gerenciamento do banco de dados) tem sua estrutura muito

semelhante à linguagem ADA, que foi desenvolvida a partir da linguagem

PASCAL, a mesma usada no ambiente Borland Delphi e que muitos

profissionais erroneamente afirmam não ser mais usada. Apesar da influência

das linguagens ADA e PASCAL, a PL/SQL tem estrutura própria e particular.

Infelizmente no mercado de banco de dados, apesar do esforço da entidade

ISO em procurar estabelecer um padrão de trabalho único para a linguagem

SQL, fornecedores apresentam recursos particulares que fogem do padrão

proposto, tornando sua ferramenta muitas vezes incompatível com as outras

que utilizam a mesma linguagem. Neste caso, existe uma só linguagem SQL e

uma série de dialetos incompatíveis entre si que são usados no mercado. O

mesmo ocorre com as muitas PLs existentes. A linguagem PL do MySQL,

como o próprio programa MySQL, possui algumas características particulares,

diferenciando-a dos outros fornecedores.

Page 7: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

2. SQL Procedural

A maioria dos SGBDs já possuíam muitos recursos avançados tais como os

procedimentos armazenados (store procedures) e gatilhos (triggers), porém no

MySQL estes recursos são bem recentes, adicionados a partir das versões 5.x.

Estas funcionalidades permitem fazer uso de uma série de técnicas e práticas

de programação, subrotinas e funções, obtendo desta forma resultados rápidos

para problemas complexos e demorados, como tarefas repetitivas e de dificil

implementação.

Quando falamos de SQL procedural estamos falando de procedimentos

armazenados (store procedures), funções armazenadas (store functions ou

simplesmente functions) e gatilhos (triggers). Trataremos nesta apostila pelos

nomes convecionais store procedures, functions e triggers.

Muitos destes conceitos foram abordados na introdução, assim iremos detalhar

eles bem como ver sua sintaxe e principais características, regras e melhores

práticas.

2.1. Store Procedures

As Store procedures, são subrotinas, lógicas complexas composta de uma

séries de comandos em linguagem SQL, que realizam determinada tarefa.

Podem receber parâmetros e retornar diferentes tipos de resultados.

No dia a dia surgem problemas relacionados à necessidade de se realizar

operações complexas que envolvem a realização de um ou mais comandos de

consulta a tabelas em conjunto com comandos de inclusão e/ou alteração de

dados. Em outros casos, deseja-se realizar operações com base em

parâmetros definidos pelo usuário.

Page 8: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Nessas situações, o ideal é que essas operações não sejam definidas na

aplicação que vai fazer uso do banco de dados, mas no próprio servidor do

banco de dados. Isso garante a segurança do banco de dados, uma vez que o

mesmo pode controlar o acesso a essas operações especiais, evitando o

conhecimento excessivo da estrutura do banco de dados pelos

desenvolvedores de aplicações.

Desse modo, as Stored Procedures, traduzidas do inglês como procedimentos

armazenados, são definidos como um conjunto de comandos da linguagem

SQL definidos no servidor do banco de dados e acionados por eventuais

chamadas de qualquer usuário que tenha autorização para sua execução.

Além da questão de segurança do banco de dados, já que o usuário só poderá

executar os procedimentos a que tiver acesso, os procedimentos armazenados

ajudam a diminuir o tráfego de informações entre o usuário e o servidor,

tornando mais simples o processamento das informações.

Por exemplo, suponha que diversos usuários desejem fazer uma determinada

consulta. A execução desse conjunto de comandos por diversos usuários

simultaneamente vai gerar um grande tráfego de informações pela rede, o que

não ocorre se esse conjunto de comandos for definido usando um

procedimento armazenado no próprio servidor do banco de dados e o usuário

solicite apenas sua execução e o retorno do resultado.

Desta forma o usuário solicita ao servidor que execute a operação e lhe

devolva o resultado, não se preocupando com a estrutura do banco de dados.

Em outros SGBDs o comando utilizado pode ser diferente, como por o exemplo

no SQL Server, cujo comando é exec ao invés de call.

É possível também na criação dos procedimentos utilizar comandos comuns às

linguagens de programação, que você já viu em disciplinas anteriores, como IF,

WHILE, RETURN etc. Outra observação que deve ser feita é que visões não

podem ser criadas em procedimentos armazenados.

2.1.1. Criação, edição e exclusão de Procedures:

Page 9: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

A sintaxe básica para criação, alteração e exclusão de stores procedures são

simples, porém sua aplicação e sua lógica podem ser bem complexas e até

perigosas se mal empregadas.

CREATE PROCEDURE

Para criar uma store procedure basta utilizar a palavra reservada CREATE,

seguida da palavra PROCEDURE, os parâmetros se se necessário e as

palavras BEGIN e END. Toda a lógica do procedimento fica entre as palavras

BEGIN e END.

O nome_do_procedimento é o nome que se deseja atribuir para o

procedimento, que deve seguir as mesmas regras usadas para os nomes das

tabelas. Em seguida, caso haja, a lista de parâmetros de entrada e/ou saída.

Mesmo quando não houver parâmetros, devem ser inseridos os parênteses ().

Finalmente, entre as palavras BEGIN e END, devem ser descritos os

comandos SQL que definem a operação a ser executada.

Os parâmetros seguem a notação [IN | OUT] nome_parâmetro

tipo_de_dado, ou seja, deve-se usar a palavra chave que identifica se o

parâmetro é de entrada (IN) ou saída (OUT), se nada for informado, é

atribuido como padrão o de entrada.

Abaixo temos um exemplo de procedure que retorna os nomes de todos os

filmes que foram alugados e a quantidade alugada.

Page 10: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Visto que esse tipo de pesquisa tende a ser realizado diariamente num banco

de dados, como o nosso banco de exemplo sakila, seria útil definir uma

procedure para executar essa operação.

Detalhando um pouco melhor nosso exemplo vemos que ele também faz

alguns joins com três tabelas, o que para um usuário, ou mesmo aplicação

cliente, poderia ser oneroso e custoso. Já ao contrário, estes comandos

estando no servidor sob a forma de um procedimento, simplificam sua

execução tanto para seu uso quanto para as questões de performance.

Para utilizar o procedimento bastaria chama-lo da seguinte forma:

ALTER PROCEDURE

No MySQL, diferente de outros SGBDs, o comando ALTER PROCEDURE

não permite que sejam alterados os parâmetros ou o corpo do procedimento.

Para isto é necessário excluir e recriar o procedimento através dos comandos

DROP e CREATE.

O ALTER PROCEDURE permite que sejam alterados apenas as seguintes

características:

Comentários;

Linguagem

Definições de SQL e definições de segurança.

Page 11: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

DROP e CREATE

Já vimos o comando create e logo como criar um procedimento. O comando

para excluir um procedimento é DROP, o mesmo utilizado para excluir uma

table, uma view e outros objetos do banco de dados.

A sintaxe para excluir uma procedure é seguinte:

Na prática podemos usar apenas:

Onde “sp_filmes_alugados” é o nome do procedimento que desejamos excluir,

no exemplo acima estamos excluindo a procedure que criamos antes. Observa-

se que a sintaxe (extraída diretamente da documentação do MySQL) é a

mesma usada para excluir uma function, que veremos no próximo capitulo.

E que também é possível usar a opção IF EXISTS.

Em muitas situações é comum usarmos em conjuntos os comandos drop e

create para alterar parâmetros ou o escopo SQL do procedimento, o que

não é permitido pelo comando alter. Nestes casos utilizamos uma

combinação destes comandos junto com a opção IF EXISTS. Abaixo

temos um exemplo:

Page 12: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Observe que primeiro excluímos a procedure (linha 3), mas somente se ela

existir o que é garantido pela opção “IF EXISTS“, caso contrário nada

acontece. Já na linha 5 criamos novamente a procedure, adicionando um

parâmetro de entrada (IN) chamado filme do tipo varchar que é usado na

cláusula where.

Para chamar o procedimento utilizamos a mesma sintaxe vista antes, porém

passando o parâmetro “filme”. O comando fica:

Neste exemplo passamos como parâmetro o título “AFRICAN EGG”, o qual

retorna apenas uma linha no resultado.

2.1.2. Procedimentos Condicionais

É muito comum situações onde um procedimento armazenado irá realizar uma

tarefa condicionada, ou seja irá ou não realizar determinados comandos de

acordo com uma situação, uma regra de negócio, um parâmetro passado,

Page 13: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

enfim, algo que sinalize para o procedimento que deve agir de maneira “A” e

não “B”.

Isto é muito comum em linguagens de programação, os famosos IFs ou

simplesmente condicionais. Os mesmos conceitos podem ser aplicados em

SQL, especialmente dentro de um procedimento.

Para visualizar melhor o problema e logo a sintaxe, pegaremos o procedimento

criado antes, “sp_filmes_alugados” o qual recebe como parâmetro o título do

filme para ser usado na cláusula where. a rotina funciona perfeitamente,

porém caso o usuário queira pesquisar pelo título não exato, mas sim

aproximado, por exemplo apenas digitar “african” e retornar a lista de todos

filmes alugados que tenham a palavra “african” em qualquer parte do seu título,

será possível?

Sabemos que em uma query normal poderíamos usar o operador like, logo

podemos recriar a rotina apenas usando o like ao invés do operador “=”

correto? Vejamos o exemplo abaixo como ficaria:

A store procedure fica praticamente igual a anterior, apenas com o operador

like ao invés do “=” e o parâmetro “filme” concatenado com o caractere

curinga de pesquisa “%”. Para testá-la use o mesmo comando usado antes, o

comando e o resultado são mostrados abaixo:

Page 14: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Observe que agora são listados três filmes, todos que possuem a palavra

“african” em seu título.

Nossa rotina está quase pronta, mas ainda queremos mais; Queremos que o

procedimento possa fazer uma busca exata, como no primeiro exemplo, ou

uma busca usando o like como nesta última. E isto ainda deverá ser

decidido por um segundo parâmetro que determinará qual tipo de busca deve

ser feita.

Para facilitar a compreensão da rotina, vamos supor o seguinte cenário:

Uma aplicação cliente que tem uma tela de relatórios, que lista exatamente o

resultado do nosso procedimento, o título dos filmes alugados e suas

quantidades. Na parte superior da tela existe um campo de texto onde o

usuário insere o nome do filme que deseja listar (um campo de busca) porém

ao seu lado existe uma opção de marcar para fazer a busca exata, um

checkbox. Esta aplicação deverá passar para o SGBD apenas o parâmetro do

título que se deseja listar e um outro parâmetro do tipo booleano (verdadeiro ou

falso) o qual provem do checkbox e informa se a pesquisa deve ser exata ou

não: se verdadeiro sim, caso contrário não.

Agora que visualizamos uma situação real, podemos recriar nossa procedure

para que ela atenda o escopo acima.

Primeiro vejamos como ficariam os parâmetros:

Page 15: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Adicionamos o novo parâmetro de entrada chamado “buscaExata” do tipo bool.

Nosso próximo passo é usar o novo valor em um teste condicional, algo como:

Está quase, pronto falta apenas adicionar os respectivos blocos de código

procedural para a busca exata e a busca não exata, que correspondem aos

diferentes scripts que criamos nos dois exemplos anteriores desta procedure.

Inserindo os devidos comandos nos lugares adequados temos o seguinte script

final:

Detalhando nosso script temos:

I. Primeiro excluímos a procedure caso ela exista (IF EXISTS..) (linha

1);

II. Logo em seguida criamos novamente nossa rotina com o novo

parâmetro (linha 2);

III. Em terceiro lugar temos nossa condição de teste e sua estrutura If -

Else – End If (linhas 4, 13 e 22).

Page 16: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

E finalmente entre a estrutura IF .. Then e Else temos nossas duas lógicas,

uma para listar os filmes pelo título exato passado no parâmetro e outra para

filtrar os filmes que contenham o texto informado em qualquer parte do título.

Para testarmos nossa procedure utilize os comandos abaixo e veja os

diferentes resultados:

2.1.3. Parâmetros de Entrada e Saída

Como visto antes os procedimentos permitem que sejam especificados

parâmetros de entrada e saída, e na verdade, ainda temos um terceiro tipo de

parâmetro que é ao mesmo tempo de entrada e saída, INOUT. Podemos

definir nenhum, um ou mais parâmetros tanto de diferentes tipos. Quando

temos mais de um parâmetro devemos passa-los na mesma ordem que são

definidos quando usamos o comando call para executar a rotina.

Exemplo de store procedure (sp) com parâmetros:

Chamada da sp acima:

Vamos rever e detalhar um pouco melhor a definição de cada um dos tipos de

parâmetros:

IN: É o modo padrão, quando definido na criação do procedimento o

comando que faz a chamada à procedure é obrigado a passar um argumento

Page 17: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

do mesmo tipo como parâmetro. O valor de um argumento de entrada é

protegido, isto significa que mesmo que o valor passado seja alterado fora do

procedimento, o seu valor original é mantido dentro do procedimento, ou seja

na prática é como se a store procedure executasse sobre uma cópia do

parâmetro.

OUT: Argumentos de saída podem ter seus valores alterados dentro do

procedimento e seu novo valor é passado de volta para o escopo que fez a

chamada.

INOUT: É a combinação dos parâmetros IN e OUT. Isto significa que o

programa de chamada pode passar o argumento, o procedimento pode alterar

seu valor durante sua execução e finalmente passar o novo valor de volta para

o programa de chamada.

Para compreender melhor estes parâmetros, especialmente o do tipo INOUT

vejamos o seguinte exemplo:

O procedimento tem dois parâmetros, um exclusivo de entrada (inc) e outro do

tipo INOUT. O procedimento é bem simples, ele incrementa o valor passado

no argumento count pelo valor passado em inc.

Page 18: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Para compreender exatamente o funcionamento deste tipo de parâmetro

observe os resultados das chamadas consecutivas ao procedimento nas linhas

seguintes. O valor da variável @counter que é passado ao procedimento é

alterando dentro da procedure e, mesmo após a conclusão da execução do

procedimento, o programa que fez a chamada ao procedimento, neste caso o

cliente de SQL, tem acesso ao valor alterado na variável @counter.

Em outras palavras é como se o argumento do tipo INOUT fosse uma variável

global, que pode ser alterada de dentro do procedimento e acessada “de fora”,

no escopo onde a chamada é feita.

Desafio

1) Pegando o exemplo desta última procedure criada tente criar um

procedimento que:

Possua mais uma diferente lógica, ou seja, forma de executar, que retorne a

mesma listagem de filmes e suas quantidades, porém sem nenhum filtro sobre

os títulos dos filmes. Para isto você pode usar mais ou menos parâmetros e

provavelmente mais uma condição na estrutura de execução.

2.2. Funções

Assim como nos procedimentos, é possível ter uma sequência de comandos

SQL encapsulados em estruturas denominadas funções. Que, como dito antes,

tratam de lógica e programação.

A principal diferença entre uma função e um procedimento está no fato que a

função obrigatoriamente deve retornar um valor. No módulo de banco de dados

anterior, já trabalhamos em com funções internas, pré-definidas pelo próprio

SGBD, como AVG(), SUM(), COUNT() etc. Mas, o usuário pode definir suas

próprias funções, com parâmetros de entrada e variáveis locais. É possível no

SQL construir dois tipos de funções.

Page 19: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Funções escalares: estruturas semelhantes a funções internas, que retornam

um único valor.

Funções com valor de tabela: estruturas semelhantes a visões com a diferença

de aceitarem parâmetros de entrada, que retornam uma tabela como resultado

do seu processamento.

No caso do MySQL, não é permitido que uma função retorne uma tabela.

Desse modo, vamos discutir apenas como criar e utilizar as funções escalares.

2.2.1. Funções escalares

Uma função escalar retorna um único valor de dados de um tipo pré-definido e

pode ser utilizada do mesmo modo que uma função interna, sendo mais usada

como:

uma expressão na lista de um comando SELECT;

uma expressão em uma cláusula WHERE ou HAVING;

uma expressão em uma cláusula ORDER BY ou GROUP BY;

uma expressão na cláusula SET de um comando UPDATE;

uma expressão na cláusula VALUES de um comando INSERT.

A instrução para criar uma função é simples, basta utilizar o comando CREATE

FUNCTION em conjunto com a lista de parâmetros (caso necessário) a serem

usados. A sintaxe de criação de uma função é descrita no quadro abaixo.

Detalhando a expressão temos:

nome_da_funcao: É o nome que se deseja atribuir para a função. Esse nome

deve seguir as mesmas regras usadas para os nomes das tabelas.

Page 20: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

parametros_de_entrada: Aqui é inserida a lista de parâmetros ou argumentos

de entrada, caso houver, que seguem o mesmo formato definido no capítulo

anterior sobre procedimentos armazenados. Mesmo não havendo parâmetros,

devem ser inseridos os parênteses () na criação da função.

tipo_de_retorno: A cláusula RETURNS define o tipo de dado que será

retornado pela função, por exemplo, um número inteiro, um conjunto de

caracteres etc.

características: Quando você cria uma função armazenada, você deve

declarar e algumas características. Caso contrário a recuperação de dados ou

replicação pode causar comportamentos inesperados. Isto será visto no

capítulo “Processamento e Tunning” Abaixo veremos suscintamente o que

cada uma das características define:

DETERMINISTIC ou NOT DETERMINISTIC

Define se uma rotina como determinista se produz sempre o

mesmo resultado para os mesmos parâmetros de entrada; e

não determinista caso contrário.

É uma boa prática, e em alguns casos até necessário, que se declare uma das

opções acima.

E finalmente, entre as palavras BEGIN e END devem ser descritos os

comandos SQL que definem a operação a ser executada. Lembrando que

antes do END deve ser usada a cláusula RETURN que define a variável ou

expressão que irá retornar o resultado da função.

É comum usarmos variáveis para o retorno de funções. Logo vamos rever a

sintaxe para declarar variáveis locais no MySQL. Isso é feito usando o

comando DECLARE, cuja sintaxe é apresentada no quadro a seguir.

Page 21: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Nessa expressão, no campo nome_da_variavel deve-se inserir o nome da

variável que está sendo criada e esse nome deve seguir as mesmas regras

usadas para os nomes das tabelas. O mesmo acontece para a definição do tipo

de dado que será atribuído à variável.

Para começar, vamos criar uma função que retorne a quantidade total de filmes

alugado no banco de dados sakila. O comando para criar essa função é

descrito no destaque abaixo.

Observe que foi criada uma função denominada fn_qtdAlugadosl, sem qualquer

parâmetro, que retorna um valor do tipo inteiro. Os comandos que definem sua

operação encontram-se entre as palavras chave BEGIN e END.

Analisando melhor os comandos, vemos o uso do comando DECLARE para

definir uma variável intitulada qtde_vendas do tipo inteiro. Em seguida é feita

uma consulta (SELECT) da quantidade total de filmes na tabela rental. Esse

valor é armazenado na variável total usando a cláusula INTO. Finalmente, a

cláusula RETURN define que a função retorna o valor contido na variável total.

Após termos criado a função podemos usá-la consultas, atribuição de variáveis

ou mesmo dentro de outros procedimentos. Em nosso exemplo usaremos um

select simples:

Page 22: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

A partir dessa função, vamos recriá-la de forma que retorne a quantidade de

um único filme alugado, o código (id) do filme na tabela rental é o campo

inventory_id. O comando para criar essa função é descrito no quadro abaixo.

Compare a diferença entre as duas versões da função. Acrescentamos um

parâmetro de entrada do tipo inteiro, o qual é usado em uma cláusula where

sobre o campo inventory_id.

Nota-se que para “alterar” a função usamos a mesma técnica utilizada nas

store procedures, excluir a função antes com o “DROP .. IF EXISTS

....” e depois criamos novamente a função.

Para utilizar a função vamos usar o mesmo exemplo de consulta usado antes:

2.3. Gatilhos (triggers)

Começaremos usando uma definição bem sucinta e direta sobre o que são

triggers:

“Um trigger é um tipo especial de procedimento armazenado, que é executado

sempre que há uma tentativa de modificar os dados de uma tabela que é

protegida por ele.”

Mais algumas características gerais:

Page 23: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Associadas a uma tabela:

Os triggers são sempre associados a uma tabela e a um evento DML desta.

Chamados automaticamente:

Quando há uma tentativa de inserir, atualizar ou excluir os dados em uma

tabela, e um TRIGGER tiver sido definido na tabela para essa ação específica,

ele será executado automaticamente, não podendo nunca ser ignorado.

Não podem ser chamados diretamente:

Ao contrário dos procedimentos armazenados do sistema, os disparadores não

podem ser chamados diretamente e não passam nem aceitam parâmetros.

São parte de uma transação:

O TRIGGER e a instrução que o aciona são tratados como uma única

transação, que poderá ser revertida em qualquer ponto do procedimento, caso

você queria usar “ROLLBACK”, conceitos que serão vistos no próximo capítulo.

Os gatilhos ou triggers são um tipo especial de procedimentos, os quais

possibilitam um controle sobre os dados e sua integridade de uma maneira

bem particular.

Uma trigger é um procedimento associado a uma tabela, o qual é definido para

ser executado em resposta a um evento em particular. Estes eventos são os

comandos da DML (Data Manipulation Languange), sendo eles: INSERT,

REPLACE, DELETE ou UPDATE. Cada tabela pode ter vários gatilhos,

porém para cada comando DML em uma determinada tabela, pode se definir

apenas uma trigger, que deve ser disparado antes ou depois do evento.

Quando definimos uma trigger precisamos definir se ela será disparada antes

(BEFORE) ou depois (AFTER).

Aplicação:

Page 24: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Abaixo citamos alguns exemplos de situações onde as triggers são

especialmente úteis:

Atualizar dados em várias tabelas quando uma é atualizada. Ex: tabela

venda e demais tabelas relacionadas ao estoque do produto.

Validar uma determinada entrada (inserção de dados). Ex: validar dados

de pagamento ao registrar uma nova venda.

Atualizar um dado ou campo específico. Ex: Recalcular o preço de

venda de um produto quando seu desconto ou acréscimo for atualizado.

Existem inúmeras outras situações onde os triggers são especialmente úteis.

Porém elas também são perigosas quando mal usadas ou usadas

indiscriminadamente.

Sintaxe:

DEFINER: Quando o TRIGGER for disparado, caso esta opção tenha sido

utilizada, será usada para checar com quais privilégios será disparado. Utilizará

os privilégios do usuário informado em user ou os privilégios do usuário atual

(CURRENT_USER). Caso essa sentença seja omitida da criação do

TRIGGER, o valor padrão desta opção é CURRENT_USER;

trigger_name: É o nome do procedimento, por exemplo, trg_test;

trigger_time: Define se o TRIGGER será ativado antes (BEFORE) ou

depois (AFTER) do comando que o disparou;

trigger_event: Associa a trigger ao evento, INSERT, REPLACE,

DELETE ou UPDATE;

tbl_name: Nome da tabela onde o TRIGGER ficará “pendurado”

aguardando o trigger_event;

Page 25: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

trigger_stmt: Consiste na lógica que a TRIGGER deverá fazer quando

for disparado, ou seja os comandos que serão executados quando o evento

(trigger_event) ocorrer na tabela tbl_name.

2.3.1. Operadores NEW e OLD

Conforme descrito antes, uma trigger consiste em comandos que são

executados antes ou depois de um evento de DML em uma determinada

tabela.

Obviamente ao definir um procedimento automático que será disparado antes

ou depois de um evento DML em uma tabela, desejamos poder acessar a

informação que está sendo: atualizada, inserida e/ou deletada. Para isto dentro

de um trigger usamos os operadores especiais OLD e NEW.

Através destes operadores é possível acessar as colunas alvos do comando

DML, ou seja, podemos recuperar e usar os valores alterados. Para entender

melhor vejamos o seguinte contexto:

Para entender estes operadores vamos criar uma trigger simples sobre a tabela

category do banco de dados sakila.

Mas antes vamos criar uma tabela chamada testeTG para armazenar os

valores e entende-los melhor:

Esta tabela possui apenas três campos: OldValue; NewValue e EnventDML

que armazenarão o valor antigo da coluna, o novo valor e ao evento DML

respectivamente.

Page 26: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Agora vamos criar nossa primeira trigger:

Como podemos observar a trigger tg_categorys é definida sobre a

tabela category e disparada antes (BEFORE) do evento UPDATE. E o que

ela faz é inserir os valores old.name, new.name e “UPDATE” na tabela

que criamos.

Para testá-la vamos realizar um update na tabela, mas antes vejamos o

conteúdo da tabela (para nosso exemplo apenas os cinco primeiros registros já

são o suficiente):

Certo vamos agora atualizar o a coluna name da categoria id 1

(categopry_id = 1). Para isto execute o comando abaixo:

Certo, o comando deve ter executado sem problemas, para ter certeza do

resultado pode-se executar novamente a consulta com o select “LIMIT 5”.

Page 27: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Mas para entender o que nossa trigger fez realmente vamos visualizar os

dados da tabela testeTG:

Como podemos observar as colunas OldValue e NewValue possuem o valor

antigo e novo da coluna name. Para entendermos melhor vamos criar mais

algumas triggers nesta tabela e executar outros comandos:

Detalhando as triggers que criamos temos dois novos gatilhos, um para

UPDATE e outro para a operação DELETE. Ambos fazem exatamente a

mesma coisa: inserem os valores na nossa tabela testeTG, com a diferença

que a primeira insere um valor NULL ao invés da informação old.name

enquanto a segunda insere um valor NULL onde seria o a informação

new.name. Isto é feito desta forma para evitar um erro na criação da trigger, o

que ocorreria se tentasse executar com no mesmo formato da primeira.

Este erro é característico dos operadores OLD e NEW, uma vez que na

operação INSERT não existe a informação “OLD”, da mesma forma que para

uma operação DELETE não existe a informação “NEW”. Este comportamento

pode ser ilustrado nos resultados da nossa tabela testeTG:

Page 28: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Assim podemos constatar exatamente as quais informações temos disponíveis

com os operadores OLD e New.

Importante: A disponibilidade e os valores dos operadores OLD e NEW são os

mesmos tanto para triggers do tipo AFTER quando do tipo BEFORE.

2.4. Boas Práticas

Geralmente as empresas e desenvolvedores adotam padrões na hora de criar

seus scripts ou programas. Estes padrões os chamados Code Conventions

ou Coding Standards são uma boa prática em muitos sentidos. As rotinas

SQL, funções e demais objetos de banco de dados não são diferentes.

É Comum utilizarmos nomes ou prefixos padrões para determinados tipos de

objetos. Em nossos exemplos criamos procedimentos com o prefixo “sp_” nos

nomes, “sp” de Store Procedure. Bem como utilizamos “fn“ como prefixox para

o nome das functions.

Isto além de padronizar os scritps, facilita sua compreensão por outros

desenvolvedores.

Não existem regras específicas para prefixos e/ou determinados tipos de

objetos, apenas boas práticas. Os que usamos nesta apostila são apenas

exemplos de prefixos que geralmente são utilizados, mas cada empresa,

Page 29: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

organização ou mesmo grupos de desenvolvedores pode adotar seu próprio

padrão.

3. Transações

Em qualquer aplicação que esteja integrada com um banco de dados,

provavelmente haverá a necessidade de definir operações sobre o banco de

dados que envolvam mais de um comando; em outras palavras, uma

combinação de inserções, alterações e/ou exclusões que representam uma

única ação do usuário.

A linguagem SQL define o conceito de transação (transaction) para esse tipo

de ação. Uma transação é uma sequência de comandos que devem respeitar

uma série de propriedades, de forma a garantir segurança e integridade para a

base de dados. Isso é necessário porque, no caso de algum ou alguns desses

comandos não ser executado (devido a uma violação de restrição, ou a uma

falha no sistema, travamento no servidor, etc.), o banco de dados

provavelmente ficará em um estado inconsistente.

Por exemplo, suponha um evento onde uma pessoa inscreveu-se em uma

oficina, que exige o pagamento de uma taxa de inscrição. Antes do início da

oficina, porém, a pessoa cancelou sua inscrição, o que lhe dá o direito de

receber o valor da taxa de volta. Para efetivar o cancelamento, o sistema

precisa realizar no mínimo dois comandos na base de dados: A: Cancelar a

inscrição, e B: Cancelar o pagamento da taxa. O sistema especifica que a

execução de A necessariamente implica na execução de B, e vice versa. Se

apenas A ou apenas B for executado, os dados estarão inconsistentes, pois o

dinheiro recebido não é compatível com o número de inscritos efetivados. A

única forma realmente segura de impedir esse tipo de inconsistência é

colocando A e B dentro de uma mesma transação.

Page 30: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Em um SGBD, uma transação deve obedecer ao padrão ACID, uma

abreviação em inglês para quatro propriedades:

Atomicidade (atomicity): faz com que a transação inteira seja

executada como um único comando. Da mesma forma que um comando

não deve ser executado apenas parcialmente, uma transação deve

obrigatoriamente ser executada por inteiro;

Consistência (consistency): garante que a transação trará o banco de

dados para um estado consistente, isto é, onde todas as restrições são

respeitadas. Em outras palavras, a transação não pode abrir um “rombo”

no banco;

Isolamento (isolation): garante que transações diferentes não

interfiram umas nas outras. Isto é, não haverá problemas de

concorrência se duas transações forem iniciadas ao mesmo tempo;

Durabilidade (durability): significa que as alterações efetivadas por

uma transação serão todas persistidas no banco de dados; mesmo que

ocorra uma falha no banco de dados, as alterações permanecerão.

Quem dá a garantia de que essas propriedades serão respeitadas é o próprio

SGBD. O desenvolvedor apenas deve utilizar os comandos adequados para

iniciar e finalizar uma transação:

A seguir é mostrado os três principais comandos relacionados a transações e

suas características.

3.1. BEGIN ou START TRANSACTION

O início de uma transação é sinalizado com o comando BEGIN. Isso significa

que, para a conexão atual, os comandos seguintes fazem parte de uma

transação. Em alguns SGBDs, as transações podem ser nomeadas.

Page 31: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Qualquer comando Insert, Update ou Delete realizado em seguida será

efetivado, e essas alterações serão refletidas nos Selects executados dentro da

transação. Porém as mudanças feitas não serão efetivamente persistidas na

base de dados enquanto a transação não for terminada. Por exemplo, se o

servidor do banco de dados cair no meio de uma transação, todos os

comandos executados serão imediatamente desfeitos assim que o banco de

dados voltar. Isso respeita a atomicidade da transação.

3.2. COMMIT

Para finalizarmos uma transação e efetivar as alterações realizadas, usamos

COMMIT. Isso fará com que a última transação aberta seja fechada de maneira

bem sucedida.

3.3. ROLLBACK

Outra alternativa é o ROLLBAC. Isso fará que todos os comandos executados

dentro da última transação aberta sejam imediatamente desfeitos. Isso faz com

que a transação seja fechada, porém nenhuma alteração será persistida.

3.4. Na prática

Utilizando o banco de dados sakila, vamos criar uma transação para realizar o

aluguel de um DVD. Para tanto vamos considerar que a regra de negócio para

criar um aluguel válido é a seguinte:

Primeiro, confirmar que o item de inventário dado está em estoque;

Em seguida, inserir uma linha na tabela de locação, criando o objeto

“aluguel”;

Depois inserir uma linha na tabela de pagamento, referenciando o

aluguel recém criado e dando o mesmo como pago.

Page 32: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Esta operação, embora ainda seja considerada simples, é um típico processo

que é mais adequado de ser criado no lado do servidor, deixando para a

aplicação apenas a chamada desta transação.

Agora vamos detalhar os comandos necessários:

No primeiro comando SELECT INVENTORY_IN_STOCK(10); retorna o

valor booleano 1, indicando que retornou verdadeiro. Aqui é usado um select

sobre uma função armazenada (funções serão vistas no capítulo 3) que retorna

verdadeiro se existe estoque para o item desejado.

Logo após é inserido um registro na tabela de aluguel. No comando seguinte

recuperamos o valor devido pelo cliente na variável @balance através da

função get_customer_balance(). Então finalmente inserimos o

registro na tabela de pagamentos.

Nossa lógica e comandos estão prontos, agora precisamos tornar estes

comandos uma transação única, garantindo que todos os comandos serão

Page 33: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

executados com sucesso se, e somente se, todos os comandos

individualmente tiverem sucesso, ou seja nenhum erro.

A resposta é simples, basta adicionarmos as palavras chaves BEGIN e

COMMIT no antes e depois dos comandos respectivamente. O exemplo final

fica:

Para validarmos podemos consultar a tabela payment com o seguinte

comando:

SELECT * FROM payment WHERE customer_id = 3;

O qual deve retornará o seguinte resultado:

Desafio:

Nesta transação que criamos, existe um pequeno erro lógico, você consegue

identificar qual é o erro?

O erro consiste no fato de testarmos a informação se existe o item em estoque

mas não usamos o resultado. Dependendo das regras de negócio, você

também pode precisar verificar se o cliente tem um saldo devedor antes de

processar o aluguel.

Tente recriar esta transação fazendo estes dois ajustes; utilizar a informação

retornada pela função INVENTORY_IN_STOCK() e criar a validação se o

Page 34: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

cliente possui saldo devedor e somente processar o aluguel se não existir saldo

devedor.

3.5. Deadlocks

Uma das maneiras que as transações atingem as propriedades ACID é através

do bloqueio de tabelas, ou de registros, de forma que outras transações ou

comandos isolados não possam manipulá-los. Isso resulta em uma fila de

espera: assim que o bloqueio é desfeito, as alterações pendentes são

realizadas.

Uma transação A pode encontrar um bloqueio criado por outra transação

concorrente B, e desta forma fica em estado de espera; isto é, parada,

enquanto B não libera o bloqueio. Vamos supor que ambas transações A e B

façam operações nas tabelas Compositores e Obras, porém em ordens

diferentes. Desta forma, A bloqueou a tabela Compositores, e B bloqueou

Obras. A transação A, portanto, aguardará o término de B, para que Obras seja

desbloqueada. Porém, a transação B está aguardando que A libere a tabela

Compositores. Isto resultou em um bloqueio mútuo, de forma que nenhuma das

duas transações pode terminar. No jargão de banco de dados, isso se chama

deadlock.

A maioria dos SGBDs possui mecanismos internos que detectam deadlocks. A

única solução, porém, é “matar” uma das transações com um ROLLBACK, para

que a outra possa terminar. Em consequência, A ocorrência de deadlocks em

um banco de dados pode acarretar em um comportamento imprevisível nas

aplicações. Desta forma, todo esforço deve ser dedicado para que deadlocks

não ocorram.

A principal regra que evita a ocorrência de deadlocks é que todas as

transações acessem as tabelas na mesma ordem. Se no caso acima, A e B

ambas acessassem Compositores e Obras nessa mesma ordem (ou na ordem

inversa), não haveria a possibilidade de deadlocks entre elas. Em transações

Page 35: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

simples, essa recomendação pode ser fácil de seguir, mas em sistemas com

um grande número e complexidade de transações, pode ser bastante difícil

assegurar isso. A definição de transações, portanto, pode não ser uma tarefa

trivial.

4. Definição e utilização de Visões.

Visões, conhecidas como VIEWS, em SQL são consultas armazenadas em

uma estrutura de fácil acesso baseadas no comando SELECT. Essa consulta

armazenada funciona como uma tabela virtual, com comportamento similar a

uma tabela real, entretanto, sem armazenar dados, não existindo como uma

entidade independente no banco de dados. Os dados que são exibidos

nas visões são gerados dinamicamente toda vez que a visão é referenciada.

O SGBD armazena apenas a definição das visões (nome da visão e o

comando SELECT). Quando o usuário chama uma visão, o sistema de banco

de dados associa os dados apropriados a ela. Uma visão apresenta o

resultado final desse processo, ocultando todos os detalhes técnicos.

A utilização de visões permite simplificar e personalizar tabelas no seu banco

de dados. Também oferece um mecanismo de segurança (restringindo o

acesso de usuários a campos predeterminados).

Views também são muito uteis quando temos consultas complexa que são

constantemente utilizadas, como consultas com vários JOINS, Ao invés de se

digitar ou enviar ao servidor toda a query, é executado apenas um select

simples. Isto também provê um nível de encapsulamento de determinadas

informações e/ou estruturas.

Por exemplo é comum usarmos uma série de estruturas de tabelas e regras

para calcular a folha de pagamento, porém para a aplicação ou determinada

parte da aplicação (módulo) pode-se desejar que esta estrutura complexa não

Page 36: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

seja conhecida e nem acessada, neste caso uma view que traga apenas as

informações necessárias se faz muito útil.

4.1. Criação, Edição, exclusão e Alteração

Existem algumas restrições quanto utilização, criação e atualização de views.

Estas restrições são diferentes de acordo com cada SGBD, bem como detalhes

na sua sintaxe. Lembrando que esta apostila é focada no MySQL, logo sua

sintaxe e detalhes mais técnicos também.

Abaixo temos algumas restrições no momento da criação de uma view:

A instrução SELECT não pode conter uma subconsulta na cláusula

FROM.

A instrução SELECT não pode se referir a variáveis do sistema ou do

usuário.

Não é possível associar uma trigger à uma visão

No momento de criação da view qualquer tabela citada precisa existir, porém

uma tabela referenciada por uma view já criada pode ser excluída. O que

causará um erro ao se tentar consultar a view.Para verificar este tipo de

problema pode-se usar o comando CHECK TABLE.

Para maiores detalhes sobre a definição de VIEWS consultar o manual do

MYSQL.

CREATE VIEW

A instrução para criar uma visão é bastante simples, basta adicionar as

palavras CREATE VIEW antes da instrução da consulta que se deseja

armazenar. A sintaxe de criação de uma visão é descrita no destaque abaixo.

Page 37: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Nessa expressão, no campo nome_da_visão deve-se inserir o nome que se

deseja atribuir para a visão, nome esse que deve seguir as mesmas regras

usadas para os nomes das tabelas. Após a cláusula AS, tem-se qualquer

comando SELECT válido.

Após criar a View para visualizar seus dados basta acessá-la exatamente como

uma tabela, conforme exemplo abaixo:

ALTER VIEW

O comando para alteração de uma View também é simples, basta utilizar o

comando ALTER VIEW nome_da_view AS, seguido da query responsável por

trazer os resultados da view. Ex:

DROP VIEW

O comando para excluir uma view é igual ao de excluir uma tabela, exceto pela

palavra chave VIEW ao invés de TABLE. Ex:

Page 38: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Importante:

Lembrando que por se tratar de uma tabela virtual, quando ela é excluída os

dados não são deletados, pois eles continuam nas suas tabelas de origem.

4.2. Manipulação de dados em Visões

Embora a criação, alteração e exclusão da definição de uma view possam ser

praticamente iguais a de uma tabela, a manipulação dos seus dados no não é

exatamente igual. Lembrando que uma visão é apenas uma estrutura virtual e

não real dos dados, assim o tratamento dos seus dados é diferente.

Na maioria dos SGBDs a manipulação dos dados através de views não é

permitido, porém no MySQL isto, em alguns casos é possível. O que

acreditamos não ser recomendável e tão pouco uma boa prática. O mais

aconselhável é fazer toda manipulação dos dados diretamente sobre as tabelas

e nunca sobre as views. Embora o MySQL permita manipular os dados

diretamente através das views, em alguns casos. Veremos apenas a parte

conceitual, visto que como dito antes, não é uma boa prática.

O MySQL permite atualizar e excluir os dados através das visões, desde que

na visão não tenha valores agregados, tais como SUM, COUNT e AVG, e nem

cláusulas como GROUP BY e DISTINCT.

Também não é possível atualizar ou inserir dados em uma view que não

possuam em sua definição todos os campos NOT NULL das tabelas as quais

fazem referências. Isto acontece porque quando a view é atualizada as

respectivas tabelas também o são, mas caso os campos NOT NULL não

estejam na definição da view eles seriam atualizados com valor NULO, o que

não é permitido pela restrição da tabela.

Page 39: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

A regra citada acima não é validade para campos AUTO INCREMENT, pois

campos deste tipo, embora também possam ser not null não necessitam de

um valor para inclusão de novo registro.

5. Estrutura dos dados

5.1. Introdução

Esta apostila é focada na storage engine InnoDB. Mas como estamos no

capítulo que trata justamente do armazenamento de dados, apresentaremos

um resumo dos principais storage engines suportadas pelo MySQL. Mas antes

vamos definir o que é Storage engine.

Um mecanismo de armazenamento (ou motor de banco de dados), ou ainda

simplesmente engine é o componente de software interno que um SGBD usa

para criar manipular os dados. A maioria dos sistemas de gerenciamento de

banco de dados incluem sua própria interface de programação de aplicativo

(API) que permite ao usuário interagir com o seu motor subjacente, sem passar

pela interface do usuário do SGBD. Em em outras palavras os usuários do

SGBD usam os mesmos comandos de DML sem se preocupar com o engine

utilizado, se tratando de um mecanismo do mesmo modelo claro, como o

transacional o qual estamos tratando nesta apostila e no curso.

Muitos dos SGBDs modernos suportam vários motores de bancos de dados

dentro do mesmo banco de dados.

5.2. Mecanismos de Armazenamento (Storage engines)

O MySQL suporta vários tipos de mecanismos para controlar o armazenamento

(storage engines) - não usando assim o file system do SO - que atuam como

controladores para diferentes tipos de tabelas:

Page 40: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

MyISAM: Suportada em todas as configurações do MySQL. É indicado

para armazenar dados que serão consultados frequentemente. Como

por exemplo, um cadastro de estados e de cidades. Suas principais

características são:

Limite de armazenamento de 256 TB;

Dados podem ser comprimidos;

Possibilidade de indexar também campos BLOB e TEXT;

Ausência de chaves estrangeiras (foreign key);

Ausência de transações (commit e rollback);

InnoDB: É o atual motor de armazenamento padrão do MySQL a

partir da versão 5.5, devido a sua alta confiabilidade e performance.

Suas principais vantagens são:

Limite de armazenamento de 64 TB;

Suporte a transações Commit, Rollback e Crach-Recovery;

Suporte a chaves estrangeiras (Foreign Key);

Permite utilizar outros tipos de motores de armazenamento, o estilo Oracle de

leitura consistente e de alta performance a multi-usuários, mantém sua própria

área de buffer para armazenamento de dados.

Merge: Permite a operação de agrupar logicamente, tabelas MyISAM

idênticas, de forma a ficarem referenciadas como uma só, em outras

palavras simula o comportamento relacional do InnoDB (PK e FKs) em

tabelas MyISAM.

Memory: Também conhecida como Heap, cria tabelas com o conteúdo

que está em memória alta (RAM), isto permite um acesso muito rápido

as informações, porém por utilizar a memória RAM, a quantidade de

informações que pode ser armazenada é bem limitada. Entrou em

desuso devido ao InnoDB que absorveu esta característica através do

seu buffer de memória que atende ao mesmo propósito.

Example: Serve apenas para programadores que tenham interessse

em desenvolver novos storage engines. Permite criar tabelas usando-o,

Page 41: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

mas nenhuns tuplos (registros) podem ser criados ou lidos, servindo

apenas para ilustrar aos programadores como se inicia o

desenvolvimento de uma storage engine.

Federated: Possibilita unir um grupo de servidores físicos MySQL em

um único servidor lógico. É muito útil para aplicações distribuídas

especialmente os que necessitam de um grande volume de dados como

os repositórios conhecidos como Data Warehouse.

Arquive: Mais indicado para armazenar e recuperar grandes blocos

de dados que poucas vezes são usados, tais como históricos, logs de

segurança e informações de auditoria.

CSV: Armazena os dados em ficheiros de texto no formato csv

(comma-separated values), ou simplesmente separados por vírgula. É

um motor bem primitivo e pouco usado.

Blackhole: Recebe dados, mas não os armazena. Este mecanismo é

usado em computação distribuída, onde os dados não são armazenados

localmente, mas, sim, replicados.

NDBCLUSTER: Também conhecida como NDB, não é suportada no

MYSQL 5.1. Este engine foi descontinuado e atualmente é suportado

pelo MySQL Cluster NDB 7.2. É um motor especialmente desenvolvido

para computação distribuída.

Para maiores informações sobre o Cluster NDB veja a documentação oficial do

produto em: http://dev.mysql.com/doc/refman/5.6/en/mysql-cluster.html

Para definir um storage engine o comando é o seguinte:

Também é permitido definir um motor apenas para uma tabela específica, para

isto deve-se definir o engine ao criar a tabela, veja a sintaxe no exemplo

abaixo:

Page 42: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Como visto acima, a sintaxe para se definir um engine diferente para uma

tabela é bem simples, bastando acrescentar a definição engine =

<tipo_engine>.

5.2.1. Arquitetura do MySQL com Storage Engines

A arquitetura do MySQL é independente do motor de armazenamento em uso e

é sempre idêntica. As Storage Engines simplesmente funcionam como um

conexão que é feita no MySQL, permitindo ao programador uma escolha mais

benigna para o sistema, indo de encontro à necessidade da aplicação.

Por exemplo, pode ser desejar deixar o sistema mais lento em pontos que não

necessita, porém com uma capacidade de armazenamento maior. Sempre que

for necessário pode se optar por storage engine diferente; e neste caso não é

requerido instalar nada de novo no sistema, tão pouco fazer algum tipo de

alteração significante do processamento ou de código.

Abaixo temos uma figura que representa a arquitetura do MySQL com storage

engines.

Page 43: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Detalhando a figura verificamos que todo conjunto de ferramentas e técnicas; e

a própria linguagem SQL em si, estão em uma única camada acima dos

storage engines, o qual, conforme a figura indica, podem ser inclusive

plugáveis. O que torna o MySQL sob aspecto bastante poderoso e competitivo.

Abaixo temos um quadro detalhando os principais Storage Engines por

funcionalidade:

Page 44: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

6. Segurança.

Independente do sistema e do ambiente, ou mesmo do seu tamanho e

complexidade, as questões relativas a segurança e recuperação dos dados são

primordiais. De nada vale um SGBD bem arquitetado e uma aplicação robusta

se seus dados e/ou estruturas podem ser facilmente corrompidos ou mesmo

acessados e violados indevidamente.

O MySQL por ser um banco muito utilizado e gratuito é também uma fonte de

risco grande, uma vez que muitos usuários conhecem seu funcionamento, suas

senhas e configurações padrões. Portanto conhecer bem o seu SGBD e saber

aplicar as melhores práticas na administração do mesmo são vitais para

segurança e continuidade do banco de dados e dos sistemas que rodam sobre

ele.

Aliado a segurança do sistema, o armazenamento e recuperação dos seus

dados são essências para a continuidade do mesmo e eventuais incidentes.

Mesmo quando não ocorrem situações de falha, é comum situações de

migração ou mesmo atualizações sobre o banco de dados. O qual exigem

processos de restauração bakcup de dados.

Neste capitulo serão discutidas as melhores praticas e técnicas de segurança ,

armazenamento e recuperação de dados no MySQL.

6.1. Tipos de Segurança

Em ambientes com múltiplos usuários, é importante proteger o banco de dados

de alterações indevidas nos dados ou nas estruturas das tabelas, as quais

podem comprometer a integridade do banco de dados. Além disso, evita o

acesso de determinados usuários a dados sigilosos, como, por exemplo, a

folha de pagamento dos empregados de uma empresa. Com esse propósito, os

SGBDs possuem um conjunto de regras e mecanismos de proteção de acesso

ao banco de dados denominado segurança ou autorização.

Page 45: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

A segurança em banco de dados pode ser classificada em duas categorias:

segurança de sistema: relaciona-se com o controle de acesso ao banco de

dados no nível de sistema, como, por exemplo, nome de usuário e senha;

segurança de banco de dados: relaciona-se com o controle de uso dos

objetos do banco de dados e as ações que esses usuários podem realizar

sobre os objetos.

Primeiramente veremos como configurar o MySQ com os requisitos iniciais

iinimos de segurança.

6.2. Configurando os Privilégios Iniciais do MySQL

Depois de instalar o MySQL, normalmente cusma-se configurar os privilégios

iniciais dos acessos através do prórpio instalador do MySQL, caso esteja

utilizando alguma versão mais antiga do MySQL verifique diretamente na

documentação oficial do mesmo, citada nas referencias desta apostila.

Seja pelo instalador ou pelos scripts, após iniciar o servidor mysqld, as tabelas

de permissões com a seguinte configuração dos privilégios:

• O usuário root do MySQL é criado como um superusuário que

pode fazer qualquer coisa. Conexões devem ser feitas através da

máquina local.

NOTA: A senha inicial de root é vazia, portanto qualquer um que conectar

como root sem senha terá direito a todos os privilégios.

• Um usuário anônimo é criado e pode fazer o que desejar com

bancos de dados com nome 'test' ou iniciando com 'test_'. Conexões

devem ser feitas da máquina local. Isto significa que usuários locais

podem se conectar sem senha e serem tratados como usuários

anônimos.

• Outros privilégios são negados. Por exemplo, usuários normais

não podem executar mysqladmin ou mysqladmin processlist.

Page 46: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

NOTA: Os privilégios padrões são diferentes no Windows. See Secção 2.1.1.8,

“Executando o MySQL no Windows”.

6.2.1. Verificando a senha de root

Se você acabou de instalar o MySQL, tanto no Linux, quanto no Windows,

provavelmente você já saiba a senha de root (ou então ela esteja vazia). Se

você já sabe e tem certeza da senha, pode pular à vontade este item.

Para verificar a senha via linha de comando:

Se o prompt do mysql apareceu, então a senha está correta e iremos usar ela.

Se ao invés disso aparecer:

Isso quer dizer que a senha está errada. Como citado antes, muitas das vezes

a senha do MySQL está vazia depois da instalação, para verificar, retire o

parâmetro -p (de password) e veja se cai no prompt MySQL:

6.2.2. Configurando senhas

Page 47: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Como sua instação inicialmente é parcialmente aberta, uma das primeiras

coisas que você deve fazer é especificar uma senha para o usuário root do

MySQL. Você pode fazer isto como a seguir (perceba que a senha foi

especificada utilizando a função PASSWORD()):

shell> mysql -u root mysql

mysql> SET PASSWORD FOR root@localhost=PASSWORD('nova_senha');

Substitua 'nova_senha' pela senha que você deseja usar.

Se você souber o que esta fazendo, você também pode manipular diretamente

a tabela privilégios:

shell> mysql -u root mysql

mysql> UPDATE user SET Password=PASSWORD('nova_senha')

-> WHERE user='root';

mysql> FLUSH PRIVILEGES;

Outra forma de configurar a senha é utilizando o comando mysqladmin:

shell> mysqladmin -u root password nova_senha

Somente usuários com acesso de escrita/atualização ao banco de dados mysql

podem alterar a senha de outros usuários. Todos os usuários comuns (não os

anônimos) podem alterar somente a própria senha com um dos comandos

acima ou com SET PASSWORD=PASSWORD('nova_senha').

Perceba que se você atualizar a senha na tabela user diretamente utilizando

UPDATE, você deve dizer ao servidor para reler as tabelas de permissões (com

FLUSH PRIVILEGES), de outra forma a alteração não seria notificada.

Uma vez que a senha de root foi configurada, você deve informar a senha

quando se conectar ao servidor MySQL como root.

Page 48: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Você pode desejar deixar a senha de root em branco para que você não

precise especificá-la quando realizar configurações adicionais ou testes.

Entretanto, tenha certeza de configurá-la antes de utilizar sua instalação para

qualquer ambiente de produção.

Veja o script scripts/mysql_install_db para ver como são configurados os

privilégios padrões. Você pode usar isto como uma base para ver como

adicionar outros usuários. Se você deseja que os privilégios iniciais sejam

diferentes do descrito acima, é possível modificar o script mysql_install_db

antes de executá-lo.

Para recriar as tabelas de permissões completamente, remova todos os

arquivos .frm .MYI e .MYD no diretório contendo o banco de dados mysql. (Este

é o diretório chamado mysql sob o diretório do banco de dados, que é listado

quando você executa mysqld --help). Depois execute o script

mysql_install_db, possivelmente depois de editá-lo para criar os privilégios

desejáveis.

Isto deve ser o suficiente para se conseguir um ambiente minimamente seguro.

Caso deseje saber maiores detalhes sobre configurações avançadas do

servidor e permissões, você pode consultar diretamente o manual de referência

do MySQL.

6.2.3. Configurando Privilégios (GRANT e REVOKE)

Após a devida criação e configuração dos usuários necessários, o próximo

passo é dar dos privilégios que cada usuário deve possuir. Neste sentido

existem diversas politicas e boas práticas, uma em especial, que é sempre

válida na hora de conceder qualquer tipo de permissão; a de que deve primeiro

retirar todos os privilégios de todos os usuários e depois adicionar somente as

permissões necessárias.

Page 49: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Para isto utilizamos os comandos GRANT e REVOKE, o qual permitem aos

administradores do sistema criar usuários e conceder e revogar direitos aos

usuários do MySQL em quatro níveis de privilégios.

Comandos:

GRANT: Adiciona permissões ao usuário.

REVOKE: Remove permissões do usuário.

Sintaxe:

Os níveis de privilégios no Mysql são os seguintes:

Nível Global

Privilégios globais aplicam para todos os bancos de dados em um determinado

servidor. Estes privilégios são armazenados na tabela mysql.user. Os

comandos GRANT ALL ON *.* e REVOKE ALL ON *.* concederão e revogarão

apenas privilégios globais.

Nível dos bancos de dados

Page 50: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Privilégios de bancos de dados aplicam-se a todas as tabelas em um

determinado banco de dados. Estes privilégios são armazenados nas tabelas

mysql.db e mysql.host. GRANT ALL ON db.* e REVOKE ALL ON db.*

concederão e revogarão apenas privilégios de banco de dados.

Nível das tabelas

Privilégios de tabelas aplicam-se a todas as colunas em uma determinada

tabela. Estes privilégios são armazenados na tabela mysql.tables_priv. GRANT

ALL ON db.table e REVOKE ALL ON db.table concederão e revogarão apenas

privilégios de tabelas.

Nível das colunas

Privilégios de colunas aplicam-se a uma única coluna em uma determinada

tabela. Estes privilégios são armazenados na tabela mysql.columns_priv.

6.2.4. Tipos de privilégios

Para as instruções GRANT e REVOKE, tipo_priv pode ser especificado como

um dos seguintes:

ALL [PRIVILEGES] Configura todos os privilégios simples exceto WITH GRANT OPTION

ALTER Permite o uso de ALTER TABLE

CREATE Permite o uso de CREATE TABLE

CREATE TEMPORARY

TABLES

Permite o uso de CREATE TEMPORARY TABLE

DELETE Permite o uso de DELETE

DROP Permite o uso de DROP TABLE.

EXECUTE Permite que o usuário execute stored procedures (MySQL 5.0)

FILE Permite o uso de SELECT ... INTO OUTFILE e LOAD DATA INFILE.

INDEX Permite o uso de CREATE INDEX e DROP INDEX

INSERT Permite o uso de INSERT

LOCK TABLES Permite o uso de LOCK TABLES em tabelas nas quais se tem o

privilégio SELECT.

Page 51: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

PROCESS Permite o uso de SHOW FULL PROCESSLIST

REFERENCES Para o futuro

RELOAD Permite o uso de FLUSH

REPLICATION CLIENT Da o direto ao usuário de perguntar onde o slave/master está.

REPLICATION SLAVE Necessário para a replicação dos slaves (para ler logs binário do master).

SELECT Permite o uso de SELECT

SHOW DATABASES SHOW DATABASES exibe todos os banco de dados.

SHUTDOWN Permite o uso de mysqladmin shutdown

SUPER Permite a conexão (uma vez) mesmo se max_connections tiverem sido

alcançados e executa o comando CHANGE MASTER, KILL thread, mysqladmin

debug, PURGE MASTER LOGS e SET GLOBAL

UPDATE Permite o uso de UPDATE

USAGE Sinônimo para “sem privilégios''.

GRANT OPTION Sinônimo para WITH GRANT OPTION

Logicamente muitas destas só podem ser utilizadas em determinados objetos,

assim temos algumas regras no uso destes tipos de permissões, as principais

são:

Os únicos valores de tipo_priv que você pode especificar para uma

tabela são SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,

GRANT, INDEX e ALTER.

Os únicos valores de tipo_priv que você pode especificar para uma

coluna (isto é, quando você usar uma cláusula column_list)

são SELECT, INSERT e UPDATE.

O MySQL permite que você crie privilégios a nível de banco de dados mesmo

se o banco de dados não existir para tornar fácil de se preparar para o uso do

banco de dados. Atualmente, no entanto, o MySQL não permite criar

permissões de a nível de tabela se a tabela não existir. O MySQL não revogará

automaticamente qualquer privilégio, mesmo se você apagar uma tabela ou

banco de dados.

Page 52: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Você pode configurar privilégios globais utilizando a sintaxe ON *.*. Você pode

configurar privilégios de bancos de dados utilizando a sintaxe ON nome_bd.*.

Se você especificar ON * e estiver com algum banco de dados aberto, será

configurado os privilégios somente para este banco de dados. (AVISO: Se

você especificar ON * e você não tem possui um banco de dados aberto, irá

afetar os privilégios globais!).

Para acomodar concessões de direitos para usuários de máquinas arbitrárias,

o MySQL suporta a especificação do valor user_name no

formato usuário@máquina. Se você desejar especificar uma

string user contendo caracteres especiais (como o ‘-’), ou uma string contendo

caracteres especiais ou meta caracteres (como o ‘%’), você pode colocar o

usuário ou o nome de máquina entre aspas (por exemplo, 'usuário-

teste'@'máquina-teste').

Você também pode especificar meta caracteres no nome da máquina. Por

exemplo, user@"%.loc.gov" se aplica a user para qualquer máquina no

domínio loc.gov, e user@"144.155.166.%" se aplica a user em qualquer

máquina na subrede de classe C 144.155.166. O formato simples user é

sinônimo de user@"%".

O MySQL não suporta metacaracteres em nomes de usuários. Usuários

anônimos são definidos inserindo entradas com User='' na tabela mysql.user ou

criando um usuário com um nome vazio com o comando GRANT.

No momento, GRANT suporta somente nomes de máquinas, tabelas, bancos

de dados e colunas até 60 caracteres. Já o nome de usuário pode ter até 16

caracteres.

Os privilégios para uma tabela ou coluna são formados através do OU lógico

dos privilégios em cada um dos quatro níveis de privilégios. Por exemplo, se a

tabela mysql.user especifica que um usuário tem um privilégio global select,

isto não pode ser negado por uma entrada no nível de banco de dados, tabela

ou coluna.

Page 53: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

Os privilégios para uma coluna podem ser calculados da seguinte forma:

privilégios globais

OR (privilégios de banco de dados AND privilégios de

máquina)

OR privilégios de tabela

OR privilégios de coluna

Esta combinação de privilégios nos permite detalhar exatamente o que cada

usuário poderá acessar e fazer. E, embora isto seja bem interessante para

algumas situações e aplicações específicas, na maioria dos casos, os direitos a

um usuário são atribuídos em apenas um dos níveis de privilégios, portanto a

vida normalmente não é tão complicada como mostrado acima.

Se um usuário não tem privilégios em uma tabela, a tabela não é mostrada

quando o usuário solicita uma lista de tabelas (com a instrução SHOW

TABLES por exemplo). O mesmo é verdade para SHOW DATABASES

6.2.5. Privilégio de dar privilégios (WITH GRANT OPTION)

A cláusula WITH GRANT OPTION dá ao usuário habilidade de fornecer à outros

usuários quaisquer privilégios que ele tenha em um nível específico de

privilégio. Você deve ter cuidado ao fornecer o privilégio grant, pois dois

usuários podem se unir para unir privilégios!

Você não pode conceder a outro usuário um privilégio que não possua; o

privilégio GRANT possibilita fornecer somente os privilégios que possuir. Esteja

ciente que quando conceder a um usuário o privilégio GRANT em um nível

particular de privilégios, qualquer privilégio que o usuário já possua (ou seja

fornecido no futuro!) nesse nível também pode ser concedido por este usuário.

Suponha que você conceda a um usuário o privilégio INSERT em um banco de

dados. Se você conceder o privilégio SELECT no banco de dados e

especificar WITH GRANT OPTION, o usuário além de poder repassar o

privilégio SELECT poderá também repassar o insert. Se você concede o

Page 54: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

privilégio UPDATE para o usuário no banco de dados, o usuário poderá

conceder os privilégios INSERT, SELECT e UPDATE.

Você não deve conceder privilégios ALTER a um usuário comum. Se você fizer

isto, o usuário pode tentar enganar o sistema de privilégios renomeando

tabelas!

Perceba que se você estiver utilizando privilégios de tabelas ou colunas,

mesmo que para apenas um usuário, o servidor examina os privilégios de

tabelas e colunas para todos os usuários e isto irá deixar o MySQL um pouco

mais lento.

Quando o mysqld inicia, todos os privilégios são lidos na memória. Privilégios

de bancos de dados, tabelas e colunas são iniciados um vez, e privilégios ao

nível de usuário fazem efeito na próxima vez que o usuário conectar.

As modificações nas tabelas de permissões que você realiza pelos comandos

GRANT ou REVOKE são percebidas pelo servidor imediatamente. Agora se

você modificar as tabelas de permissões manualmente (utilizando

INSERT,UPDATE, etc), você deve executar uma instrução FLUSH

PRIVILEGES ou executar mysqladmin flush-privileges para

dizer ao servidor para recarregar as tabelas de permissões.

As maiores diferenças entre o padrão SQL e versões MySQL de GRANT são:

No MySQL privilégios são fornecidos para uma combinação de usuário e

máquina e não somente para um usuário.

O SQL padrão não possui privilégios no nível global ou de bancos de

dados, e não suporta todos os tipos de privilégios que o MySQL suporta.

O MySQL não suporta os privilégios TRIGGER, EXECUTE ou UNDER do SQL-

99.

Os privilégios do SQL são estruturados em uma maneira hierárquica. Se

você remover um usuário, todos os privilégios do usuário são removidos.

Page 55: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

No MySQL os privilégios concedidos não são removidos

automaticamente, mas você deve removê-los se necessário.

Se no MySQL você possuir o privilégio INSERT em somente parte das

colunas em uma tabela, você pode executar instruções INSERT na tabela;

As colunas em que você não tem o privilégio INSERT irão receber seus

valores padrões. O SQL padrão necessita que você tenha o

privilégio INSERT em todas as colunas.

Quando você remove uma tabela no SQL padrão, todos os privilégios

para a tabela são removidos. Se você remover um privilégio no SQL-99,

todos os privilégios que foram concedidos baseado neste privilégio são

também removidos. No MySQL, privilégios só podem ser removidos com

comandos REVOKE explícitos ou manipulando as tabelas de permissões

do MySQL.

Page 56: Banco de Dados II

CURSO TÉCNICO EM INFORMÁTICA SENAC-RS

REFERÊNCIAS

http://ftp.nchu.edu.tw/MySQL/doc/refman/4.1/pt/grant.html http://dev.mysql.com/doc/sakila http://dev.mysql.com/doc/refman/5.7/en/