Solução do segundo exercício proposto REDE DE HOTÉIS Este exemplo já tem um pouco mais de complexidade devido à quantidade de entidades envolvidas no cenário. Em um primeiro momento a solução poderia ficar da seguinte forma: Neste tipo de cenário, em que uma entidade abrange as outras em cadeia (encadeamento 1:N a melhor técnica é se partir da entidade mais abrangente. Aqui, como a questão é geográfica, entendese, por experiência de vida, que a CIDADE irá abranger todas as demais entidades, ou seja, tudo o mais que houver em determinado hotel (prédio estará confinada àquela CIDADE.
Não podemos esquecer que se não compreendermos com precisão como funciona e quais são as necessidades do negócio para o qual iremos desenvolver nosso sistema, fatalmente iremos criar um modelo inadequado. Quanto menos compreensão, maior a quantidade de erros de modelagem e o nosso sistema não funcionará de forma adequada. Se ficaram pontos obscuros devemos solicitar esclarecimentos do nosso cliente antes de começarmos a modelagem em si. Estamos supondo aqui no nosso exercício que este entendimento está satisfatório. Continuando, sabemos que os prédios ficam nas cidades e não há nenhuma outra entidade no meio. Logo o PREDIO fica na CIDADE. Tipo 1:N onde se pode ter de 0 a N prédios em uma cidade e cada prédio tem que estar no mínimo em uma cidade e no máximo em uma. Da mesma forma vamos ao nível do quarto. O PREDIO tem QUARTO(s. Não é necessário nada neste meio. Até este ponto temos a chamada operação administrativa do sistema. Uma vez pronto o sistema, um usuário administrativo terá que fazer a configuração, ou seja, cadastrar as cidades, os prédios e respectivos os quartos. A partir daí o sistema estaria pronto para a utilização operacional. Aquela em chega um hóspede pedindo um quarto e então o funcionário do balcão verifica se há quarto vago, preenche os dados do hóspede etc. Neste modelo optou-se em vincular a CONTA ao QUARTO e não o HOSPEDE ao QUARTO. É uma decisão do analista de sistemas. Poderia ter vinculado o hóspede ao quarto e vincular a conta a pagar ao hospede? Sim, poderia, mas assim fica melhor. A conta é um arquivo do hotel para futuros (obrigatórios levantamentos de faturamento, por exemplo, já o hóspede é alguém que vem e vai e não necessariamente se vai querer uma estatística sobre ele. Então os dados que mais acessamos devemos deixar com acesso menos burocrático (menos tabelas no meio do caminho. Um QUARTO tem muitas CONTAs. Evidentemente sabemos por experiência que se determinado quarto já tem um hóspede não se pode colocar outro hóspede junto (abrir outra conta para o mesmo quarto ao mesmo tempo. Isto é uma chamada regra do negócio e deverá ser tratada no nível da programação, pois não tem como o banco resolver isso com os recursos de chaves primárias/estrangeiras. Logo, a CONTA deverá ter algum atributo sinalizador informando se está aberta ou fechada. Como posso saber se um determinado quarto está vago? Verificando se existe alguma conta aberta vinculada a este quarto. Se houver: quarto ocupado, se não houver: quarto vago. O atributo DATA_SAIDA pode servir para fazer este controle. Se esta data não estiver preenchida (valor NULL, significa que o quarto está ocupado. O HOSPEDE, então, pode ficar vinculado à sua CONTA e seus acompanhantes vinculados a ele. Aqui vale uma discussão. Em um sistema mais completo se poderia ter um cadastro de hóspedes que já passaram pela rede de hotéis e, cada vez que um determinado hóspede retornar, associar a sua chave primária a uma determinada nova conta em um tipo de cardinalidade 1:N no sentido HOSPEDE para CONTA (um hóspede tem várias contas e uma conta está associada a um único hóspede. Mas este modelo é mais complexo pois também muda a forma de relacionamento dos acompanhantes, de forma que iremos modelar no tipo 1:1. Uma conta tem um hóspede e um hóspede só tem uma conta. O ACOMPANHANTE poderia ser movido para a entidade HOSPEDE, pois ACOMPANHANTE é um HOSPEDE, a única diferença é que ele é acompanhante, não é o hóspede responsável pela conta. Será que um atributo para sinalizar o hóspede responsável não resolveria? Dessa forma eliminaríamos uma entidade. Abaixo os modelos produzidos pelo software modelador DB Designer 4, freeware orientado ao MySQL. A estrutura de Tabelas (Modelo Lógico e o Esquema Físico para geração do banco de dados.
Estrutura de Tabelas Esquema Fisico CREATE TABLE cidade ( idcidade INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, nome VARCHAR(30 NULL, estado CHAR(2 NULL, PRIMARY KEY(idcidade CREATE TABLE atividade ( idatividade INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, nome VARCHAR(30 NULL, observacao TEXT NULL, PRIMARY KEY(idatividade
CREATE TABLE predio ( idpredio INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, idcidade INTEGER UNSIGNED NOT NULL, nome VARCHAR(20 NULL, logradouro VARCHAR(50 NULL, bairro VARCHAR(30 NULL, numero CHAR(5 NULL, complemento VARCHAR(20 NULL, PRIMARY KEY(idpredio, FOREIGN KEY(idcidade REFERENCES cidade(idcidade CREATE TABLE quarto ( idquarto INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, idpredio INTEGER UNSIGNED NOT NULL, andar INTEGER UNSIGNED NULL, numero CHAR(10 NULL, tipo CHAR(1 NULL, ar_con CHAR(1 NULL, tv_cabo CHAR(1 NULL, internet CHAR(1 NULL, frigobar CHAR(1 NULL, sauna CHAR(1 NULL, hidro_massagem CHAR(1 NULL, PRIMARY KEY(idquarto, FOREIGN KEY(idpredio REFERENCES predio(idpredio CREATE TABLE conta ( idconta INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, idquarto INTEGER UNSIGNED NOT NULL, entrada DATETIME NULL, saida DATETIME NULL, item VARCHAR(50 NULL, preco DOUBLE NULL, PRIMARY KEY(idconta, FOREIGN KEY(idquarto REFERENCES quarto(idquarto CREATE TABLE hospede ( idconta INTEGER UNSIGNED NOT NULL, responsavel CHAR(1 NULL, nome VARCHAR(50 NULL, logradouro VARCHAR(50 NULL, bairro INTEGER UNSIGNED NULL, numero CHAR(5 NULL, complemento VARCHAR(20 NULL, cidade VARCHAR(30 NULL, estado CHAR(2 NULL, rg VARCHAR(20 NULL, cpf VARCHAR(20 NULL, origem VARCHAR(30 NULL, destino VARCHAR(30 NULL, PRIMARY KEY(idconta, FOREIGN KEY(idconta REFERENCES conta(idconta
CREATE TABLE conta_has_atividade ( idconta INTEGER UNSIGNED NOT NULL, idatividade INTEGER UNSIGNED NOT NULL, PRIMARY KEY(idconta, idatividade, FOREIGN KEY(idconta REFERENCES conta(idconta, FOREIGN KEY(idatividade REFERENCES atividade(idatividade CREATE TABLE monitor ( idmonitor INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, idpredio INTEGER UNSIGNED NOT NULL, nome VARCHAR(50 NULL, endereco TEXT NULL, cpf VARCHAR(20 NULL, rg VARCHAR(20 NULL, PRIMARY KEY(idmonitor, FOREIGN KEY(idpredio REFERENCES predio(idpredio CREATE TABLE monitor_has_atividade ( idmonitor INTEGER UNSIGNED NOT NULL, idatividade INTEGER UNSIGNED NOT NULL, PRIMARY KEY(idmonitor, idatividade, FOREIGN KEY(idmonitor REFERENCES monitor(idmonitor, FOREIGN KEY(idatividade REFERENCES atividade(idatividade