Bases de dados e tabelas

Bases de dados

Uma base de dados pode ser definida como um conjunto estruturado de dados armazenados num suporte informático, de uma forma acessível à consulta e manipulação por parte dos utilizadores.

O software que permite criar e/ou gerir uma base de dados costuma ser designado por SGBD – Sistema de Gestão de Bases de Dados.

Um SGBD é concebido para poder implementar bases de dados segundo um determinado modelo. Desde a década de 80 que o modelo de bases de dados mais difundido e utilizado nos sistemas de informação é o modelo relacional.

O modelo relacional foi criado por um grupo de trabalho dirigido por Edgar Codd, cerca de 1970. Neste modelo a estrutura básica é a tabela – que é vista como uma relação de dados.

Tabelas

Uma tabela é uma estrutura de dados formada por:

  1. Um conjunto de colunas, campos ou atributos (tudo sinónimos),
  2. Um conjunto de linhas, registos (ou ainda tuplos, na linguagem do modelo relacional).

Como é fácil constatar, uma tabela é uma estrutura de dados para armazenar informação sobre uma entidade ou classe.

Na verdade, quando falámos de entidades (Diagramas ER) e de classes (Diagramas de Classes), já tínhamos visto que tanto umas como outras vão, em princípio, dar origem a tabelas de bases de dados.

Atributos e campos

Vimos que uma classe é formada por atributos. Vimos também que um atributo é uma propriedade ou característica de uma entidade que nos interessa registar numa base de dados.

Nas bases de dados do modelo relacional, os atributos correspondem às colunas de uma tabela que também costumam ser designados por campos.

Na figura acima, a tabela Alunos contém o seguinte conjunto de campos: N_Aluno, Nome e Localidade.

Registos

Por sua vez, as linhas de uma tabela correspondem a registos. Por outras palavras, um registo é constituído por um conjunto de dados (atributos ou campos) relativos a uma entidade singular ou um objeto.

Por exemplo, na tabela Alunos da figura acima, o conjunto de dados (3, Carla, Coimbra) é um registo dessa tabela.

Dominios dos atributos

Um outro conceito muito importante que está relacionado com cada atributo ( ou campo) de uma tabela é o de domínio.

O domínio de um atributo (ou campo de uma tabela) corresponde aos valores ou tipos de dados que esse atributo (ou campo) pode assumir.

Por exemplo, na figura acima, no campo N_Aluno, o domínio corresponde aos números inteiros que podem ser atribuídos aos alunos.

Por sua vez, o campo Nome tem como domínio o conjunto dos nomes possíveis, que são strings.

O campo Localidade tem como domínio o conjunto dos nomes possíveis de localidades que também são strings.

Como se pode concluir, os domínios são importantes para a definição da estrutura de uma tabela, pois têm a ver com os tipos de dados com que um sistema informático e um SGBD podem trabalhar, tais como: inteiros, reais, datas, strings, etc..

Tabelas em bases de dados relacionais

Chave primária e chaves candidatas

No modelo relacional, para que uma tabela esteja bem definida deve, em princípio, ter uma chave primária.

Uma chave primária é um atributo ou conjunto de atributos que permite identificar, de forma unívoca, cada registo numa tabela, sendo selecionado para esse efeito entre as possíveis chaves candidatas.

Uma chave candidata é um atributo ou conjunto de atributos que permite identificar de forma unívoca cada registo numa tabela.

Os dois conceitos são semelhantes. A única diferença é que a chave primária é selecionada entre as chaves candidatas para desempenhar essa função de identificar de forma unívoca cada registo numa tabela.

Considere-se a imagem acima:

Para que um atributo possa ser considerado chave candidata, não pode conter dados repetidos em diferentes registos (linhas da tabela) . Só assi, pode identificar de forma única cada registo.

Na tabela Alunos, os atributos que podem ser considerados chaves candidatas são: N_Aluno e Nome. Localidade não pode porque apresenta dados repetidos.

Entre as duas chaves candidatas da tabela Alunos (N-Aluno e Nome), a melhor opção para chave primária é N_Aluno, pois cada aluno terá um numero único. O atributo Nome não é tão seguro quanto a esse aspeto, já que é possível surgirem nomes idênticos para alunos diferentes.

Na tabela Artigos,  tal como está apresentada, temos apenas uma chave candidata: Designação.

Os outros campos apresentam dados que se repetem: logo não podem ser chaves candidatas.

Mas, mesmo o campo Designação não oferece garantias de não conter repetições para certos produtos.

Em situações como esta, é prática usual  criar um campo que ofereça essa garantia. Por exemplo, na tabela Artigos, podemos incluir um campo com um código para o produto (CodArtigo ou algo semelhante), geralmente com um numero inteiro sequencial, e, então, será esse campo a chave primária da tabela.

Formas de representar uma tabela numa base de dados relacional

Há mais do que forma de representar tabelas. Até agora representámos tabelas na forma de um conjunto de colunas por um conjunto de linhas. Essa forma de representar tabelas é conhecida por vista de folha de dados.

Na figura abaixo representamos uma tabela no formato vista de estrutura. Neste caso trata-se da vista de estrutura do MS Access.

Na figura abaixo temos uma tabela na vista de estrutura definida tecnicamente. Esta forma de representar uma tabela é usada na fase de desenho da base de dados antes dela ser implementada:

Neste caso, temos apenas as definições técnicas dos campos da tabela sem a visualização dos dados.

