Modelando um 1 a 1..n relação na base de dados

votos
3

Como você modelar quarto de hotel reservado para relacionamento convidados (em PostgreSQL, se isso importa)? Um quarto pode ter vários convidados, mas pelo menos um.

Claro, pode-se relacionar hóspedes que viajam a reservas com uma chave estrangeira booking_id. Mas como você aplicar no nível DBMS que um quarto deve ter pelo menos um convidado?

Pode ser que é simplesmente impossível?

Publicado 27/10/2008 em 12:25
fonte usuário
Em outras línguas...                            


6 respostas

votos
0

Que tal um quarto que não foi alugado? O que você está procurando são reservas e uma reserva precisa presumivelmente pelo menos um convidado sobre ele.

Eu acho que você está perguntando é se você pode garantir que um registro de reserva não é adicionado a menos que você tem pelo menos um convidado para e você não pode adicionar um convidado sem uma reserva. É um pouco de um Catch-22 para a maioria dos sistemas SGBDs.

Respondeu 27/10/2008 em 12:32
fonte usuário

votos
1

Você pode designar um dos convidados como o convidado "primário" e tê-lo mapear para uma coluna na tabela salas. Claro, esta é uma regra ridícula para um hotel, onde é perfeitamente válido ter um quarto com 0 convidados (eu poderia muito bem pagar por um quarto e não ficar lá) ...

Respondeu 27/10/2008 em 12:32
fonte usuário

votos
4

Neste contexto, sugere que a entidade que você está modelando é na verdade um RESERVA - uma única entidade - em vez de duas entidades de quarto e convidado.

Assim, a tabela seria algo como

BOOKING
-------
booking id
room id
guest id (FK to table of guests for booking)
first date of occupancy
last date of occupancy

Onde id hóspede não é anulável, e você tem outra mesa para manter os hóspedes por reserva ...

GUESTS
------
guest id
customer id (FK to customer table)
Respondeu 27/10/2008 em 12:33
fonte usuário

votos
5

Na verdade, se você ler a pergunta, ele afirma reservado quartos de hotel. Isto é bastante fácil de fazer o seguinte:

Rooms:
    room_id primary key not null
    blah
    blah

Guests:
    guest_id primary key not null
    yada
    yada

BookedRooms:
    room_id primary key foreign key (Rooms:room_id)
    primary_guest_id foreign key (Guests:guest_id)

OtherGuestsInRooms:
    room_id foreign key (BookedRooms:room_id)
    guest_id foreign key (Guests:guest_id)

Dessa forma, você pode impor um quarto reservado com pelo menos um dos hóspedes, enquanto os OtherGuests é um 0-ou-mais relacionamento. Você não pode criar um quarto reservado sem um convidado e você não pode adicionar outros hóspedes sem o quarto reservado.

É o mesmo tipo de lógica que você siga se você quer um relacionamento n-para-n, que deve ser corrigido para a tabela separada contendo um n 1-para-um e n-para-1 com as duas tabelas.

Respondeu 27/10/2008 em 12:43
fonte usuário

votos
1

Eu acho que você quer dizer é que uma reserva de quarto é, pelo menos, um convidado. ANSI SQL padrão que lhe permitem expressar a restrição como uma afirmação algo como:

create assertion x as check
   (not exists (select * from booking b
                where not exists
                   (select * from booking_guest bg
                    where bg.booking_id = b.booking_id)));

No entanto, não creio Postgres suporta isso (não tenho certeza qualquer DBMS atual faz).

Existe uma maneira usando visualizações materializadas e restrições de verificação, mas eu nunca vi isso feito na prática:

1) Criar uma visão materializada como

select booking_id from booking b
where not exists 
   (select * from booking_guest bg 
    where bg.booking_id = b.booking_id);

2) Adicionar uma restrição de verificação para a visão materializada:

check (boooking_id is null)

Esta restrição irá falhar se alguma vez a visão materializada não está vazio, ou seja, se há uma reserva com nenhum convidado associado. No entanto, você precisa ter cuidado com o desempenho desta abordagem.

Respondeu 27/10/2008 em 12:43
fonte usuário

votos
0

Eu diria que você deve criar uma bookingstabela com três chaves primárias. Mas, em vez de se referir a reservas de quartos, você pode se referir a uma bedsmesa.

bookings:
  bed_id: foreign_key primary
  guest_id: foreign_key primary
  day: date primary
  bill_id: foreign_key not null

beds:
  room_id: foreign_key primary

Desde que o primaryimplica que seja necessário, e uma vez que esta é a única maneira de um convidado e um quarto pode ser relacionado, ele garante que não pode haver uma reserva sem um convidado.

Observe que há apenas um daycampo. Isto requer que você crie uma reserva para cada dia um convidado vai ficar em um quarto, mas também garante que nada será acidentalmente reservado duas vezes. A cama pode ser reservado por apenas um cliente em qualquer dia (o que não é verdade para os quartos)

O bill_idque há de modo que você pode consultar uma reserva para um registro específico para um projeto de lei, que também pode ser referenciado por outras coisas, como as despesas de mini-bar.

Respondeu 15/09/2010 em 10:17
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more