Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Projekt bazy danych dla biblioteki
Forum PHP.pl > Forum > Bazy danych
black008
Witam. Ostatnio zostałem poproszony przez znajomego nauczyciela o zaprojektowanie i stworzenie aplikacji zarządzającej biblioteką szkolną. Aplikacja miałaby na celu pozwolić na stworzenie internetowej wypożyczalni. Stworzyłem wstępną wersję schematu bazy danych:

http://imageshack.us/photo/my-images/717/schematbazy.png/

Stwierdziłem że adres zameldowania i korespondencyjny będą w jednej tabeli i będą rozróżnianie przez pole "type_address".
Nie stworzyłem osobnej tabeli dla autorów książki ponieważ jeżeli będzie ich więcej można ich nazwisko umieścić w jednym polu w jednej tabeli.
Co sądzicie o takim pomyśle?? Jak wy byście to rozwiązali??
thek
Co do adresów - słusznie.
Co do autorów - nierozsądne. Autor powinien mieć osobną encję (tabelę) i łaczyć się relacją "wiele do wielu". Czemu? Bo zachodzić może wiele możliwości:
- autor może mieć wiele książek,
- książka może być wielu autorów i jeszcze pod czyjąś redakcją.
To już sugeruje nie tyle relację n-n, ale n-n z parametrami, która wygląda prosto, ale w ORM-ach wszelakich jest upierdliwa. Poza tym jak sobie wyobrażasz modyfikowanie pola autora gdy używasz stringa w książce mającej kilku? Wyciągniesz rekord, zaczniesz cudować by go dokleić, wyciąć czy co tam będziesz robił? Jak zrobisz wyszukiwanie w bazie po autorze mając go wpisanego jako string? Co gdy zmieni nazwisko lub uznasz, że popełnił ktoś w nim błąd? A co gdy zechcesz userom pomóc w tym i zrobić autouzupełnianie?
black008
Słuszna uwaga. Tego nie przewidziałem. Dzięki za pomoc. A generalnie cały schemat jest do przyjęcia questionmark.gif Czy jeszcze czegoś nie przewidziałem questionmark.gif

Poprawiłem sprawę z tabelą dla autorów. W programie DBDesigner 4 jak chciałem zaznaczyć relacje wiele do wielu wyszło mi coś takiego:

http://imageshack.us/photo/my-images/20/bazad.png/

Tak może być questionmark.gif
thek
Dla relacji n-n pokazało Ci dobrze (tabela łącząca z odpowiednimi kluczami). Problem pojawi się gdy będziesz miał jeszcze książkę jako praca zbiorowa pod czyjąć redakcją. Jak określisz kto czuwał nad tym? wink.gif Ogólnie samo "zadanie z biblioteką" jest dość typowym projektem i warto się zastanowić nad relacjami pomiędzy obiektami i tym, jak one będą żyć w systemie. Przykład z rodzaju "oczywisty, niewidoczny na pierwszy rzut oka dla początkującego". Masz adres w postaci jaką widać w linku. Zauważyłeś już, że adres zamieszkania i korespondencyjny są w sumie tym samym (ta sama tabela). Co jednak, gdy ktoś podaje dane z więcej niż jednym telefonem? Idźmy dalej... By ułatwić wpisującemu uzupełnianie danych, miasto jest pozycją z autouzupełnianiem. Będziesz jechał po całej bazie by dopasowywać znalezione u wszystkich userów nazwy miast?

Dlatego przy tym zadaniu zastanów się nie tyle "jak wyglądają tabele?", ale "jakie są relacje między rolami lub obiektami w systemie?", "jakie funkcjonalności mają poszczególne osoby i obiekty?", "Jak widziane przeze mnie obiekty między sobą są widoczne i jak się kontaktują, co zawierają?", bo to pomoże Ci określić właśnie strukturę tabel i ich pola. Ogólnie dobrze zacząłeś, ale diabeł zawsze tkwi w szczegółach wink.gif Postanowisz więc, że Cię nieco naprowadzę kilkoma pytaniami odnośnie poszczególnych obiektów:
Adres:
- czy miejscowość ma być dostępna z autozupełniania i wiązać się z określonym województwem lub państwem? (może z automatu te pola uzupełniać?)