Cada campo da tabela tem, o nome do capo seguido do seu tipo de dados, bem como outras informações importantes como, se é chave primária, se é um campo de preenchimento obrigatório, se tem valores de defeito, se tem valores opcionais, etc..

Por exemplo, o campo Numero, está indicado como sendo do tipo Integer (inteiro) e <<PK>> que significa Primary Key, ou chave primária.

No campo Sexo, o seu tipo de dados é Char (caractere) e são explicitadas as únicas opções aceitáveis: [‘M’ | ‘F’], M ou F.

Há ainda uma outra forma de representar uma tabela, muito usada,  a forma analítica, que é uma forma simplificada da vista de estrutura:

A tabela Socios seria representada da seguinte maneira, na forma analítica:

Socios(Número, Nome, Sexo, DataNascimento, Morada)

Neste caso, indica-se o nome da tabela, seguido da lista de atributos ou campos dentro de parenteses curvos. O facto de o campo Numero estar sublinhado indica que se trata da chave primária desta tabela.

Relacionamentos entre tabelas

As bases de dados relacionais raramente consistem numa só tabela. O grande sucesso do modelo relacional, deve-se ao facto de podermos combinar, numa só base de dados, uma multiplicidade de tabelas.

Recordemos que os Diagramas ER ou de classes se caracterizam por nos mostrarem como as entidades ou classes podem relacionar-se entre si.

Consideremos, por exemplo, a figura abaixo que mostra a situação de uma empresa que comercializa um conjunto de artigos (tabela Artigo) que compra aos seus fornecedores (tabela Fornecedor):

Num Diagrama de Classes, o relacionamento entre as duas classes (tabelas) pode ser representado como se pode ver na imagem abaixo:

A questão que agora se coloca é : como é que esse relacionamento se traduz para uma base de dados relacional ?

Podemos ver que esse relacionamento, na base de dados relacional, se traduz da seguinte maneira:

Na tabela Artigo, foi incluído um campo, CodForn, que corresponde *a chave primária da tabela Fornecedor. Nesse campo são registados os códigos correspondentes ao fornecedor.

Numa situação como esta estamos perante o que se chama uma chave estrangeira (FK – Foreign Key).

Uma chave estrageira é um campo “importado” para uma tabela, sendo chave primária na tabela de origem.

Consideremos como tabela principal aquela que contém a chave primária a ser importada (no nosso exemplo é a tabela Fornecedor). Consideremos agora, como tabela relacionada aquela que recebe a importação da chave primária, que nesta tabela que a recebe passa a ser chamada de chave estrangeira.

Às vezes, o relacionamento entre duas tabelas passa por uma terceira tabela de associação.

Consideremos, por exemplo, a situação de uma empresa como a figura abaixo:

Nesta empresa, os empregados estão ligados aos departamentos da empresa na seguinte relação:

Cada empregado pode trabalhar em zero ou mais departamentos (0..*) e cada departamento pode ter um ou vários empregados (1..*). Trata-se de uma relação muitos-para-muitos (*..*).

Nesta situação, não funciona importar a chave primária da tabela principal, (neste caso Departamento) para a outra tabela (neste caso, Empregado).

Não podemos, simplesmente, colocar na tabela Empregado o código do Departamento, pois pode haver empregados que não ligados a nenhum departamento e, além disso, interessa registar os vários departamentos por onde o empregado passa.

Em situações como esta a solução passa por uma tabela de relacionamento ou de associação.

No nosso exemplo, criámos uma tabela com o nome Depart_Empreg para relacionar as duas tabelas principais (Departamento e Empregado).

Na tabela Depart_Empreg incluímos os seguintes campos:

  • CodDep: que é a chave primária da tabela Departamento e, portanto, funciona aqui como chave estrangeira.
  • CodEmp: que é a chave primária da tabela Empregado e, portanto, também funciona aqui como chave estrangeira.

Desta forma, cada registo que entrar na tabela Depart_Empreg, terá de incluir um dado de CodDep da tabela Departamento e um dado de CodEmp da tabela Empregado.

Repare-se que a chave primária desta tabela Depart_Empreg tem de ser composta por estes dois campos em simultâneo: CodDep e CodEmp. Só estes campos em conjunto é que identificam de forma unívoca cada registo da tabela Depart_Empreg.

Integridade da informação numa base de dados relacional

O modelo relacional obriga a que as operações de atualização numa base de dados decorra de forma consistente.

A manutenção da consistência ou integridade numa base de dados deve ser assegurado pelo SGBD.

Uma base de dados relacional deve assegurar dois tipos de integridade:

  1. Integridade de entidade
  2. Integridade referencial

A integridade de entidade impõe que os valores dos campos que compõem a chave primária não podem ser nulos nem iguais a outros já existentes na tabela. Por outras palavras, a chave primária não pode ser nula nem estar repetida.

A integridade referencial impõe que um valor de uma chave estrangeira exista obrigatoriamente como um valor da chave primária da tabela relacionada com aquela chave estrangeira.

Podemos verificar a violação desta regra na figura abaixo:

Existe um registo na tabela Encomendas em que o valor da chave estrangeira CodArtigo(155)  não existe como chave primária na tabela Artigos. O mesmo se passa com a chave estrangeira CodCliente em que existe um registo com o valor C130 que não existe na chave primária da tabela Clientes.

Por outro lado, para garantir que a integridade da base de dados não é comprometida, se pretendermos eliminar, por exemplo, o registo da tabela Clientes com a chave primária C101, o SGBD não permite e dá origem a um erro porque essa chave (C101) está referenciada numa chave estrangeira de um registo da tabela Encomendas.