Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Problem w projektowaniu bazy
quality
post 20.11.2008, 15:45:52
Post #1





Grupa: Zarejestrowani
Postów: 172
Pomógł: 9
Dołączył: 13.02.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Witam
Napotkalem 2 problemy projektując bazę danych:

1. Mam 2 moduly - artykuly i galerie. Chcialbym zeby i galerie i artykuly mogly byc komentowane. I tutaj pytanie. Czy zrobic oddzielna tabele komentarzy dla galerii i artykulow, czy zrobic jedna tabele komentarze i dodatkowo 2 tabele "galerie -> wiele do wielu -> komentarze" i "artykuly -> wiele do wielu -> komentarze" ?

2. Drugi problem jest podobny. Mianowicie chodzi o to ze galerie, artykuly, programy itd posiadaja typy. I tutaj tez czy zrobic osobne tabele np: "typ_artykulow" itp czy zrobic jedna tabele
" typy" i dodatkowa "rodzaj_typow" (w ktorych znajda sie informacje o modulach do ktorych beda te typy nalezec)

Ps. Mam nadzieje ze nie zamotalem zabardzo. jak cos to przesle screeny z zamodelowana baza.


--------------------
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 5)
ddiceman
post 20.11.2008, 17:52:00
Post #2





Grupa: Zarejestrowani
Postów: 326
Pomógł: 121
Dołączył: 23.07.2008
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


AD 1.
Nie sadze, ze funkcjonalnosc 'wiele do wielu' jest Ci potrzebna - w koncu komentarz dotyczy jednej galerii, lub jednego artykulu, wiec jest to relacja 'jeden do wielu'.
Zastanów się, czy komentarz do galerii ma strukturę taka sama, jak do artykulu. Jezeli tak - wcisnij w jedna tabele i dodaj pole TYP enum('artykul', 'galeria') czy podobne - latwiej bedziesz mogl wyciagac statystyki komentarzy uzytkownikow etc. (choc mozna robic unie, ale po co?)

AD 2.
Zalezy, czy typow masz skonczona ilosc i niezmienna, czy nie. Jezeli pierwsza mozliwosc - ENUM, albo jakis INT. Jezeli druga - lepiej tabelke. Co prawda teoria normalizacji mowi, bys w kazdej sytuacji rozbijal na 2 tabele, ale przy duzym obciazeniu serwera zmusza sie tak glowice dysku do skakania po bazie, co owocuje problemami. Ni mniej ni wiecej powiem tylko, bys sam zastanowil sie, czy potrzebujesz osobnej tabeli.
Go to the top of the page
+Quote Post
quality
post 21.11.2008, 09:12:26
Post #3





Grupa: Zarejestrowani
Postów: 172
Pomógł: 9
Dołączył: 13.02.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Hmm jezeli tabele sa osobne lub jest jest pole enum to moze i jest relacja jeden do wielu, ale nie w takim przypadku jak ja chce zrobic.

Zrobilem zdjecia modelowanej bazy:



To jest pierwszy przypadek w dwoch wersjach.

Tabele comments maja taka sama strukture.

To jest przypadek ktory wydaje mi sie najlepszy. jednak tworzenie dodatkowych 2 tabel. Fakt ze to sa same indeksy i poprawia szybkosc dzialania ale moze jest jakis lepszy sposob o ktorym nie wiem tongue.gif. nie interesuja mnie pola enum 'artykul', 'galeria'. Ma to byc w pelni relacyjna baza danych do duzych stron, a bede sam je programowal wiec chce aby byla dobrze zamodelowana.



Ten jest za to latwiejszy w obrobce ale za to nadmiarowosc danych i nie zgodne ze standardem :/


--------------------
Go to the top of the page
+Quote Post
ddiceman
post 21.11.2008, 13:08:24
Post #4





Grupa: Zarejestrowani
Postów: 326
Pomógł: 121
Dołączył: 23.07.2008
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Dalej nie rozumiem, czemu 'wiele do wielu'? Czy zakladasz, ze ten sam komentarz moze byc i do artykulu i do galerii? Czyli 'wow, fajna galeria' jednoczesnie przypisany i do galerii i do artykulu?

Te 2 schematy nie prezentuja tej samej funkcjonalnosci - pierwszy pozwala na to, co opisalem powyzej. Drugi zapewnia, to, czego moznaby sie spodziewac:
- do jednej galerii (artykulu) moze byc wiele komentarzy
- komentarz jest przypisany do dokladnie jednego artykulu albo zdjecia

Wiec, dla jasnosci, jezeli zalezy Ci na FK, to zrobilbym tabele COMMENTS, z polami
Kod
author,
title,
content,
date,
ip,
active,
author_id,