User:
- czy może mieć więcej adresów lub określoneg rodzaju danych (telefon, email)?
- jak mają być jego uprawnienia określone? Czym te uprawnienia są i jak działają?

Author:
- czy tylko imię i nazwisko? A może datę urodzenia, rys biograficzny, odnośnik do jakiejś strony z tymi informacjami?

Book:
- jak określić egzemplarze danej książki? Czy każdy egzemplarz ma swoje id czy ujmujemy to inaczej?
- co nam daje kategoria książki i czym jest?
- co jeśli użytkownik nie zna tytułu lub autora? Jak mu pomóc odnaleźć właściwą?

Zauważ, że to tylko początek na podstawie Twojej struktury. Ale kompletnie pomija funkcjonalności i skupia głównie na strukturze. Przykładowo jak planujesz zarządzać nie oddanymi/zniszczonymi książkami? Co z informowaniem bibliotekarza o tym, że ktoś książki nie oddał, a termin mu minął? Jak spersonalizować i ułatwić użytkownikowi dostęp do zasobów? Czy podpowiedzieć kiedy ma być oddana interesująca go książka? A może zasugerować inną, powiązaną autorem, kategorią, tematyką lub wręcz analizując dotychczasowe wypożyczenia użytkownika podpowiedzieć inną, ale aktualnie dostępną? Co z systemem potencjalnego "zaklepania" książki na dany termin? A może analizować częstotliwość pytania o daną książkę by zasugerować bibliotekarzowi/użytkownikom posiadającym obecnie ją, że mogli by się pospieszyć, bo inni też ją chcą.

Jak widzisz, problematyka biblioteki wydaje się początkowo jedynie banalna, ale gdy zaczynasz myśleć o funkcjonalnościach, może się okazać, że początkowy schemat się po drodze rozszerza. Wspomniana książka bowiem może zostać uzupełniona o słowa kluczowe (tagi), które ją scharakteryzują i potrafią pomóc trafić na właściwą userowi nie znającemu autora czy tytułu. Może znać głównego lub pobocznych bohaterów przykładowo (usłyszał gdzieś przypadkiem) albo miejsce w jakim się akcja dzieje. Każda z decyzji potrafi zmienić schemat bazy lub podejście.

By nie rzucać dużej ilści pytań i zero odpowiedzi...
Książka może mieć w bibliotece wiele egzemplarzy. Tak naprawdę większość jest widoczna i rozpoznawana głównie po autorze i tytule, a to wystarczy użytownikowi wypożyczającemu. Ale nie bibliotekarzowi. On jak zauważyłeś rozpoznaje je po także innych elementach. Może istnieć wiele tych samych wersji książki, która z poziomu wypożyczającego jest nieistotna, gdyż zawiera tę samą treść. Przykładem są lektury szkolne. Zauważ jednak że bibliotekarz może mieć już wersje różnych wydawnictw, a na dodatek kilka egzemplarzy każdej. Zaczyna się robić niezły zgryz. Czemu? Ponieważ albo mamy jeden obiekt ogromny, który to wszystko trzyma (i tym samym pewna część danych jest zwyczajnie identyczna) albo wydzielamy mniejsze obiekty (kategoria, wydawnictwo, egzemplarze) i zaczynamy mieć coraz więcej połączeń. Ty przykładowo masz jeden wielki obiekt. Ja bym się zastanawiał nad:
Book:
id, title
Tu trzymamy tylko id i tytuł. Reszta dojdzie z połączeń smile.gif

Tag:
id, name
Tu będą tagi określające książkę.

Book_tags:
book_id, tag_id
Tutaj trzymamy powiązania tagów z książkami. Oczywiście jeden tag może tyczyć kilku książek. Wszak bohater serii książek wiąże się z każdą. Czyż nie?

