Estruturação de uma Base de Dados
Por Vitor Lopes para o PPLWARE.COM
Apesar de actualmente se poder encontrar muita informação sobre o tema em questão disponível na internet, resume-se no seguinte artigo alguns pontos fulcrais para a estruturação de uma base de dados, contribuindo assim para a resolução de possíveis e eventuais dúvidas que possam surgir relacionadas com o tema.
Durante o desenrolar deste artigo irão ser só abrangidos os pontos que na minha opinião são os principais e os mais importantes, para que qualquer pessoa possa adquirir o mínimo indispensável das bases necessárias para dar os primeiros passos e ir progredindo por si próprio.
Modelo Entidade-Relação
É um modelo que permite representar em forma de diagrama, auxiliando assim a sua visualização, o relacionamento das várias entidades e respectivos atributos de uma base de dados.
- Entidades
Existem várias definições, mas de uma forma geral chega-se a um consenso comum, em que uma entidade pode ser um conjunto de elementos sobre os quais se pretende guardar informação.
Exemplo: Cliente, Fornecedor, Funcionários, Alunos, Professores, etc…
Informação essa que devidamente tratada e organizada, dá origem aos atributos ou campos de uma entidade.
Exemplo: Id, Nome, Morada, Telefone, Telemóvel, Email, etc…
- Relações
Existem 3 tipos de relações:
1.1 para 1
Tal como o nome indica uma relação do tipo 1 para 1, é uma relação em que a uma ocorrência da tabela A, corresponde uma e só uma ocorrência da tabela B e vice-versa.
Exemplo: Uma pessoa só pode ter um número de BI, e um BI só pode pertencer a uma pessoa.
Numa relação do tipo um para um, cabe ao “criador” do modelo entidade-relação a escolha de qual a tabela que irá receber a chave estrangeira.
2. 1 para N (em que N significa vários)
Uma relação do tipo 1 para n, é uma relação de um para vários, ou seja, entre duas tabelas A e B, a uma ocorrência da tabela A podem corresponder várias ocorrências da tabela B, enquanto que a uma ocorrência da tabela B corresponde só uma da tabela A.
Exemplo: Um leitor pode fazer várias requisições, mas uma requisição só pode ser feita por um leitor, quer isto dizer que entre a tabela Leitor e a tabela Requisições existe uma relação do tipo 1 para n.
A chave principal é adicionada ao lado que tem n, transformando-se assim numa chave estrangeira.
3. N para M (em que N e M significam vários)
Uma relação do tipo n para m, é uma relação de vários para vários, ou seja, entre duas tabelas A e B, a várias ocorrências da tabela A podem corresponder várias ocorrências da tabela B, e vice-versa.
Exemplo: Uma moeda pode ser emitida durante vários anos, mas um ano pode emitir várias moedas, quer isto dizer que entre a tabela Moeda e a tabela Ano existe uma relação do tipo n para m.
Para toda e qualquer relação do tipo n para m, há que decompor a relação em duas do tipo 1 para n, ou seja, irá ser necessário criar uma nova tabela, com o nome que o “criador” do modelo entidade-relação bem entender, onde a mesma irá conter as chaves principais das tabelas envolvidas, chaves estas que se irão tornar numa chave composta da nova tabela.
Decomposição final:
Exemplo pratico: Aplicação para gestão de stocks de consumíveis de impressoras
Para o exemplo seguinte irá ser utilizada a ferramenta de desenvolvimento access, pois para além de bastante conhecida, é também bastante utilizada e é na minha opinião ideal para dar os primeiros passos no desenvolvimento e estruturação de uma base de dados.
Como se poderá constatar a aplicação poderá ser “melhorada”, mas por motivos de simplificação, irão ser só utilizados os “requisitos mínimos” para dar início ao desenvolvimento da aplicação, ficando ao critério de cada um como proceder de acordo com as suas necessidades.
A primeira coisa a fazer antes de criar as tabelas, é definir o conjunto de elementos e respectivos atributos para os quais interessa guardar informação, que após o devido tratamento e organização da mesma e já com os critérios das relações devidamente aplicados é:
- Stock (Id_Stock, Referência, Descrição, Quantidade armazenada, Data de actualização)
- A Entidade Stock diz respeito aos produtos em armazém, irá também servir para registar novas entradas e saídas de produtos.
- Saidas (Id_Requisição, Id_Departamento, Id_Stock, Data_Saida, Descrição, Quantidade, Impressora, Recebimento)
- A Entidade Saidas serve para registar as requisições de consumíveis, que á posteriori irá servir como base para alterar/registar saídas de produtos da tabela Stock.
- Departamento (Id_Departamento, Departamento);
- Guias_Remessa (Id_Guia, Nr_Guia, Total, Data_Entrada);
- Linhas Guias Remessa (Id_Linha, Id_Guia, Id_Produto, Referência, Descrição, Quantidade);
Após a conclusão do levantamento da informação necessária, pode-se então passar ao segundo passo que implica a criação das tabelas.
Tabela Departamentos
Como se pode verificar o tipo de dados do campo Id_Departamento está como numeração automática, mas também poderia estar só como número, a diferença entre um e outro é que no tipo numeração automática, não é necessário estar constantemente a preencher o campo Id, enquanto que com o tipo número tem que se ir preenchendo o mesmo.
O campo Departamento está como texto, pois irá só servir para guardar o nome dos departamentos existentes.
Tabela Stock
Como já foi referido anteriormente, a tabela stock irá servir para guardar os registos dos produtos em armazém, onde o campo Referência serve para guardar a referência do produto por exemplo “HP43”, e o campo Descrição serve para registar neste exemplo “tinteiro”.
O campo quantidade irá servir para guardar a informação relativa á quantidade de produtos existentes em armazém, sendo também alterado de acordo com as entradas e saídas de produtos.
O campo Data Actualização serve para registar quando foi a última vez que a tabela Stock foi alterada, seja pela entrada e saída de novos produtos, seja por inventário.
Tabela Saídas
Como também já foi referido anteriormente, a tabela Saídas, serve para registar as requisições ou saídas de consumíveis para os vários departamentos. Tal como o nome indica o campo Data_Saida, serve para registar a data em que foi feita a requisição/ou a data em que um funcionário do departamento “requisitante” foi levantar o consumível, ficando o seu nome no campo Recebimento.
O campo Id_Stock serve para identificar a informação relativa ao consumível requisitado, enquanto que o campo Descrição serve para registar a referência e o tipo de produto requisitado.
O campo Impressora para além de servir para identificar o tipo de consumível caso o funcionário requisitante não o saiba identificar, serve também para se saber quantas e quais são as impressoras existentes por departamento.
Tabela Guias Remessa
Tal como está explicito a tabela Guias Remessa, serve para guardar o número da guia recebida, o valor a pagar (Total), e a data em que a guia foi recebida.
Tabela Linhas Guias Remessa
A tabela Linhas Guias Remessa serve para guardar os detalhes das guias de remessa recebidas.
Após a conclusão da criação das tabelas, dá-se então inicio á criação das relações entre as mesmas.
Relacionamento entre Tabelas
Como se pode verificar o esquema final de um modelo entidade relação deverá ser algo deste género, dependendo do tipo de base de dados a ser desenvolvida, e do número de tabelas que a mesma tiver.
Uma vez que os tipos de relações já foram referidos anteriormente, resta só referir uma breve explicação do raciocínio utilizado para a criação deste modelo:
- Um departamento pode fazer várias requisições, mas uma requisição só diz respeito a um departamento, logo é uma relação do tipo 1 para n;
- Um produto em stock pode ser requisitado várias vezes, mas para uma requisição só pode corresponder um produto, logo é uma relação do tipo 1 para n;
- Entre Guias Remessa e Stocks existia uma relação do tipo n para m, ou seja, uma guia de remessa pode incluir vários produtos, e um produto pode corresponder a várias guias, logo criou-se a tabela Linha Guias Remessa para decompor a relação em duas do tipo 1 para n, ou seja, uma guia de remessa pode ter várias linhas de remessa, e um produto em stock pode ser abastecido por várias linhas de remessa.
Espero que este artigo seja uma mais valia tanto para a comunidade, como para qualquer outro visitante, e que possa contribuir para ajudar a resolver toda, e qualquer possível e eventual dúvida que possa surgir.
Este artigo tem mais de um ano
5* Manuel
Dúvida. A imagem “imagem_estruturacao_bd10.jpg” é feita com??
Abraço,
Miguel Goyanes
É mesmo o access =)
search “database improvement solution”, primeira do google.
cumpz
Pelo que me parece SQL Server.
SQL Server???? LOL bouuuaaaaa!
Miguel Goyanes, é feita no access no separador “ferramentas da base de dados” em “Relações”.
O Sql server nos diagramas é parecido com isto.
Caro Miguel,
Agradeço os seus agradecimentos, mas os créditos vão para o nosso amigo Progster.
A imagem a que te referes é feita com Microsoft Access.
Cumprimentos,
Manuel Rocha
Lol…
No Problem
parece-me que é com o micro$oft access
Boa tarde.
A imagem em questão foi feita em Access.
Cumprimentos.
Microsoft Office Access (2003/2007/2010)
Muitos parabéns sobre o artigo, muito completo e de fácil compreensão.
Ainda hoje, apanhei uma seca com alguns dos conteúdos apresentados acima que com este artigo era muito simples de entender.
Obrigado.
bom artigo e de fácil compreensão, os meu parabéns
espero ver mais vezes assim pequenos tutoriais sobre diversos temas, boa pplware
João, esta pagina foi dada em 2 ou 3 aulas e ainda vem mais! grande seca que apanhamos lool
Obrigado BR.
Belo Artigo , esta penando em tornar isso um manue, assim como foi o de sql?
Belo Artigo , esta pensando em tornar isso um manual, assim como foi o de sql?
Boa tarde.
É uma ideia a considerar. Aceitam-se sugestões relacionadas com o tema, das quais de acordo com a disponibilidade, podem vir a ser implementadas.
Cumprimentos.
Qual o link para o manual do SQL?
Obrigado
Boas…
Não sendo eu especialista em bases de dados, recomendaria alguma prudência aos mais “novos” na utilização de relações 1-1.
Bem sei que o exemplo apresentado serve apenas para ilustrar o conceito, mas mesmo assim já dá para levantar alguns problemas deste tipo de relações.
O principal cuidado a ter com este tipo de relações é que apenas devem ser consideradas quando de facto o item da tabela “forasteira” for obrigatório, isto é, se for obrigatoriamente necessário uma Pessoa ter BI…
Caso contrário, levaria a que houvesse uma chave forasteira a NULL (poderia ser criado um registo de default, mas… 🙁 ).
Exemplo concreto: Pegando no mesmo exemplo, poderíamos tentar fazer o mesmo para o NIF (Numero de Identificação Fiscal), mas a verdade é que é possível ser Pessoa durante muitos anos sem que tenha que ter um NIF… pelo que na nossa tabela teríamos uma chave forasteira a NULL…
Salvo raras excepções, em que por questões de desempenho é absolutamente necessário “normalizar” uma tabela de modo a dar origem a uma relação 1-1, na generalidade dos casos mais vale ter esses dados na tabela “principal”, neste caso, na tabela Pessoa.
Mais informações sobre este tipo de relações aqui: http://stackoverflow.com/questions/517417/is-there-ever-a-time-where-using-a-database-11-relationship-makes-sense
Cumprimentos e espero ter ajudado!
Gilito
Viva Gilito,
Realmente o reparo é de ter em consideração, mas neste caso o que se pretende é mesmo ilustrar a relação para que a pessoa perceba. Penso que a situação que descreves daria outro post que viria complementar este, tipo Parte 2.
No entanto, penso que o nosso amigo Progster pode escrever algo nesse aspecto.
Cumprimentos,
Manuel Rocha
Boa noite.
A uma pessoa pertence só um, e um só BI, e o mesmo se aplica ao NIF.
Fica é ao critério de cada um a escolha de qual entidade recebe a chave estrangeira.
Cumprimentos.
Nunca entendi bem essa relação, sendo assim bastava dizer que o bi é um campo da tabela/entidade pessoa.
Isso dependerá do dados que quiseres guardar… Se quiseres guardar só o nº de BI, era capaz de ser o mais fácil. O “problema” existiria se quisesses guardar mais dados relativos ao BI (arquivo, data de validade, data de emissão, etc). Aí já faria sentido criar uma tabela de BIs com a toda a informação relativa aos mesmos, pois manterias a arquitectura da base de dados normalizada (3ª forma normal).
Corrijam-me se estiver errado… 🙂
Viva João,
A tua interpretação está correcta. No entanto, se separarmos o BI da tabela de pessoa podemos fazer um indexação a esse mesmo campo e torna-se mais rápido para realizar pesquisas, sendo que depois só necessitamos retornar a linha correspondente aquela chave.
Todavia não é de todo errado colocares na mesma tabela mas podes comprometer a performance das queries.
Há quem coloque inclusivé cada parte do nome separadas por várias tabelas pela mesma razão do descrito. Enfim, são opiniões, não podemos dizer que esta forma está errada assim como também não podemos dizer que a tua também está, mas tudo vai por questões de performance. Eu colocaria como tu dizes mas se visse uma base de dados com um relacionamento destes também não questionava.
Cumprimentos,
Manuel Rocha
Concordo plenamente que qualquer abordagem estaria correctas…No entanto creio que tudo depende realmente do que se quer atingir…Como já foi dito aqui mesmo pelo Progster: “Fica ao critério de cada um dependendo das suas necessidades”..
Creio que não se pode centrar o facto de decisão apenas em performance… Sim, tem um grande peso, sem duvida… Mas não se poderia criar mais um “index” na coluna especifica se estivesse na mesma tabela?
Abraço!
Obrigado pelo esclarecimento, fiquei a perceber a ideia.
Boa noite.
Sim, penso que se pode aceitar essa afirmação, mas também podem ocorrer situações em que é necessário ter uma tabela para Números de BI.
Fica ao critério de cada um dependendo das suas necessidades.
Cumprimentos.
Boas…
Isso não invalida o que eu disse…
Pensando ao contrário, teríamos que ter a certeza que um NIF ou BI está *obrigatoriamente* associado a uma Pessoa…
Cumprimentos…
Gilito
Boa noite.
Quando se desenvolve uma BD, há que “pensar” tanto na prespectiva do programador, como do futuro utilizador, logo se é ou não obrigatório usar no modelo ER, tanto o número de BI, como o NIF, fica ao critério de cada um de acordo com as suas necessidades.
Se é isto que estás a querer dizer então estou de acordo contigo.
Cumprimentos.
Oh Gilito, penso que estarás a ser muito especifico…
Penso que a resposta ao problema que colocas é… Depende (Como quase sempre no mundo da informática).
Sendo assim, por aquilo que defendes, no caso do T-SQL, os INNER JOIN’s poucas vezes seriam utilizados e para quê um OUTER JOIN…
Primeiro exemplo… Tens uma BD com 30000 pessoas em que 15000 tem BI’s… Se precisar de uma propriedade do BI eu vou trabalhar com um total de 15000 registos, se fosse pela tua teoria iria trabalhar sobre 30000 registos onde 15000 seriam desnecessários… (Exemplo onde refuto a tua teoria)
Segundo exemplo… Eu trabalho com SSAS todos os dias muito focado em Cubos… Neste caso eu preciso ter tabelas de Factos e Dimensões… É sempre útil ter as tabelas desnormalizadas… Porque é assim que a coisa funciona mesmo… (Exemplo onde apoio a tua teoria)
Por isso volto a dizer…. Depende…
Mas para além de isto tudo, concordo é mesmo com o Manuel Rocha… Para o post que era, está muito bem conseguido…
Cumprimentos.
Viva Duarte Brito,
O teu segundo exemplo tocou num ponto que daria um outro artigo interessante, em que se mostraria a diferença entre bases de dados OLAP (onde temos as tabelas factos e dimensões que referes) e OLTP.
Cumprimentos,
Manuel Rocha
Boa noite.
Também me parece a ser um tema interessante.
Vou fazer umas pesquisas sobre o assunto.
Cumprimentos.
OLAP, ROLAP, e MOLAP… Já testei as 3 e fazem bastante diferença no acesso a dados… Mas lá está depende…
Sim o que dizes é verdade, mas é importante realçar que a finalidade de uma BD é diferente daquela que é esperada de um modelo de dados multi-dimensional, alias, estes são posteriormente criados através destas, e como sabemos, quanto mais “desnormalizados” estiverem melhor é, facilitando o acesso a informação.
Seria interessante um artigo sobre bases de dados OLAP!
E também seriam certamente bem vindos uns artigos sobre MS Access, para mim uma das ferramentas mais interessantes do pacote MS Office! Fica a ideia 🙂
Boa noite.
Como já disse anteriormente, aceitam-se sugestões.
Qual é a tua ideia?
Cumprimentos
Bases de dados OLAP? ou bases de dados multi-dimensionais? acho que é a segunda, neste caso Datas Warehouse.
Boas… (mais uma vez)
Com o meu primeiro comentário não foi de modo algum minha intenção tirar o mérito de quem escreveu o artigo, nem baralhar ninguém…
Quis apenas alertar para uma questão que pode ser colocada pelos mais “novos” nestas andanças e poderiam desatar a fazer relações do tipo 1-1 a torto e a direito… creio que este artigo não era destinado a programadores com 10-15 anos de experiência…
Tal como disse, e creio que vocês concordam, este tipo de relações é especialmente útil por questões de desempenho… que para os mais “novos” se calhar não é a preocupação principal… e como tal, uma relação do tipo 1-1 acaba por ser uma excepção…
Seja como for, parabéns ao autor e fico à espera de mais coisas destas… 🙂
Ahh só mais uma questão, não tenho a certeza, mas criar uma relação do tipo 1-1 creio que não é propriamente normalizar uma tabela… mas isso fica para o próximo artigo…
Cumprimentos,
Gilito.
Boa noite.
Não há problema nenhum, de todo assim foi interpretado. Como já referi anteriormente algumas vezes é um artigo destinado a ajudar qualquer pessoa a dar os primeiros passos no desenvolvimento de BD’s, logo como é obvio de modo algum é destinado a programadores com 15-30 anos de experiência.
Normalmente os mais “novos” (não generalizando)optam entre outras pelo Access, pois é uma ferramenta bastante utilizada e conhecida. Pessoalmente não é uma relação que costumo utilizar com frequência.
O objectivo da sua utilização como também já foi referido, é exemplificar os tipos de relações existentes, e sim, faz parte da normalização das tabelas, dependendo dos casos.
Quanto á questão de mais artigos, tudo depende das sugestões, e da disponibilidade.
@Progster
Desculpa responder-te aqui mas no comentário acima não aparece a opção responder.
Na minha modesta opinião e no que toca ao MS Access acho que, seriam bem vindos uma série de tutoriais, logo com início na definição das tabelas, campos, tipo de dados de cada campo, passando pelas relações entre as tabelas, as consultas, formulários, relatórios, eventualmente algum código VBA para algumas funções mais simples, etc.
Tudo isto numa sequência que permitisse construir uma aplicação completa (lista telefónica, BD de dvd´s /cd´s, etc) que permitisse demonstrar algumas das enormes capacidades do MS Access, e como com esta base de dados se conseguem construir aplicações úteis, quer para uso doméstico, quer para uso numa pequena/media empresa ou organização.
Fica a sugestão
Cumprimentos
Num relacionamento 1 para 1, e caso a participação seja obrigatória em ambas as entidades, faz todo o sentido fundir ambas as tabelas em apenas uma, aplicando um indice (caso haja necessidade) no BI. Com isto, ganhamos desempenho em futuras pesquisas pois não é necessário efectuarmos a junção entre duas tabelas (Pessoa e BI). Isto não é uma regra rígida, mas é uma boa prática.
Caso a participação seja opcional numa das entidades, normalmente separa-se, mas pode ser vantajoso (novamente) fundir as duas tabelas numa só.
Cada caso é único e a sua implementação pode variar de projecto para projecto.
Espero ter contribuido com algo :)!
Boas (mais uma e última vez, prometo!)
Entendido Progster! Exacto JM!
A questão que eu levantei, teve por base o exemplo que o Progster deu, em que:
“cabe ao “criador” do modelo entidade-relação a escolha de qual a tabela que irá receber a chave estrangeira.”
O que basicamente ele quis dizer, foi: ” cabe ao “criador” do modelo definir onde há obrigatoriedade…” (mas sim, para um artigo introdutório a forma como foi dito, é correcta…)
Neste exemplo, assume-se que não há obrigatoriedade dos dois lados (das duas tabelas) e também não se dá o caso de não haver obrigatoriedade em nenhum dos lados, caso em que originaria uma terceira tabela (semelhante à da relação m:n).
Assim sendo, das duas uma: ou há obrigatoriamente um registo na tabela BI para cada Pessoa (ou vice-versa) ou então são permitidos valores nulos para uma chave forasteira, algo que sempre me foi “vendido” como desaconselhado (mas possível!)…
E pronto… creio que já chega de bases de dados por hoje…
A título de sugestão para futuros artigos, deixo o tema “Google Fusion Tables”…
Cumprimentos,
Gilito
O ideal é os campos BI e NIF não serem chaves, dado que cpodem ser NULL (BI é null num estrangeiro e NIF é null num recem nascido)….Estes campos podem ficar UNIQUE e criar um campo aleatorio para fazer de chave
Este artigo vai-me servir de estudo! Muito obrigado desde já pplwarianos.
Boa noite.
Boa…, a intenção é mesmo essa, ajudar as pessoas a darem os primeiros passos no desenvolvimento de BD’s, de modo a que consigam progredir por si próprias.
Cumprimentos.
Bom artigo com certeza. Mas as relações e a normalização de bases de dados dependem em muito dos resultados pretendidos, do n.º de registos da rapidez de acesso aos dados. Eu pessoalmente prefiro não utilizar a normalização nem a relação explicita, vou construindo cada uma conforme a necessidade, pois é mais fácil programar os formulários.
Boa noite.
Exactamente, existem várias variáveis a ter em conta aquando o desenvolvimento de uma BD, as quais podem, e em muitos casos são mesmo alteradas, de acordo com as necessidades que vão surgindo.
Cumprimentos.
Excelente Progster…
Obrigado Damnation
Access. Dei isto este ano, está bem explicado sim senhor.
Parabéns e continuação de bom trabalho.
Obrigado Visitante.
Boa noite.
@M.Manuelito
Ok. Dependendo da disponibilidade, talvez se consiga mais qualquer coisa.
Cumprimentos.
Boas,
excelente post. Alguém tem tutoriais de PostGreSQL? Ou recomenda algum que esteja disponível online?
Obrigado
Obrigado Luis. Esse também é um futuro “projecto” a considerar.
Excelente post! Vem mesmo a calhar, visto que estou a escrever um manual que começa com esta matéria 😀
Obrigado André.
Tenho um manual sobre Access disponível no meu site que podem consultar.
As bases de dados para datawarehouses tem situações de ter as tabelas desnormalizadas e enriquecidas com informações de outras tabelas por forma a reduzir o número de tabelas a que se tem que aceder quando são efectuadas as pesquisas.
O tipo de perguntas a que uma datawarehouse deve responder em segundos se colocado em queries sobre sistemas correntes podem demorar longos minutos ou horas.
A análise para bases de dados OLAP começa pela identificação das dimensões necessárias e dos cruzamentos mais interessantes.
Espero ter ajudado.
Boa…
Obrigado a todos.
Novas ideias estão já a começar a entrar na fase de estruturação.
Cumprimentos.
Recomendo a ferramenta PowerDesigner para estruturar e esquematizar estas bases de dados. Podem também depois, a partir do mesmo software criar uma base de dados já com as tabelas, campos e relações criadas 🙂
obviamente foi feito em bloco de notas integralmente
Este topico vem mesmo a proposito de uma duvida que tenho no Access. A minha BD tem um forulario principal que tambem é composto por varios subformularios. A questão é que preciso de pesquisar informação nesse formulario principal, mas a pesquisa não é efectuada nos subformularios. Alguem me pode ajudar.
Obrigado e um abraço.
Bom artigo. Apenas um reparo, talvez não seja o objectivo deste artigo no entanto não é uma boa prática colocar acentuação/espaços no nome das tabelas/campos.
BOUM ARTIGU! AJUDOUME IMEMSO! 🙂