FACE - FUMEC Superior em Tecnologia de Processamento de Dados Fundamentos de Banco de Dados Instrutor: Rodrigo Baroni de Carvalho Índice 1) Introdução __________________________________________________________________________ 3 2) Modelo Hierárquico _________________________________________________________________ 10 3) Modelo de Rede _____________________________________________________________________ 13 4) Modelo Relacional ___________________________________________________________________ 15 5) SQL (Structured Query Language) _____________________________________________________ 17 5.1) Objetos de um SGBD Relacional _____________________________________________________________ 17 5.2) Comando SELECT ________________________________________________________________________ 18 5.3) Alteração de Dados (DML) __________________________________________________________________ 18 5.4) Funcionalidades do SQL (DML) _____________________________________________________________ 19 5.5) Exemplos de Recuperação de Dados (DML) ___________________________________________________ 25 5.6) Utilização de Várias Tabelas _________________________________________________________________ 26 6) Administração de Banco de Dados ______________________________________________________ 32 7) SGBD Microsoft SQL Server __________________________________________________________ 36 8) Mercado de Banco de Dados Relacionais ________________________________________________ 40 9) Integridade Referencial _______________________________________________________________ 41 10) Bibliografia _______________________________________________________________________ 42 2 1) Introdução 1.1) Estrutura da Área de Informática - Antiga Desenvolvimento Suporte Define processos Define dados Gerencia hardware e software básico - Hoje Define processos Trabalha com a visão local dos dados Desenvolvimento Gerencia hardware e software básico Suporte Administração de Dados Define a estrutura de dados da empresa Gerencia a visão global dos dados 3 FASE Levantamento Análise Projeto Construção Manutenção FUNÇÃO Levantamento de Processos Análise Estruturada (DFD) Projeto Estruturado Codificação/Teste/Implant. Alteração nas Funções DADO Levantamento de Dados Modelagem de Dados Projeto Lógico do BD Projeto Físico do BD Alterações no BD OBS: O esquema propõe um tratamento diferenciado entre dados e funções mas não estanque, pois deve existir sempre uma forte interação entre a abordagem de dados e funções. • Administrador de Dados - Define a estrutura de informação da empresa (base de dados) - Administra a descrição da base de dados (dicionário de dados) - Define padrões para codificação de objetos da base de dados (arquivos, registros, variáveis) • Administrador de Banco de Dados - Gerencia a base de dados instalada - Administra o Sistema Gerenciador de Banco de Dados (SGBD) - Modifica a estrutura de armazenamento e a organização física - Concede autorização para acesso a dados 4 1.2) Enfoque Convencional de Armazenamento de Dados Aplicação 1 Arquivo 1 Aplicação 2 Arquivo 3 Aplicação 3 Arquivo 4 Arquivo 2 - Cada aplicação (sistema) era proprietária da sua base de dados particular. Registros são armazenados em vários arquivos e diferentes programas são escritos para extrair ou adicionar registros nos arquivos apropriados. - Problemas: • Redundância de dados: os arquivos e programas são criados por diferentes programadores fazendo com que a mesma informação esteja duplicada em diversos lugares. Essa redundância leva a um custo maior de armazenamento e acesso. Por exemplo, o endereço de um cliente pode aparecer em um arquivo que contém registros de conta corrente e em outro arquivo que contém contas de poupança. • Inconsistência de dados: várias cópias do mesmo dado não são coerentes. • Dificuldade de Aproveitamento dos Dados Existentes em Novas Aplicações: os dados estão espalhados em vários arquivos e os arquivos podem estar em diferentes formatos, dificultando a escrita de novos programas. • Inexistência de Controle Centralizado dos Dados: os dados podem ser acessados por muitos programas diferentes, que não foram previamente coordenados, ocasionando problemas de segurança e supervisão. • Dificuldade no Acesso aos Dados: a única maneira de obter os dados é através de programas. Não existem ferramentas amigáveis para elaboração de consulta dos usuários. 5 1.3) Enfoque do Sistema Gerenciador de Banco de Dados (SGBD) Aplicação 1 Arq.1 Arq.2 Aplicação 2 . . . S G B D Arq.3 Arq.4 Base de Dados Aplicação N Vantagens . Criação de uma base de dados comum a todos os sistemas . Existência de um controle centralizado dos dados da empresa . Eliminição de redundâncias . Permite que os dados possam ser vistos de forma diferente e mais adequada a cada aplicação . Facilita o desenvolvimento de novas aplicações para as quais os dados já estejam na base de dados Base ou Banco de Dados: conjunto inter-relacionado de arquivos que descrevem a estrutura de informação da empresa. O Banco de Dados é um depósito de dados armazenados, geralmente integrados e compartilhados. Sistema Gerenciador de Banco de Dados: software que administra uma base de dados proporcionando o acesso e a definição de informações desta base. Um SGBD consiste numa coleção de dados inter-relacionados e num conjunto de programas para acessar esses dados. O principal objetivo de um SGBD é proporcionar um ambiente, conveniente e eficiente, para retirar e armazenar informação no BD. 6 Propriedades de um SGBD: Integridade: garante que os dados armazenados representam as informações do mundo real de forma precisa. Segurança: garante que os dados sejam acessados por pessoas devidamente autorizadas. Recuperação e Backup: em casos de falhas elétricas, defeitos de equipamentos ou erros de software, o SGBD deve prover instrumentos para detectar tais falhas e restaurar o BD ao estado anterior. Concorrência: garante a possibilidade de acesso múltiplo, isto é, por vários usuários sem que ocorra inconsistências nos dados armazenados. Monitoração: fornecimento de ferramentas que possibilitem a verificação de como o sistema está se comportando a cada momento. Esquema de Dados em um SGBD Nível Externo ou de Visão: visão de cada usuário, sejam estes programadores ou usuários finais. Os usuários necessitam de apenas uma parte do BD. Podem haver diferentes visões providas pelo sistema para um mesmo BD. Nível Conceitual: visão da comunidade de usuários. Este nível descreve quais dados são armazenados no BD e quais os relacionamentos existentes entre eles. Nível Interno ou Físico: visão de armazenamento Nível Externo Mapeamento Externo/Conceitual Nível Conceitual Mapeamento Conceitual/Interno Nível Interno 7 Independência Lógica: ocorre quando alterações no nível conceitual não provocam modificações no nível externo. A independência lógica é mais difícil de ser atingida do que a independência física, uma vez que os programas são muito dependentes da estrutura lógica dos dados que manipulam. Ex: adição de um novo campo no registro. Independência Física: ocorre quando alterações no nível físico não provocam modificações no nível conceitual. Alterações no nível físico são necessárias ocasionalmente para melhorar a performance, como a criação de índices, por exemplo. Linguagens de um SGBD: DDL (Data Definition Language): linguagem de definição de dados. Permite a especificação da base de dados, definindo os arquivos, as ligações entre arquivos, os registros e as variáveis dos registros. DML (Data Manipulation Language): linguagem de manipulação de dados. Permite a consulta e atualização (inclusão, alteração e deleção) de informações da base de dados definida pela DDL. Pode ser procedural quando o usuário tem que especificar o caminho para acessar a informação ou não-procedural quando o usuário não define como os dados serão acessados. DMLs não-procedurais são mais fáceis de aprender e usar do que as DMLs procedurais, pois o usuário não precisa especificar como chegar até os dados, mas apenas quais dados deseja. Modelos de Dados de SGBD Modelo de Dados é uma coleção de ferramentas conceituais para descrição dos dados e seus relacionamentos, além de suas restrições e semântica. Os SGBDs utilizam uma forma de representação da base de dados que pode ser classificada em três categorias: - Modelo Hierárquico - Modelo de Rede - Modelo Relacional 8 Fases do Projeto de uma Base de Dados Modelagem de Dados Projeto Lógico Projeto Físico Modelagem de Dados: descreve a estrutura de informação da empresa sem se preocupar em qual SGBD a base de dados vai residir. Nesta fase, é feita a definição dos tipos de dados que a empresa manipula e como estes dados se relacionam. Esta fase deve contar com a participação do administrador de dados, do usuário final e do analista de sistemas. Projeto Lógico da Base de Dados: descreve um modelo de dados gerado na fase anterior para um determinado SGBD. Neste momento, o conhecimento das características do SGBD utilizado é fundamental para o sucesso do projeto. Esta fase deve contar com a participação do administrador de banco de dados, do analista de sistemas e do administrador de dados. Projeto Físico da Base de Dados: define de que maneira o projeto lógico será fisicamente armazenado, implicando na definição do espaço necessário em disco, da periodicidade dos backups, do volume de alteração dos dados e do número e perfil dos usuários que terão acesso aos dados. Nesta fase, deverá ser feito um estudo visando a melhoria de performance (“tunning do SGBD”), através da identificação dos processos mais críticos. Esta fase deve contar com a participação do administrador de banco de dados e do analista de sistemas. 9 2) Modelo Hierárquico Neste modelo as estruturas de dados são representadas no SGBD como coleções de registros e ligações entre registros, sendo que existe um hierarquia nas ligações, de modo que os registros formar uma estrutura de árvore. Diagrama de Estrutura de Dados Registro raiz Departamento Ligação Registro Funcionário Representação dos Dados 10 | Informática 30 | Finanças 40 | Pessoal 200 | Ana 100| Paulo 500| Rita 301| Cristina 110| Beatriz 600| Pedro 10 Linguagem de Manipulação (DML) GET FIRST <registro> WHERE <condição> GET NEXT <registro> WHERE <condição> GET NEXT WITHIN PARENT <registro> WHERE <condição> GET HOLD INSERT DELETE REPLACE Exemplos de recuperação no modelo hierárquico: 1 - Imprimir o endereço do funcionário Pedro. GET FIRST Funcionario WHERE Nome_Func = “Pedro” WRITE (Endereco_Func) 2 - Imprimir o nome do funcionário do departamento 10 e que ganhe mais de 2000 GET FIRST Funcionario WHERE Cod_Depto = 10 AND Salario_Func > 2000 WRITE (Nome_Func) 3 - Imprimir o nome de todos os funcionários que recebam mais de 1000 GET FIRST Funcionario WHERE Salario_Func > 1000 WHILE DB_STATUS = 0 WRITE (Nome_Func) GET NEXT Funcionario WHERE Salario_Func > 1000 END 4 - Imprimir a soma dos salários dos funcionários do departamento 10 SOMA:= 0.00 GET FIRST DEPTO WHERE COD_DEPTO = 10 GET NEXT WITHIN PARENT Funcionario WHILE DB_STATUS = 0 SOMA:= SOMA + SALARIO_FUNC GET NEXT WITHIN PARENT Funcionario END 11 Relacionamento Muitos para Muitos (N-N) Problema: Construir um modelo que responda as seguintes perguntas: - Quais os fornecedores que fabricam uma determinada peça ? - Quais as peças fabricadas por um deterninado fornecedor ? Para que o modelo hierárquico possa dar estas respostas de forma eficiente, teremos que montar 2 árvores: Fornecedor Peça Peça Fornecedor Este tipo de implementação provoca um alto nível de redundância de informações. Conclusão: O Modelo Hierárquico é apropriado para representar estruturas com características hierárquicas (relacionamento 1 para N ou mesmo 1 para 1), tornando-se ineficiente para estruturas mais complexas (relacionamentos N para N). O SGBD hierárquico mais difundido é o IMS (Information Management System) fornecido pela IBM. 12 3) Modelo de Rede Neste modelo os dados são também representados como coleções de registros e ligações, sendo que não existe uma hierarquia a ser seguida. O Modelo de Rede fornece uma estrutura mais geral que a do Modelo Hierárquico porque uma determinada ocorrência de registro pode ter qualquer quantidade de superiores ou de dependentes imediatos. Devido a isso a abordagem de Rede permite a modelagem de uma relação N para N mais diretamente do que a abordagem Hierárquica. A fixação do padrão do Modelo de Rede foi feita pelo DTBG (Data Base Task Group) do CODASYL. Diagrama de Estrutura de Dados Peça Fornecedor PF FP Registro Ligação P-F Representação dos Dados P1 | Parafuso 10 F1| Martins S/A P2 | Mola 20 30 F2 | Silva S/A 13 Linguagem de Manipulação de Dados (DML) 1 - Imprimir a quantidade total de peças a serem fabricadas pelo fornecedor Silva S/A. Soma:= 0.00 FIND ANY Fornecedor WHERE Nome_Func = “Silva S/A” FIND FIRST PF WHILE DB_STATUS = 0 Soma:= Soma + Qtde_Pecas FIND NEXT PF END Conclusão: O Modelo de Rede é efetivamente mais abrangente do que o Hierárquico, embora seu esquema de definição possa se tornar extremamente complexo, além de uma linguagem de manipulação ainda bastante procedural. Os SGBDs de rede mais difundidos são o TOTAL fornecido pela Cincon System e o IDMS fornecido pela Culliname Database System. O ADABAS (Adaptable Data Base System) fornecido pela Software AG utiliza um esquema de listas invertidas, adaptado a partir do modelo de rede. 14 4) Modelo Relacional O Modelo Relacional é fortemente baseado na teoria dos conjuntos, oferecendo assim uma representação simples e natural da informação. Os primeiros trabalhos de definição do modelo foram lançados em 1970 por E.F.Codd, sendo que a primeira tentativa de implementação do modelo foi realizada na IBM em 1974, através do Sistema R. O Modelo Relacional é uma teoria, mas nem todos os SGBDs ditos relacionais e disponíveis comercialmente implementam a teoria na sua totalidade. Esquema de uma Relação Ex: Relação de Funcionários Código 10 20 30 40 Nome Ana Maria Paulo Beatriz Leonardo Função Idade Analista Programador Analista Gerente Salário 30 22 40 45 1500 900 2200 3500 Relação: normalmente chamada de tabela nos SGBDs relacionais do mercado. É composta por 2 partes: -Cabeçalho: conjunto fixo de atributos, que são as colunas ou campos da relação. O número de atributos define o grau da relação. No exemplo, a relação tem grau 5. -Corpo: conjunto variável de tuplas, que são as linhas da relação. O número de tuplas define a cardinalidade da relação. No exemplo, a relação tem cardinalidade igual a 4. Podem ser observadas as seguintes propriedades: - Não existem tuplas duplicadas; - A ordem das tuplas é insignificante; - A ordem dos atributos é insignificante; - Os valores dos atributos são atômicos, sem grupos repetitivos; - Os atributos podem ter valores nulos, sendo que nulo significa inexistência de valor, diferente portanto de zero e branco. 15 Domínio: conjunto de valores a partir do qual um ou mais atributos extraem seus valores. Os atributos são comparáveis entre si, se e somente se pertencerem a um mesmo domínio. No exemplo da relação de funcionários, poderíamos dizer que o domínio do atributo idade é um número inteiro entre 13 e 70 e o domínio do salário seria um número real entre 100,00 e 10.000,00. Domínio é um conceito semântico. Por exemplo, peso e peça são numéricos, mas têm significado diferente. O mesmo domínio pode ser utilizado múltiplas vezes em uma relação. Ex: relação Peça-Substituída (Peça, Cod-Peça, Data) 3 atributos diferentes com 2 domínios apenas Chaves Chave Candidata: conjunto de atributos que definem unicamente e minimamente cada tupla de uma relação. Ex: Empregado (Código, Nome, CPF). Código e CPF são chaves candidatas. Chave Primária (Primary Key): é uma chave escolhida entre as chaves candidatas para identificar a tupla da relação. Ex: Empregado (Código, Nome, CPF). Código é a chave primária. Chave Alternativa: são as chaves candidatas não escolhidas para chave primária. Ex: Empregado (Código, Nome, CPF). CPF é a chave alternativa. Chave Estrangeira (Foreign Key): conjunto de atributos de uma relação R1 que constituem chave primária de uma outra relação R2. As chaves estrangeiras funcionam como elo de ligação entre relações. Ex: Empregado (Cod-Emp, Nome, Cod-Depto) Departamento (Cod-Depto, Nome, Gerente) Na relação Empregado, Cod-Emp é chave primária e Cod-Depto é chave estrangeira. Na relação Departamento, Cod-Depto é chave primária e Gerente é chave estrangeira, pois o gerente deve estar cadastrado na tabela de empregados. 16 5) SQL (Structured Query Language) O SQL é a linguagem padrão ANSI para acesso a banco de dados relacionais e engloba tanto uma DDL como uma DML. É uma linguagem a nível de conjunto, isto é, com um simples comando recuperamos um conjunto de registros, sem precisarmos efetuar leituras registro a registro. O SQL é utilizado tanto embutida em programas de aplicação tipo Cobol, PL/1, Natural, CSP, quanto por usuários finais através de ferramentas de consulta (ISQL, QBE, QMF) semelhantes ao modo interativo do padrão Xbase. 5.1) Objetos de um SGBD Relacional Tabela: estrutura utilizada para armazenar a base de dados. Corresponde a relação do modelo relacional. Visão: define uma estrutura virtual oriunda dos dados armazenados em tabelas. Tem a mesma forma de uma tabela, mas não se encontra armazenada fisicamente.Ex: visão dos funcionários que ganham mais de 800 de salário. Índice: estrutura que permite um acesso mais rápido aos dados de uma tabela. É apenas um instrumento de melhoria de performance nos processos de recuperação de informação. Não deve ser confundido com chave. Catálogo: local onde o SGBD armazena dados e estatísticas a respeito das tabelas. Tipos de Dados: SMALLINT: inteiro de 16 bits. Faixa: -32.768 a 32.767 INTEGER: inteiro de 32 bits. Faixa: -2.147.483.648 a 2.147.483.647 DECIMAL(x,y): decimal onde x é o número de dígitos e y o número de casas decimais CHAR(x): string de caracteres de tamanho fixo - até 254 DATE: data TIME:hora 17 5.2) Comando SELECT Sintaxe: SELECT <lista de atributos> FROM <nome das tabelas> WHERE <condição de pesquisa / filtro> - Selecionar o código e o nome das peças com código menor do que 100 SELECT Cod-Peça, Nome-Peça FROM Peça WHERE Cod-Peça < 100 - Selecionar todas as informações de todas as peças SELECT * FROM Peça 5.3) Alteração de Dados (DML) INSERT (Inserção) - Sintaxe 1 - Inserção Unitária: INSERT INTO <tabela> ( <lista-de-colunas>) VALUES ( <lista-de-valores>) - Inserir uma peça na tabela de peças INSERT INTO Peça VALUES (“P3”,”Biela”,1000) - Sintaxe 2 - Inserção em Massa: INSERT INTO <tabela1> (<lista-de-colunas>) SELECT ... UPDATE (Alteração) - UPDATE <tabela>> SET <coluna1> = <expressão1>, <coluna2> = <expressão2>, ... WHERE <condição-de-alteração> - Alterar o peso da peça P3 de 1000 para 500 UPDATE Peça SET Peso = 500 WHERE Cod-Peça = “P3” 18 - Alterar o peso das peças cujo nome começa com a letra “P” de 1000 para 500 UPDATE Peça SET Peso = 500 WHERE Nome-Peça LIKE “P%” DELETE (Exclusão) - DELETE FROM <tabela> WHERE <condição-de-exclusão> - Excluir a peça “P3” DELETE FROM Peça WHERE Cod-Peça = “P3” - Deletar as peças que pesam mais de 1000 gramas DELETE FROM Peça WHERE Peso > 1000 5.4) Funcionalidades do SQL (DML) Funções da Linguagem (Built-In): - AVG: média aritmética - SUM: soma de valores - MAX: valor máximo - MIN: valor mínimo - COUNT(*): contador de linhas da tabela - COUNT (DISTINCT atributo): contador de linhas com ocorrências diferentes de um atributo Operadores: - Comparação: =, <>, >, <, >=, <= - Lógicos: AND, OR, NOT - BETWEEN <expressão1> AND <expressão2>: testa intervalo - IN ( <lista de valores>): testa presença na lista - IS NULL: testa nulo - LIKE: testa conteúdo de string de caracteres 19 Montagem de Filtros Na claúsula WHERE, especificam-se as condições para seleção das linhas da tabela. Qualquer expressão lógica envolvendo os campos das tabelas é válida. Os campos que fazem parte da expressão WHERE não precisam necessariamente terem sido selecionados na expressão SELECT SELECT DEPTO, NOME, MATRICULA FROM FUNCIONARIOS WHERE SALARIO + COMISSAO >= 2000 Agrupamentos (GROUP BY) Em um SELECT tradicional, as linhas da tabela são exibidas de maneira analítica. Existe a expressão GROUP BY que permite que se faça uma consolidação dos registros, fazendo a síntese dos mesmos por um conjunto de campos. A funcionalidade do GROUP BY equivale a das informações de subtotais usadas em relatórios. Ao se fazer o agrupamento por um determinado campo de quebra, perde-se a informação detalhada a nível de registros. Novas informações são geradas a partir da totalização dos registros. Os campos da expressão GROUP BY devem sempre fazer parte da expressão SELECT. SELECT DEPTO, MIN (SALARIO) FROM FUNCIONARIOS GROUP BY DEPTO SELECT DEPTO, AVG (SALARIO) FROM FUNCIONARIOS GROUP BY DEPTO 20 Ordenação (ORDER BY) A expressão ORDER BY é utilizada quando se pretende exibir os registros em uma determinada ordem, seja esta crescente (ASC – default) ou decrescente (DESC). Caso a expressão não esteja presente, os registros serão exibidos na ordem em que foram inseridos na tabela. Os campos que constam da expressão ORDER BY devem obrigatoriamente estar presentes na expressão SELECT. Não é necessário possuir um índice fisicamente criado e composto pelos campos da ordenação para usar o ORDER BY. No entanto, caso o índice exista o comando será executado mais rápido. Pode-se utilizar números indicando que a ordenação será feita por determinado campo de acordo com a ordem do SELECT. SELECT NOME, DEPTO FROM FUNCIONARIOS ORDER BY NOME SELECT SALARIO, NOME FROM FUNCIONARIOS ORDER BY 1 DESC (Obs: nomes dos funcionários em ordem decrescente de salário) Contagem (COUNT) A função COUNT permite que se efetue a contagem de registros de uma tabela. A sua forma mais usual é o COUNT(*), onde se contam as linhas (ocorrências) de uma tabela. Existe também a forma COUNT (DISTINCT nome-do-campo) utilizada para a contagem de diferentes ocorrências de um campo. Neste caso, o campo não é chave primária, pois esta já tem as ocorrências distintas por obrigação. SELECT AVG(SALARIO), COUNT(*) FROM FUNCIONARIOS SELECT COUNT (DISTINCT CARGO) FROM FUNCIONARIOS (Obs: número de cargos distintos entre os funcionários) 21 Filtro de Agrupamento (HAVING) A expressão HAVING só pode aparecer depois da expressão GROUP BY, funcionando como um filtro para o agrupamento. Resumidamente, o HAVING é o WHERE do GROUP BY. Através do HAVING pode-se selecionar apenas os agrupamentos desejados que atendam determinadas condições. Os campos que fazem o filtro do HAVING não precisam necessariamente estar selecionado. SELECT DEPTO, COUNT (*) FROM FUNCIONARIOS GROUP BY DEPTO HAVING COUNT (*) > 5 (Obs: número de funcionários por departamento, mas apenas para os departamentos com mais de 5 funcionários) SELECT DEPTO, AVG(SALARIO) FROM FUNCIONARIOS GROUP BY DEPTO HAVING COUNT (*) > 2 (Obs: média salarial dos departamentos que tenham mais de 2 funcionários) Comparação de Padrões de Strings (LIKE) O operador LIKE é usado quando se deseja obter colunas de um registro que sigam um determinado padrão pré-especificado. Quando se quer saber os nomes de todos os funcionários cujo nome começa com JOAO ou termina com SILVA, usa-se o LIKE. O caracter % dentro da expressão LIKE tem a mesma função do caracter * no MS-DOS, assim como o _ (underscore) tem a semelhança com o ? do MS-DOS. SELECT NOME FROM FUNCIONARIOS WHERE NOME LIKE ‘JOAO%’ SELECT * FROM FUNCIONARIOS WHERE NOME LIKE ‘_ _ R%’ (Obs: a terceira letra do nome do funcionário deve ser R) 22 Distinção (DISTINCT) O operador DISTINCT nome-do-campo elimina ocorrências repetidas de um mesmo campo. Não faz sentido utilizar DISTINCT para um campo que já seja chave primária. SELECT DISTINCT DEPTO FROM FUNCIONARIOS SELECT DISTINCT CIDADE FROM CLIENTES (Obs: nomes das cidades onde se têm clientes, sem repetições de cidades) SELECT COUNT (DISTINCT DEPTO) FROM FUNCIONARIOS (Obs: número de departamentos da empresa) Pertinência (IN) O operador IN verifica se um elemento pertence a um conjunto, isto é, se um campo assume o valor de algum membro de uma lista de valores. É utilizado para substituir grandes expressões de OR para o mesmo campo. SELECT * FROM ORGANIZACAO WHERE DEPTO IN (10, 15, 20) (é bem mais legível do que) SELECT * FROM ORGANIZACAO WHERE DEPTO =10 OR DEPTO =15 OR DEPTO = 20 SELECT NOME, SALARIO FROM FUNCIONARIOS WHERE CARGO IN (‘ANALISTA’, ‘PROGRAMADOR’, ‘GERENTE’ ) 23 Intervalos (BETWEEN) O operador BETWEEN permite testar se um determinado campo assume o valor dentro de um intervalo especificado. É utilizado por ser mais prático do que o teste de >= e <=. SELECT * FROM FUNCIONARIOS WHERE SALARIO BETWEEN 1800 AND 2000 (é bem mais legível do que) SELECT * FROM FUNCIONARIOS WHERE SALARIO >= 1800 AND SALARIO <= 2000 Tratamento de Nulos (NULL) A palavra chave NULL é usada para representar valores nulos, o que tem significado diferente de branco ou zero. O nulo significa não se aplica, ou seja, o campo não assume nenhum valor. No momento da criação da tabela é que se define se o campo pode ou não aceitar nulos. SELECT NOME FROM FUNCIONARIOS WHERE COMISSAO IS NOT NULL (Obs: nome de todos os funcionários que recebem comissão) SELECT NOME, DEPTO, ANOS, SALARIO FROM FUNCIONARIOS WHERE DEPTO = 42 AND (ANOS IS NULL OR SALARIO BETWEEN 1000 AND 1500) 24 5.5) Exemplos de Recuperação de Dados (DML) 1- Informe o nome das peças que pesam mais de 1000 gramas SELECT Nome-Peça FROM Peça WHERE Peso > 1000 2 - Informe o código e o nome das peças que pesam 10, 20 ou 30 gramas SELECT Cod-Peça, Nome-Peça FROM Peça WHERE Peso IN (10, 20, 30) 3 - Informe o somatório dos pesos das peças cujo nome começa pela letra “P” SELECT SUM(Peso) FROM Peça WHERE Nome-Peça LIKE “P%” 4 - Informe todos os dados das peças que pesam mais de 1000 gramas e cujo nome tenha a letra “P” na segunda posição SELECT * FROM Peça WHERE Nome-Peça LIKE “_P%” AND Peso > 1000 5 - Informe o nome das peças que pesam entre 10 e 100 gramas ordenado pelo nome (em ordem ascendente) SELECT Nome-Peça FROM Peça WHERE Peso BETWEEN 10 AND 100 ORDER BY Nome-Peça ASC 6 - Informe o número de fornecedores por cidade SELECT Cidade, COUNT(*) FROM Fornecedor GROUP BY Cidade 7 - Informe o número de fornecedores por cidade para totais acima de 100 SELECT Cidade, COUNT(*) FROM Fornecedor GROUP BY Cidade HAVING COUNT(*) > 100 8 - Informe os nomes de todas as cidades que tem fornecedores (sem repetição de nome de cidade) SELECT DISTINCT Cidade FROM Fornecedor 25 5.6) Utilização de Várias Tabelas União (Union) - Agrega resultados de comandos SELECT. Deve existir compatibilidade de colunas e as linhas duplicadas são desprezadas. Equivale a operação de união da teoria dos conjuntos. Pode atuar em tabelas diferentes desde que a compatibilidade seja respeitada. É pouco utilizado na prática, pois geralmente se opta por fazer um único SELECT, mesmo que a sintaxe seja mais complexa. - SELECT Cod-Depto, Nome-Depto FROM Depto WHERE Local = “Rio” UNION SELECT Cod-Depto, Nome-Depto FROM Depto WHERE Local = “BH” - SELECT MATRICULA, NOME, DEPTO, ‘*’ FROM FUNCIONARIOS WHERE DEPTO = 42 UNION SELECT MATRICULA, NOME, DEPTO, ‘ ’ FROM FUNCIONARIOS WHERE DEPTO <> 42 (Obs: Exibe com * todos os funcionários do depto. 42) - SELECT MATRIC_TEMP, NOME, ‘BEM-VINDO’ FROM ENTREVISTAS WHERE POSICAO = ‘ADM’ AND (MONTH(DATA_ENTREV) = 09 OR MONTH(DATA_ENTREV) = 10) UNION SELECT MATRICULA, NOME, ‘PARABENS’ FROM FUNCIONARIOS WHERE ANOS = 5 ORDER BY 2 26 Junção (Join) - Implementado em SQL através do comando SELECT, especificando as ligações envolvidas na cláusula FROM e as condições de ligação na claúsula WHERE. É utilizado quando se pretende obter informações que estão presentes em 2 ou mais tabelas. A ligação entre as tabelas é feita através do relacionamento da chave primária com a chave estrangeira e é denominada condição de junção. - Pode-se utilizar apelidos (ALIAS) para os nomes das tabelas. Se um campo aparece nas 2 tabelas e é selecionado, é preciso informar de qual tabela o mesmo será exibido. - SELECT Nome-Func, Salário, Nome-Depto FROM Funcionário, Depto WHERE Funcionário.Cod-Depto = Depto.Cod-Depto (Obs: Cod-Depto é chave primária na tabela Depto e chave estrangeira na tabela Funcionário) - SELECT B.Cod-Depto, Nome-Func, Salário, Nome-Depto FROM Funcionário A, Depto B WHERE A.Cod-Depto = B.Cod-Depto - SELECT AVG(Salario) FROM Funcionario A, Depto B WHERE Nome-Depto = ‘Informatica’ AND A.Cod-Depto = B.Cod-Depto (Obs: salário médio do departamento de informática: o campo Salário está na tabela Funcionário e o campo Nome-Depto está na tabela Depto) 27 SUBSELECT (Sub-Consulta) - Corresponde a vários SELECTs aninhados, ou seja, SELECT dentro de outro SELECT. Os resultados de um SELECT são utilizados como valores pelo SELECT mais externo. * SUBSELECT sem Correlação - É o caso mais simples onde não existe ligação de colunas do SELECT mais externo com o SELECT mais interno. As junções que não exibem colunas de tabelas diferentes podem ser substituídas por SUBSELECTs. - SELECT Nome-Func, Salário FROM Funcionário WHERE Salário > (SELECT AVG(Salário) FROM Funcionário) - SELECT Nome-Func, Salário FROM Funcionário WHERE Cod-Depto IN (SELECT Cod-Depto FROM Depto WHERE Local = “Rio”) - SELECT B.Cod-Depto, Nome-Func, Salário, Nome-Depto FROM Funcionário A, Depto B WHERE A.Cod-Depto = B.Cod-Depto (Obs: Este JOIN não pode ser substituído por um SUBSELECT, pois campos de diferentes tabelas participam da expressão SELECT.) - SELECT AVG(Salario) FROM Funcionario A, Depto B WHERE Nome-Depto = ‘Informatica’ AND A.Cod-Depto = B.Cod-Depto é igual a: SELECT AVG(Salario) FROM Funcionario WHERE Cod-Depto IN ( SELECT Cod-Depto FROM Funcionario WHERE Nome-Depto = ‘Informatica” ) - SELECT NOME, DEPTO, SALARIO FROM FUNCIONARIOS WHERE DEPTO IN (SELECT NUMERO_DEPTO FROM ORGANIZACAO WHERE LOCAL = ‘ATLANTA’) 28 * SUBSELECT com Correlação - É o caso mais complexo onde existe ligação de colunas do SELECT mais externo com o SELECT mais interno. - SELECT Nome-Func, Salário FROM Funcionário A WHERE Salário > (SELECT AVG(Salário) FROM Funcionário B WHERE A.Cod-Depto = B.Cod-Depto) (Obs: nome dos funcionários que tem salário acima da média do seu depto.) - SELECT NOME, MATRICULA, DEPTO FROM FUNCIONARIOS X WHERE SALARIO + COMISSAO > (SELECT AVG(SALARIO + COMISSAO) FROM FUNCIONARIOS WHERE DEPTO = X.DEPTO AND MATRICULA <> X.MATRICULA) (Obs: funcionários que tem ganhos maiores que a média (calculada sem os respectivos) dos ganhos totais de seus departamentos. Cláusulas Adicionais (EXISTS, ANY, ALL) - EXISTS: testa a existência de linhas que resultariam do subselect. Pode ser substituído pelo IN. SELECT NOME, SALARIO FROM FUNCIONARIOS X WHERE EXISTS (SELECT * FROM ORGANIZACAO WHERE GERENTE = X.MATRICULA) (Obs: nome e salário dos gerentes) é igual a SELECT NOME, SALARIO FROM FUNCIONARIOS X WHERE MATRICULA IN (SELECT MATRICULA FROM ORGANIZACAO WHERE GERENTE = X.MATRICULA) 29 - ANY: também produz o mesmo efeito do IN, diferenciando-se pela sintaxe. SELECT NOME, MATRICULA FROM FUNCIONARIOS WHERE DEPTO = ANY (SELECT NUMERO_DEPTO FROM ORGANIZACAO WHERE DIVISAO = ‘LESTE’ ) É igual a SELECT NOME, MATRICULA FROM FUNCIONARIOS WHERE DEPTO IN (SELECT NUMERO_DEPTO FROM ORGANIZACAO WHERE DIVISAO = ‘LESTE’) - ALL: compara um elemento contra todos de seu conjunto. SELECT DEPTO, AVG (SALARIO) FROM FUNCIONARIOS GROUP BY DEPTO HAVING AVG(SALARIO) >= ALL (SELECT AVG(SALARIO) FROM FUNCIONARIOS GROUP BY DEPTO) (Obs: departamento com a maior média salarial entre todos deptos.) 30 Exemplos 1- Informe o código das peças que tem peso > 100 ou são fabricadas pelo fornecedor “F1” SELECT Cod-Peça FROM Peça WHERE Peso > 100 UNION SELECT Cod-Peça FROM Fornecimento WHERE Cod-Forn = “F1” 2 - Informe código, nome e quantidade fornecida das peças que são fabricadas pelo fornecedor “F1” , utilizando junção (Join) SELECT Cod-Peça, Nome-Peça, Qtde-Peças FROM Peça, Fornecimento WHERE Peça.Cod-Peça = Fornecimento.Cod-Peça AND Cod-Forn = “F1” 3 - Informe código e nome das peças que são fabricadas pelo fornecedor “F1”, utilizando sub-consulta (subquery) SELECT Cod-Peça, Nome-Peça FROM Peça WHERE Cod-Peça IN ( SELECT Cod-Peça FROM Fornecimento WHERE Cod-Forn = “F1” ) 4 - Informe o nome dos fornecedores que não fabricam a peça “P1” SELECT Nome-Forn FROM Fornecedor WHERE NOT EXISTS ( SELECT * FROM Fornecimento WHERE Fornecimento.Cod-Forn = Fornecedor.Cod-Forn AND Cod-Peça = “P1” ) 31 6) Administração de Banco de Dados Definição de Base de Dados em SQL (DDL): - Sintaxe: CREATE TABLE <nome da tabela> (lista de campos com definição de tipos e permissão p/nulos) PRIMARY KEY (lista de campos que formam chave primária) FOREIGN KEY (lista de campos que formam a chave estrangeira) REFERENCES <nome da tabela estrangeira> ON DELETE <condição de integridade referencial> IN <nome do espaço físico do banco de dados> - CREATE TABLE Peça ( Cod-Peça CHAR(2) NOT NULL, Nome-Peça CHAR(30) NOT NULL, Peso DECIMAL(7,2) NOT NULL ) PRIMARY KEY (Cod-Peça) - CREATE TABLE Fornecedor ( Cod-Forn CHAR(2) NOT NULL, Nome-Forn CHAR(30) NOT NULL, Cidade CHAR(30) NOT NULL) PRIMARY KEY (Cod-Forn) - CREATE TABLE Fornecimento (Cod-Peça CHAR(2) NOT NULL, Cod-Forn CHAR(2) NOT NULL, Qtde-Peças SMALLINT NOT NULL) PRIMARY KEY (Cod-Peça, Cod-Forn) FOREIGN KEY ( Cod-Peça) REFERENCES Peça ON DELETE RESTRICT FOREIGN KEY (Cod-Forn) REFERENCES Fornecedor ON DELETE RESTRICT 32 - CREATE TABLE Funcionarios (Matricula SMALLINT NOT NULL, Nome CHAR(9) NOT NULL, Depto SMALLINT, Cargo CHAR(5), Salario DECIMAL(7,2), Comissao DECIMAL(7,2) ) PRIMARY KEY (Matricula) FOREIGN KEY kdepto (Depto) REFERENCES Organizacao ON DELETE SET NULL) In dbspacename Visões (CREATE VIEW) A visão é uma tabela lógica que é montada dinamicamente a partir de um SELECT. Através da visão, consegue-se selecionar as linhas e colunas desejadas de uma tabela e dar um nome lógico (nome da visão) para o resultado. Com isso, os programas aplicativos ou usuários finais podem acessar a visão, simplificando a sintaxe dos comandos. As visões podem ser encadeadas, mas isto provoca uma queda de performance. Sintaxe: CREATE VIEW nome-da-visão (apelidos para os campos – opcional) AS SELECT CREATE VIEW SalarioDepto (Depto, Media_Salarial, Numero) AS SELECT Depto, AVG(Salario), COUNT(*) FROM Funcionarios GROUP BY Depto CREATE VIEW MaioresSalarios AS SELECT * FROM SalarioDepto WHERE Media_Salarial > 2000 (OBS: Pode-se criar uma visão de uma visão) 33 Índices (CREATE INDEX) Os índices são estruturas físicas de banco de dados criadas para otimizar a performance no acesso. Os comandos SELECT que envolvem ORDER BY ficam mais rápidos após a criação de índices pelos campos de ordenação. Para escolher bem os índices, deve-se analisar quais campos da tabela participam das expressões WHERE de comandos de SELECT, UPDATE e DELETE. No entanto, o uso excessivo de índices pode ser prejudicial a performance, pois todo comando que atualiza a tabela origem pode gerar uma alteração no índice. Os índices não são visíveis para o usuário, pois o algoritmo do otimizador do BD é que decide se deve ou não utilizá-los. Os índices geralmente são definidos em conjunto pelo DBA e pelo analista do sistema, que é quem conhece quais são as consultas mais críticas que evolvem um maior volume de acesso a dados. Os índices podem ou não ser únicos (UNIQUE). O índice é único quando não se permite repetições no conjunto de campos que compõem o índice. Assim sendo, o índice pela chave primária é sempre UNIQUE. Em alguns SGBDs este índice pela chave primária já é gerado automaticamente. CREATE UNIQUE INDEX xfuncionarios ON Funcionarios (Matricula) CREATE INDEX xsalario ON Funcionarios (Depto, Salario) Mudança de Tabelas (ALTER TABLE e DROP TABLE) O comando ALTER TABLE pode ser usado para acrescentar colunas numa tabela. A coluna é adicionada no final da tabela. O comando DROP TABLE elimina a estrutura da tabela e os registros da mesma. Em alguns SGBDs, ao se eliminar uma tabela, todas as estruturas relacionadas a mesma (visões, índices) são também excluídos automaticamente. ALTER TABLE Funcionarios ADD Aniversario DATE DROP TABLE Funcionarios 34 Segurança e Controle de Dados (GRANT e REVOKE) O banco de dados envolve armazenamento de informações estratégicas, e às vezes sigilosas, da organização. O aspecto segurança de dados relaciona qual usuário ou grupo de usuários tem privilégio de INSERT, DELETE, SELECT ou UPDATE em uma tabela ou visão. O privilégio de SELECT é o mais usual, sendo os outros mais restritos. Quando se deseja conceder todos os privilégios, a palavra chave ALL é utilizada. Quando se deseja conceder privilégios para todos os usuários, a palavra chave PUBLIC é utilizada. A sintaxe do comando GRANT é a seguinte: GRANT <lista de operações> ON <tabela ou visão> TO <usuário ou PUBLIC> GRANT SELECT, INSERT ON FUNCIONARIOS TO MARIA GRANT ALL ON FUNCIONARIOS TO CARLOS, ANTONIO GRANT SELECT ON ORGANIZACAO TO PUBLIC GRANT ALL ON FUNCIONARIOS TO PUBLIC (Obs: Concede privilégios para todos na tabela) O comando REVOKE tem o efeito oposto do GRANT, pois revoga privilégios já concedidos. Cabe ao DBA em conjunto com o analista de sistema e o usuário gestor do sistema estabelecer a política de privilégios. A sintaxe do comando REVOKE é a seguinte: REVOKE <lista de operações> ON <tabela ou visão> FROM <usuário ou PUBLIC> REVOKE SELECT, INSERT ON FUNCIONARIOS FROM MARIA, CARLOS REVOKE ALL ON FUNCIONARIOS FROM PUBLIC (Obs: Retira privilégios de todos na tabela) 35 7) SGBD Microsoft SQL Server No SGBD SQL Server, antes de se criar fisicamente os bancos de dados e tabelas, é preciso definir os dispositivos físicos (‘devices’) onde os mesmos serão armazenados. “Devices” são arquivos do sistema operacional usados para armazenar bancos de dados, logs de transações de banco de dados, bem como backups. Um “device” pode conter vários BDs e um BD (“database”) pode ser armazenado em vários “devices” que podem estar inclusive em diferentes discos rígidos. No entanto, por uma questão de organização, a maior parte das empresas opta por criar 1 “device” para cada BD, facilitando assim o trabalho do DBA. Existem 2 tipos de “devices”: “database devices” e “dump devices”. Os “devices” de BD armazenam BD e log de transações, podendo ser criados fisicamente em discos rígidos. Já os “dump devices” são utilizados para armazenar backups de BDs e logs, podendo ser criados em discos rígidos, disquetes e fitas. Somente o administrador do sistema (usuário System Administrator – sa) pode criar “devices”. Após a instalação do SQL Server, os seguintes “devices” são criados: MASTER: usado pelos BDs master (catálogo do BD), model (BD com os padrões), tempdb (BD temporário) e pubs (BD exemplo) MSDBDATA e MSDBLOG: usado pelo BD msdb (BD de programação de eventos de alerta, backups e tarefas) e pelo log do msdb “Device de dump”: DISKDUMP Um “device” tem um nome lógico usado para referências e um nome físico que indica o caminho do arquivo .DAT do sistema operacional. Por exemplo, poderíamos criar o “device” com o nome lógico Vendas e o nome físico C:\MSSQL\DATA\VENDAS.DAT. Na maior parte das vezes quando se cria o “device” que irá conter um BD, é feita também a criação do “device” que irá conter o log de transações. O log tem usalmente de 10 a 25% do tamanho do BD, dependendo do volume de atualizações do mesmo. Quanto mais estável o BD, menor deve ser o seu log. Colocando o BD e o log em “devices” distintos, consegue-se efetuar backup do log separadamente, além de otimizar a performance. O tamanho mínimo de um “device” é de 1 MB. Após a criação, um “device” pode ser aumentando, dependendo somente da disponibilidade de espaço em disco. 36 Uma vez criado o “device” pode-se partir para a criação do BD através do comando CREATE DATABASE, que possui a seguinte sintaxe: CREATE DATABASE database_name [ON {DEFAULT | database_device} [= size] [, database_device [= size]]...] [LOG ON database_device [= size] [, database_device [= size]]...] onde database_name: nome do BD database_device: nome lógico do(s) device(s) onde o BD será criado size: tamanho do BD em MB LOG ON: nome lógico do(s) device(s) que irão conter o log do BD Ex: CREATE DATABASE Vendas ON Dev_Vendas = 20 LOG ON Log_Vendas = 2 Após a criação do DATABASE, pode-se finalmente criar as tabelas. O comando CREATE TABLE do SQL Server tem uma sintaxe um pouco diferente do SQL padrão. CREATE TABLE [database.[owner].]table_name ( {col_name column_properties [constraint [constraint [...constraint]]] | [[,] constraint]} [[,] {next_col_name | next_constraint}...] ) onde constraint = restrições que a tabela possui, incluindo chave primária, unicidade de campos, default de campos e verificação de consistências. Toda restrição (“constraint”) deve possuir um nome para controle interno do SQL. Para uma PRIMARY KEY constraint: garante a integridade de entidade. Todas as colunas participantes de uma chave primária devem ser NOT NULL. O SQL Server cria automaticamente um índice único (UNIQUE) para a chave primária. Se nenhum tipo de índice é especificado, o default é CLUSTERED, onde os registros serão armazenados fisicamente conforme a ordem da chave primária. Uma tabela só pode possuir um índice CLUSTERED. [CONSTRAINT constraint_name] PRIMARY KEY [CLUSTERED | NONCLUSTERED] (col_name [, col_name2 [..., col_name16]]) 37 Para uma UNIQUE constraint: como uma tabela possui somente uma chave primária, as chaves alternativas ou candidatas que sejam únicas são implementadas através desta restrição. O SQL Server cria automaticamente um índice único (UNIQUE) para a restrição UNIQUE. Se nenhum tipo de índice é especificado, o default é NON CLUSTERED. [CONSTRAINT constraint_name] UNIQUE [CLUSTERED | NONCLUSTERED] (col_name [, col_name2 [..., col_name16]]) Para uma FOREIGN KEY constraint: um valor não nulo informado na(s) coluna(s) deve existir na claúsula REFERENCES e a tabela referenciada deve possuir uma restrição de PRIMARY KEY ou UNIQUE. Esta restrição de chave estrangeira não cria índices automaticamente. [CONSTRAINT constraint_name] [FOREIGN KEY (col_name [, col_name2 [..., col_name16]])] REFERENCES [owner.]ref_table [(ref_col [, ref_col2 [..., ref_col16]])] Para uma DEFAULT constraint: especifica o valor default que será gravado em uma coluna quando o valor do campo não for informado no momento do INSERT. [CONSTRAINT constraint_name] DEFAULT {constant_expression | niladic-function | NULL} [FOR col_name] Para uma CHECK constraint(s): especifica a validação do domínio do campo. [CONSTRAINT constraint_name] CHECK (expression) Ex: CREATE TABLE Funcionario ( Matric INT NOT NULL, Nome CHAR(30) NOT NULL, Salario MONEY NOT NULL, Cargo CHAR(15) DEFAULT “Analista”, Estado CHAR(2) NOT NULL, Idade SMALLINT NOT NULL, Cod_Depto SMALLINT NULL, CONSTRAINT chavefunc PRIMARY KEY CLUSTERED (Matric), CONSTRAINT uniconome UNIQUE NONCLUSTERED (Nome), CONSTRAINT estfunc FOREIGN KEY (Cod_Depto) REFERENCES Departamento (Cod_Depto), CONSTRAINT checkestado CHECK (Estado IN (‘MG’, ‘RJ’, ‘SP’)) ) 38 A sintaxe do comando de criação de índices (CREATE INDEX) do SQL Server segue o SQL padrão. Os índices são criados para melhorar a performance dos SELECTs e garantir a unicidade de campos (índices UNIQUE). A otimização do tempo de resposta de um BD depende muito da habilidade em se saber criar os índices adequados. No entanto, a construção e controle dos índices requer tempo, espaço adicional em disco e “overhead” nas operações de INSERT, DELETE e UPDATE. Portanto, os índices são criados usualmente para as chaves primárias e para as chaves estrangeiras, visando agilizar os comandos que envolvem junção de tabelas. Colunas muito usadas em claúsulas WHERE também são boas candidatas para índices. O índice deve ser o mais seletivo possível. Por exemplo, não se deve criar um índice para o campo Sexo, pois o mesmo só apresenta 2 valores. A sintaxe do comando CREATE INDEX é a seguinte: CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX Nome-do-índice ON tabela (coluna ou lista-de-colunas) 39 8) Mercado de Banco de Dados Relacionais Os SGBDs relacionais dominam hoje o mercado de banco de dados. Podemos relacionar vários fornecedores: - IBM . DB2/2 para o OS/2 e Windows NT . SQL/400 para o OS-400 (máquina AS-400) . DB2 para AIX (máquina RISC 6000) . SQL/DS para VM e VSE (mainframe) . DB2 para MVS (mainframe) - Oracle . Ambientes: UNIX, MVS, VM, DOS/Windows, OS/2, Netware e Windows NT - Digital . RDB para VAX/VMS - Informix . Ambiente Unix e Windows NT - Sybase . SQL Server para Unix, Windows NT e VAX/VMS - Ingres . Ambiente Unix, VAX/VMS e OS/2 - Microsoft . SQL Server para Windows NT 40 9) Integridade Referencial Regras de Integridade Integridade de Entidade: nenhuma tupla participante de uma chave primária de uma relação pode ter valor nulo. Toda tupla representa uma entidade que deve ser identificável, portanto a chave primária não pode conter atributos com valores sem identificação. Integridade Referencial: se existe uma chave estrangeira em uma relação R1, que corresponde a uma chave primária em uma relação R2, cada valor da chave estrangeira em R1 deve ser: - Igual ao valor de chave primária em alguma tupla de R2 ou, - Nulo. Ex: Se existir um gerente para um departamento, deve existir o empregado que seja o gerente. Departamento ( 20, “Contabilidade”, 100 ) Funcionário ( 100, “Alexandre”, 3000 ) Pode existir um departamento sem gerente: Departamento ( 20, “Contabilidade”, NULL ) 41 10) Bibliografia - Date, C.J. Introdução a Sistemas de Banco de Dados. Editora Campus. - Neto, Acácio Feliciano. Engenharia da Informação. McGraw Hill Editora. - Hackathorn, Richard D. Conectividade de Bancos de Dados Empresariais. IBPI Press. - Salemi, Joe. Bancos de Dados Cliente/Servidor. IBPI Press. - Korth,Henry e Silberchartz,Abraham. Sistema de Banco de Dados. McGraw Hill Editora. 42