SERVIÇO NACIONAL DE APRENDIZAGEM COMERCIAL
CURSO TÉCNICO EM INFORMÁTICA
BANCO DE DADOS II
CURSO TÉCNICO EM INFORMÁTICA
CURSO TÉCNICO EM INFORMÁTICA
BANCO DE DADOS II
Profissional responsável pela elaboração do conteúdo: Prof° Edimar Gusmão Martins
SENAC-RS
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
CURSO TÉCNICO EM INFORMÁTICA
SENAC-RS
5.2. Mecanismos de Armazenamento (Storage ( 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
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 f ormas 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) 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) function) é similar à descrição de sub-rotina e por conseguinte à descrição de procedimento. p rocedimento.
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.
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.
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.
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 .
Cr ia ção , ed ição e ex c lu s ão d e Pr o c ed u re s :
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 n o m e _ d o _ p r o c e d i m e n t o é 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.
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.
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. Observase 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:
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 f i l m e 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.
Procedim entos Cond icionais
É 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,
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:
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:
CURSO TÉCNICO EM INFORMÁTICA
SENAC-RS
Adicionamos o novo parâm etro 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).
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 âm etr o s de En trad a e Saíd a
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
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 c o u n t pelo valor passado em inc.
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.
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.
Fu nções esc alar es
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: n o m e _ d a _ f u n c a o : É o nome que se deseja atribuir para a função. Esse nome
deve seguir as mesmas regras usadas para os nomes das tabelas.
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. ca rac ter íst ic as: 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 d eter m in is ta 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.
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:
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:
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:
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;
CURSO TÉCNICO EM INFORMÁTICA
trigger_stmt:
SENAC-RS
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.
Operad ores 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.
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 .
“
”
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:
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 C o d e C o n v e n t i o n s ou C o d i n g S t an d a r d s 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 “s p _” 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,
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.
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 ( c o n s i s t e n c y ): 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.
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.
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 r etorna 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
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
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
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
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.
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:
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 t abelas 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.
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 n o t n u l l 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 eng ine. Um mecanismo de armazenamento (ou motor de banco de dados), ou ainda simplesmente e n g i n e é 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:
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,
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:
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
=
.
5.2.1.
Arq uitetura 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.
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:
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.
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.
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.
Verificand o a senh a de roo t
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.
Configu rando senhas
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.
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 r eferência do MySQL.
6.2.3.
Con fig ur and o Priv ilé gi os (GRANT e REVOK E)
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.
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
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.
Tip o s de p riv ilé gi o s
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 Permite o uso de CREATE TABLE
CREATE CREATE
TEMPORARY
Permite o uso de CREATE TEMPORARY TABLE
TABLES 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.
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.
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
formato usuário@máquina.
a
especificação Se
você
do desejar
valor user_name no especificar
uma
s t r i n g u s e r 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 u s e r 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.
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.
Pr iv il é g io d e d ar p ri vi lé g io s (WITH GR A NT OP TION )
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
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 A L T E R 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 SQL99.
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.
CURSO TÉCNICO EM INFORMÁTICA
No
MySQL
os
privilégios
SENAC-RS
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.