Nauka SQL projekt DB

0

Cześć,
zacząłem się uczyć SQL i chciałbym zaprojektować samodzielnie bazę danych, a później ćwiczyć na niej zapytania.
Baza będzie dotyczyć mieszkania, w którym są pokoje, a każdy z tych pokoi jest do wynajęcia.

Zrobiłem schemat na Lucidchart i chciałbym was poprosić o opinię co do niego.
Czy jest wykonany poprawnie i czy użyłem dobrych znaczników do relacji.
Rent a Flat DB schema.jpeg

Opis tabel:
apartment - dane dotyczące mieszkania .
room - pokój i informacje o nim, jeden klucz obcy1-N (pokój może być w jednym mieszkaniu, ale w mieszkaniu może być kilka pokoi).
charges - opłata może dotyczyć jednego mieszkania ale mieszkanie może mieć kilka różnych opłat.
person - dane wynajmującego.
Z tym mam problem i wątpliwości co do poprawnego wykonania:
contract - informacje dotyczące umowy. Umowa może być podpisana przez jedną osobę, ale osoba może mieć kilka umów. Umowa może dotyczyć wynajmu jednego lub kilku pokoi przez jedną osobę (np. ktoś wynajmuje dwa pokoje w tym samym czasie w jednym mieszkaniu), ale pokój może mieć jedną umowę(wynajmującego) w danym czasie.
I teraz nie wiem. Bo mogę to tak zostawić i podpisać umowę oddzielnie dla każdego pokoju z jednym wynajmującym wtedy dla każdego pokoju contract_id będzie różne.
A zastanawiam się jak zrobić żeby pod jednym contract_id i start można było przypisać np. dwa room_id.
Teraz podczas pisania tego myślę, że mógłbym również zrobić kolejną kolumnę pod nazwą active gdzie będzie wartość bool mówiąca czy umowa jest w trakcie trwania czy już nie obowiązuje.
rent - czynsz, który wpłaca wynajmujący (w zamyśle wynajmujący płaci czynsz co miesiąc), kwota wpłaty nie zawsze musi się pokrywać, z kwotą na umowie. Wpłata zawsze idzie na konto konkretnego mieszkania.

Będę wdzięczny za opinie :)

1

Skorzystaj z gotowych stron www gdzie możesz poćwiczyć SQL jak hackerrank. Jak sam zaczniesz tworzyć na początek cuda, to nie wyjdzie to raczej na dobre.

0

@PaulGilbert: Dzięki, akurat nie znałem tej strony i chętnie skorzystam.

1

Teraz podczas pisania tego myślę, że mógłbym również zrobić kolejną kolumnę pod nazwą active gdzie będzie wartość bool mówiąca czy umowa jest w trakcie trwania czy już nie obowiązuje.

Moim zdaniem to słabe rozwiązanie. Bo prędzej czy później będziesz musiał taką wartość aktualizować. Pomyśl lepiej jakie są warunki tego czy umowa trwa. Wg mnie mogą być one takie

  • jeśli umowa trwa od do... I aktualna Data mieści się w tym zakresie to umowa jest aktywna

  • jeśli umowa ma warunek, że klient nie może zalegać z płatnościami to w tabeli z płatnościami możesz sprawdzić czy ostatnie X miesięcy jest opłacone.

  • jeśli umowa jest zawarta na rok i mamy ostatni miesiąc, to jeśli klient nie złożył chęci przedłużenia to umowa będzie nieaktywna.

    Pomysł teraz że dla tych trzech warunków musiałbyś aktualizować flagę. Nadal byś musiał to sprawdzać,
    Czasami lubię wymyślać głupie przykłady. Tak więc... Chcesz zjeść płatki z mlekiem, zaglądasz do lodówki a tam mleka brak. Wiesz ze musisz iść do sklepu by je kupić. Czy w takim przypadku warto zapisywać to na kartce? Skoro i tak sprawdziłeś że mleka nie ma, a i tak będziesz musiał iść do sklepu. Zapisanie tego stanu w dodatkowym miejscu nic moim zdaniem nie zmieni.

Jeśli chodzi o wydajność to jeśli już chcemy mieć prosty dostęp do tego czy umowa jest ważna w danym momencie to proponowałbym wrzucić info o tym do specjalnej tabeli, która by przechowywała poszczególne wartości z warunków umowy
Np Select * from orders_state where last_3_months_paid=1

Nie jest to może cud architektury, ale pomyśl o tym. Myślę że spece od baz mogą mnie zaraz zjechać, ale osobiście na pewno nie trzymałbym w bazie czegos co trzeba aktualizować zamiast po prostu wyciągać te rzeczy bezpośrednio z tabel.

0

Mam jeszcze jedno pytanie,
zacząłem tworzyć tabele w bazie danych i mam problem z ustawieniem FOREIGN KEY w jednej tabeli korzystając z PK utworzonego z dwóch innych FK.
Może pokaże to na przykładzie.
Jak na obrazku na początku stworzyłem tabele room oraz person dzięki czemu mogłem stworzyć tabelę contract z takim PK:

CREATE TABLE contract (
    room_id INT,
    person_id INT,
    PRIMARY KEY(room_id, person_id),
    FOREIGN KEY(room_id) REFERENCES room(room_id) ON DELETE CASCADE,
    FOREIGN KEY(person_id) REFERENCES person(person_id) ON DELETE CASCADE,
    price INT NOT NULL,
    start DATE NOT NULL,
    end DATE
);

I teraz chciałbym do nowej tabeli przypisać kolumnę contract dodając PK contract jako FK

CREATE TABLE rent (
    rent_id INT AUTO_INCREMENT PRIMARY KEY,
    ammount INT NOT NULL,
    date DATE NOT NULL,
    contract INT,
    CONSTRAINT contract FOREIGN KEY(contract) REFERENCES contract(room_id, person_id) ON DELETE SET NULL,
    apartment INT,
    FOREIGN KEY(apartment) REFERENCES apartment(apartment_id) ON DELETE SET NULL
);

Niestety pojawia mi się błąd, którego nie potrafię rozwiązać.

Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match

1 użytkowników online, w tym zalogowanych: 0, gości: 1