Book_version:
id, book_id, publishing_house
To różne wersje (nie egzemplarze!) tej samej książki, różnych wydawnictw przykładowo.

Author:
id, name, surname (i inne dane)
Oczywiście dane autorów - dowolnie rozszerzalne

Teraz mamy dylemat autorstwa. Możemy zastosować kilka podejść. Ja osobiście skłaniam się do dodatowego określenia z czym mamy do czynienia na podstawie tabeli łączącej.
Book_authors:
book_id, author_id, author_status
Czemu tak? Mogę określić, wyróżnić określonych autorów dla danej książki. Jeśli jest jeden tylko, nie ma problemu. Jeśli kilku o tym samym poziomie, też luz. Ale nadając różne statusy, mogę określić czym są (autor główny, współautor, redaktor pracy zbiorowej, autor w pracy zbiorowej itd)

Publishing_house:
id, name (i inne dane)
Oczywiście dane wydawnictwa różne

Book_publisher:
book_version_id, publisher_id
Powiązanie miedzy książką i jej wydawcą.

Category:
id, name
Oczywiście kategorie. Tutaj tylko tak, ale warto zastanowić nad hierarchicznością kategorii (struktura drzewiasta zapewne).

Book_category:
book_id, category_id

Book_copy:
id, book_version_id, copy_status
Tu to o czym wspominałem - egzemplarze danej książki. Łączą do wersji książki. Ja dodałem status, ale nie czy wypożyczona (choć też można), ale jej stan zużycia (może zostać uznana za zniszczoną, do utylizacji, sprzedaną, zagubioną)

Renting:
user_id, book_copy_id, book_date, book_end
Tu oczywiście serce, czyli wypożyczenie określonego egzemplarza książki.

Jak widzisz rozwinąłem nieco Twoje główne tabele by były bardziej uniwersalne. A uwierz, że to tylko dość pobieżne i można by bardziej się postarać. Na dodatek wziąłem tylko pod uwagę tabele: autor, książka, wypożyczenie. Bez ujęcia usera i jego danych, tabel kar (automatyczne obliczanie za oddanie po terminie), statusu książki (możliwa do wypożyczenia czy z księgozbioru podręcznego?) oraz wielu innych aspektów. Dodam, że warto by archiwizować rekordy z wypożyczeniami już zakończonymi (i z jakim statusem! - oddana, zniszczona, zagubiona) by nie trzymać w aktualnych tych, które już nam nie są potrzebne do bieżących zadań. Myślę, że wystarczająco dałem Ci materiału do przemyślenia wink.gif
black008
Cytat
Myślę, że wystarczająco dałem Ci materiału do przemyślenia


Owszem dałeś dałeś smile.gif Postaram się to wszystko ogarnąć smile.gif Nie zdawałem sobie sprawy że tyle tego jest smile.gif Ale damy radę smile.gif
thek
Powiem tak... Zacznij od określenia dziedziny problemu. Jak najlepiej? Idź do biblioteki, pogadaj z bibliotekarzem i zwyczajnie zapytaj co robi, co mu zajmuje najwięcej czasu. Może ułatwienie najczęściej powtarzających się działań lub najbardziej uciążliwych. Pogadaj z wypożyczającymi i określ co by im było potrzebne, jakie funkcje obecnie uznają za brakujące. Może wspomniane zaklepanie książki przez Internet albo sprawdzenie kiedy powinna być dostępna. ALbo zwróć uwagę na aktualny trend społeczościowy. Masz bibliotekę, a więc ludzi o określonych zainteresowaniach. Daj im możliwość wzajemnej wymiany informacji. Zgromadź ich wokół aplikacji smile.gif Daj nawiązać kontakt na linii użytkownicy - biblioteka. Może mogli by proponować bibliotece zakup określonych, interesujących ich tytułów?
abort
Cytat(thek @ 27.10.2012, 22:00:05 ) *
Book:
id, title
Tu trzymamy tylko id i tytuł. Reszta dojdzie z połączeń smile.gif