gallery_id_FK, /* klucz obcy wskazujacy, do ktorej galerii nalezy komentarz, null jesli do zadnej */
article_id_FK, /* klucz obcy wskazujacy, do ktorego artykulu nalezy komentarz, null jesli do zadnej */


Wg tej konstrukcji zawsze jedno z kluczy obcych musi byc NULLem a drugie nie, czyli przydalby sie wtedy trigger:

Kod
CHECK (
    (gallery_id_FK IS NULL AND article_id_FK IS NOT NULL) OR
    (gallery_id_FK IS NOT NULL AND article_id_FK IS NULL)
)


No ale na nieszczescie MySQL nie obsluguje takowych. Chyba, ze praca ma charakter dydaktyczny (a takie mam wrazenie)

Ten post edytował ddiceman 21.11.2008, 13:09:08
Go to the top of the page
+Quote Post
quality
post 21.11.2008, 13:37:51
Post #5





Grupa: Zarejestrowani
Postów: 172
Pomógł: 9
Dołączył: 13.02.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


gallery_id_FK, /* klucz obcy wskazujacy, do ktorej galerii nalezy komentarz, null jesli do zadnej */
article_id_FK, /* klucz obcy wskazujacy, do ktorego artykulu nalezy komentarz, null jesli do zadnej */

No wlasnie o cos takiego mi dokladnie chodzilo. Po prostu nie wiem jak zrobic zeby w jednym polu bylo NULL, zeby jeden komentarz nie byl przypisywany i do artykulu i do galerii.

Sytuacja wiele do wielu po prostu omija ten problem, ale chodzi mi wlasnie o to co piszesz, nie wiem tylko jak to rozgryzc skoro jest napisales.

Nie uzywalem nigdy trigerow w sql. Mozesz cos wiecej powiedziec na ten temat ?

Dzieki z gory

Eh pokombinowalem i wyszlo ze wystarczy dac NULL w tych polach i wszystko ladnie bedzie dzialac. Martwilem sie wczesniej po prostu ze mi sie nie doda komentarz jezeli nie bedzie jednego z id (artykulu czy galeri).
Dzieki

Ale nie rozwiazalem jeszcze tego drugiego watku.
Moze pokaze model bazy bo tak latwiej zrozumiec.

Chodzi o kategorie poszczegolnych modulow. Na pierwszym zdjeciu zrobilem to za pomoca tylko 2 tabel polaczonych relacjami.
Ten sposob wydaje sie najrozsadniejszy, jednak taki model wyglada bardzo zagmatwanie. mysle ze to jest ok jednak nie jestem przekonany do konca.


To jest drugi sposob, w ktorym kategorie sa osobnymi tabelami dla kazdego z modulow



Ten post edytował quality 21.11.2008, 14:44:05


--------------------
Go to the top of the page
+Quote Post
ddiceman
post 21.11.2008, 14:53:01
Post #6





Grupa: Zarejestrowani
Postów: 326
Pomógł: 121
Dołączył: 23.07.2008
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Triggery - jak dorbze pamietam - obecnie sa w MySQL tylko na silniku InnoDB i jezeli rzeczywiscie zalezy Ci na tym mechanizmie, to prawdopodobnie musisz to zrobic w brzydki sposob (podobno, jezeli chce sie powstrzymac MySQL przed wykonaniem zapytania, to nie da sie tego zrobic za bardzo elegancko):
  1. /* tabela w ktorej chcesz chronic pola l1, l2 */
  2. CREATE TABLE liczby1 (
  3. id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  4. l1 INT,
  5. l2 INT
  6. ) ENGINE = InnoDB;
  7.  
  8. /* tabela jedynie do sztucznego wywolywania bledow, z jedna krotka */
  9. CREATE TABLE trigger_trap(
  10. id TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY
  11. );
  12. INSERT INTO trigger_trap VALUE(1);
  13.  
  14. /* trigger */
  15. DELIMITER $$
  16. CREATE TRIGGER sprawdz_liczby BEFORE INSERT ON liczby1 FOR EACH ROW
  17. BEGIN IF (NEW.l1 IS NULL AND NEW.l2 IS NULL) OR (NEW.l1 IS NOT NULL AND NEW.l2 IS NOT NULL)
  18. THEN
  19. INSERT INTO trigger_trap VALUES (1); /* wywolanie puapki - duplikat wartosci */
  20. END IF;
  21. END $$
  22. DELIMITER ;
  23.  
  24. /* testowe kwerendy */
  25. INSERT INTO liczby1 value(NULL, NULL, 1);
  26. INSERT INTO liczby1 value(NULL, 1, NULL);
  27. INSERT INTO liczby1 value(NULL, NULL, NULL);
  28. INSERT INTO liczby1 value(NULL, 1, 1);
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 15:13