ABSOLUTNIE NIE. Nie tytuł. Tytuł nie jest unikalny. Mało tego, dwa tytuły mogą oznaczać np dwa różne tłumaczenia tego samego dzieła - i co w przypadku, gdy chcemy rozróżnić książkę po tłumaczu? Owszem, można dodać pole "tłumacz" (swoją drogą pomyśl, bo chyba warto). Jednak dla książek warto zapewnić rozróżnienie tego nie po złączeniach tabel, bo mogą być jaja. Jest jedna rzecz, którą TRZEBA w tabeli "book" dać jako wyróżnik książki - takim wyróżnikiem jest Numer ISBN - jest on unikalny dla książki, nawet każda EDYCJA ma inny numer ISBN (jedynie dla reprintów ISBN się nie zmienia). Przykład: taki np. Hobbit Tolkiena miał trzy polskie tłumaczenia - wszystkie wyłapiemy po numerze ISBN, bo po tytule nie bardzo.
thek
@abort: Nigdzie nie napisałem, że tytuł jest unikalny, ale jest w miarę sensownym wyborem, gdy bierzemy pod uwagę wyjście od czegoś i ma to jeszcze być najwęższa możliwa informacja. W bazie bez problemu może być choćby i 100 takich samych tytułów. Wyszukiwarka może sobie wychodzić od dowolnego pola, ale korzysta z niej głównie użytkownik, który ISBN raczej na pewno nie zna. To bardziej dla bibliotekarza informacja (choć możliwość wyszukiwania po ISBN to dobra opcja dla wyszukiwarki). Usera nie obchodzi najczęściej czy jakaś książka miała ileś edycji, reedycji czy tłumaczeń. Jeśli nagle dostanie kilkanaście pozycji o odmiennych tytułach (lub tytułach w różnych językach) to może zgłupieć. To powinno być jako dodatkowa informacja. Przykładowo komunikat, że książka jest też znana pod innym tytułem, lub ma nowsze/starsze wydanie - z odnośnikiem jeśli jest dostępna w bibliotece. Pamiętajmy, że user powinien mieć informacje porcjowane. Ich nadmiar sprawi, że wszystko stanie się dla niego nieczytelne i nie będzie wiedział co jest grane. Tym bardziej jeśli spotyka się z interfejsem aplikacji po raz pierwszy. Bądźmy optymalni i nie zasypujmy usera nadmiarem niepotrzebnych z początku informacji ( lub sensownie je pogrupujmy).

@abort: To co piszesz o ISBN to wiem, ale problem jest tego typu, że tak naprawdę nie ma możliwości wybrania jednej cechy, która byłaby jednoznacznym identyfikatorem (ISBN też nie jest unikatowy, o czym w linku do wiki, który podałes, też przeczytasz). Dopiero połączenie kilku "pól" tworzy w miarę unikatowy "odcisk palca" książki bez nadmiernego powtarzania danych. Poza tym zwróć uwagę na fakt, że można zawsze lekko przemodelować całość, dopasować ISBN jako wyjściowe i do niego podpinać resztę elementów, włącznie z tytułem, który stanie się relacją typu many-to-many. Kwestia podejścia do optymalizacji i pewnie jakichś warunkow ograniczających narzuconych. Żeby zrozumiec o co mi chodzi... Masz różne ISBN, wskazujące tę samą książkę, ale w róznych edycjach i tłumaczeniach. Co wyświetlisz userowi? Wedle czego pogrupujesz? To przecież, suma sumarum, powinna być jedna pozycja w wyszukiwarce dla niego. Nie da się tego zrobić idealnie i jestem tego świadomy.

Co do tłumacza zaś... Patrz tabela book_authors i komentarze do niej. Nie widzę problemu by tam tłumacza jako jeden ze statusów dodać. Nie pozbawimy się pola autor, a tłumacz jako dodatkowy "autor" to nie jest głupi pomysł. Zwłaszcza, że zdarza się, iż czytelnicy poszukują konkretnych tłumaczeń. W końcu wśród czytających jedne są bardziej cenione niż pozostałe. Z racji choćby wierności w porównaniu z oryginałem.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.