Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: czy taka baza będzie smigać?
Forum PHP.pl > Forum > Bazy danych > MySQL
dyziekwik
witam, chciałbym się dowiedzieć a może bardziej upewnić czy projekt króry właśnie szykuje ma rację bytu. Będzie to baza danych w MySQL. w tej bazie będzie ok 15 tabel o wymiarze 3000wierszyx500kolumn więc w moim mniemaniu całkiem dużo. Taki wymar jest chyba najlepszą opcją dla mojego serwisu.
czyli:

_________nazwa1__nazwa2__nazwa3__nazwa4......
element1______0______1______0______1
element2______1______1______0______0
element3______1______0______0______1
element4______1______0______1______0
:
:
:
wiec tak wygląda idea jednej z 15 tablic. nazw bedzie ok 500, elementów ok 3000. W wartościach będzie true or false, czyli 0 i 1.
Cały bajer polega na tym, że użytkownik wybierze sobie powiedzmy ok 15 nazw i zadaniem serwera będzie zwrócić wszystkie elementy które zawierają się w zadanym zbiorze, czyli mają jedynki w odpowiedniej kolumnie. czyli np. zadaje mu, że ma szukać po nazwach 1,3 i 4 i powinien zwrócić elementy 3 i 4. Jeden element będzie miał ok 10 jedynek w wierszu, czyli ok 490 pól będzie zerami. Sposób szukania mam juz opracowany i będzie to szukanie nie po "jedynkach" czyli tam gdzie element występuje, ale po "zerach", dzięki czemu wyeliminuje rekordy niespełniające założenia. Nie wiem czy to aby dobry pomysł... czy nie zamuli serwera... wielkość całej bazy (to znaczy jej zawartości) szacuje na jakies 8-10Mb czyli relatywnie nie dużo, za to będzie masa szukania.
Proszę powiedzcie czy MySQL pociągnie takie szukanie. przewiduję może i optymistycznie, że odwiedzin stron będzie ok 10000 dziennie (przynajmniej na tyle chciałbym, aby strona była przygotowana)
Czy MySQL to dobra opcja? Z góry dziękuję za odpowiedz.
Pozdrawiam!
Mchl
Baza danych to nie arkusz kalkulacyjny, a ty coś takiego tworzysz. Próbowałeś to normalizować?

Maksymalnie możesz mieć w tabeli 4096 kolumn i 65536 bajtów w wierszu, więc się mieścisz. Sam projekt mi się nie podoba i to niezależenie od silnika na jakim miałby chodzić. Może jakbyś więcej szczegółó podał, to dałoby się lepiej zrozumieć zamiar.
dyziekwik
dzięki za komentarz. więc generalnie zamiar jest taki: jest ok 500 złów kluczowych (czzyli kolumny) i mam powiedzmy 50000 rekordów. kazdy rekord sklada się z jakiejś tam liczby tych słów, powiedzmy ze około 15 (nie będzie więcej niż 30). użytkownik wybiera sobie jakąs tam ilość słów kluczowych i baza ma mu zwrócić wszystkie rekordy w których ich słowa zawierają się w zadanych słowach. czyli
mam dany
element1 o słowach (1, 3, 5)
element2 o słowach (2, 3, 5)
element3 o słowach (1, 3, 4)

a uytkownik wybierze (1,3,4,5,7) to program ma zwrócić element1 i element3. I tak jak mówie słów będzie ok 500 (wiem jakie to będą słowa) a elementów (rekordów) ok 50000.
można zrobić tabele tak:

__________id______słowa__________costam1________costam2
element1___1_____1 4 5 8___________blabla__________blabla
element2___2_____1 3 6 8___________blabla__________blabla
element3___3_____2 4 6 7___________blabla__________blabla
:
:
:
gdzie blabla to dodatkowe nie istotne dane dotyczące elementu.
W komurce słowa umieszczałbym słowa dotyczące danego elementu, ale obawiam się, że szukanie danego rekordu za pomocą ciągu słów może trwać bardoz długo. wydaje mi się, że najrozsądniej jest zrobić taki arkusz kalkulacyjny, zajmie mniej miejsca na dysku, za to będie miał 500 kolumn zamisat 5... słowa będą wyrazami, zatem każde słowo będzie się składało powiedzmy z 10-12 liter. można w celu usprawnienia zastąpić je cyframi(zzajmie mniej miejsca i algorytm szukania powinien mieć łatwiej) tak mi sie przynajmniej wydaje.
Mam nadzieję ze istota funkcjonalności jest teraz jasna. Może MySQL ma taką możliwość szukania zbiorów zawierających się w zadanym zbiorze??
Mchl
Cytat(dyziekwik @ 8.12.2009, 09:04:17 ) *
Może MySQL ma taką możliwość szukania zbiorów zawierających się w zadanym zbiorze??


Cała istota relacyjnych baz danych opiera się na arytmetyce zbiorów.

Większość systemów bazodanowych, w tym MySQL, lepiej pracuje mając tabele 'wąskie' ale 'długie', dlatego normalizacja jest tutaj jak najbardziej wskazana.
Nie mówiąc o tym, że być może tobie jest po prostu FULL TEXT search potrzebny?
dyziekwik
wiec zadam takie pytanie
mam zbiór:
X {1 2 3 4 5 6 7 8 9} - zawierające wszystkie słowa

nastepnie tworze podzbiory:

A {1 3 6 7}
B {3 5 6}
C {3 6}
D {2 3 7 9}

wybieram następnie zbiór Z {2 3 5 6 8} i zadaniem bazy będzie zwrócić wszystkie zbiory które zawierają się w zbiorze Z. czyli B i C. Czy MySQL ma takie możliwości?questionmark.gif
Moja baza danych będzie miała 500 elementów zbioru X i {A B C D....}.length = 50000 szt.smile.gif
Proszę o komentarze:)
Mchl
Robisz tabelę na słowa kluczowa (odpowiednik zbioru X)

  1. CREATE TABLE `slowakluczowe` (
  2. `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `slowo` varchar(45) NOT NULL,
  4. PRIMARY KEY (`ID`)
  5. );
  6.  
  7. INSERT INTO `slowakluczowe` (`slowo`) VALUES
  8. ('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i');



Tabelę na podzbiory A,B,C itd

  1. CREATE TABLE `podzbiory` (
  2. `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `nazwa` varchar(45) NOT NULL,
  4. PRIMARY KEY (`ID`)
  5. );
  6.  
  7. INSERT INTO `podzbiory` (`nazwa`) VALUES
  8. ('A'),('B'),('C'),('D');


Tabelę z zawartością podzbiorów

  1. CREATE TABLE `podzbiory_zawartosc` (
  2. `podzbiorID` int(10) UNSIGNED NOT NULL,
  3. `slowoID` int(10) UNSIGNED NOT NULL,
  4. PRIMARY KEY (`podzbiorID`,`slowoID`) USING BTREE
  5. );
  6.  
  7. INSERT INTO `podzbiory_zawartosc` (`podzbiorID`, `slowoID`) VALUES
  8. (1, 1),(1, 3),(1, 6),(1, 7), /* A = {a,c,f,g} */
  9. (2, 3),(2, 5),(2, 6), /* B = {c,e,f} */
  10. (3, 3),(3, 6), /* C = {c,f} */
  11. (4, 2),(4, 3),(4, 7),(4, 9); /* D = {b,c,g,i} */


No i zapytanie.
  1. SELECT
  2. p.nazwa
  3. FROM
  4. podzbiory AS p
  5. INNER JOIN (
  6. SELECT
  7. pz.podzbiorID AS ID
  8. FROM
  9. slowakluczowe AS s
  10. INNER JOIN
  11. podzbiory_zawartosc AS pz
  12. ON
  13. s.ID = pz.slowoID
  14. WHERE
  15. s.slowo IN ('b','c','e','f','h')
  16. ) AS s
  17. USING (ID)
  18. LEFT JOIN (
  19. SELECT
  20. pz.podzbiorID AS ID
  21. FROM
  22. slowakluczowe AS s
  23. INNER JOIN
  24. podzbiory_zawartosc AS pz
  25. ON
  26. s.ID = pz.slowoID
  27. WHERE
  28. s.slowo NOT IN ('b','c','e','f','h')
  29. ) AS sw
  30. USING (ID)
  31. WHERE sw.ID IS NULL
  32. GROUP BY
  33. p.nazwa

dyziekwik
witam, najmocniej dziękuję za pomoc, tak obszernej pomocy się nie spodziewałem:) analizuje zapytanie bo nie znam kilku poleceń jak inner join, left join . nie śmiem prosić o wytlumaczenie tego zapytania bo i tak juz mase czasu ci zmarnowałem...ale jak byś naprawde nie miał co robić to słówko komentarza do zapytania i jego elementów by nie zaszkodziło:) smile.gif jeszcze raz baaardzo dziekuję za pomoc.
Pozdrawiam!!
Mchl
No to najpierw poczytaj o złączeniach (JOIN) w SQL żebyś wiedział co to takiego, a potem opowiem dlaczego takie zapytanie.
dyziekwik
już poczytałem. teraz wystarczy rozumieć:)
Mchl
No dobra, czyli mamy tak:

  1. SELECT
  2. p.nazwa
  3. FROM
  4. podzbiory AS p


to nam pobiera nazwy wszystkich podzbiorów

złączamy to z

  1. SELECT
  2. pz.podzbiorID AS ID
  3. FROM
  4. slowakluczowe AS s
  5. INNER JOIN
  6. podzbiory_zawartosc AS pz
  7. ON
  8. s.ID = pz.slowoID
  9. WHERE
  10. s.slowo IN ('b','c','e','f','h')


czyli z listą ID tych podzbiorów, w których występują nasze słowa kluczowe

Gdybyśmy tak zostawili, to dostalibyśmy te podzbiory, które oprócz wskazanych przez nas słów kluczowych zawierają też inne, a chcemy mieć tylko wskazane przez nas. Dlatego robimy jeszcze jedno złączenie, tym razem lewe.

  1. SELECT
  2. pz.podzbiorID AS ID
  3. FROM
  4. slowakluczowe AS s
  5. INNER JOIN
  6. podzbiory_zawartosc AS pz
  7. ON
  8. s.ID = pz.slowoID
  9. WHERE
  10. s.slowo NOT IN ('b','c','e','f','h')


to jest lista ID tych podzbiorów, w których występują słowa kluczowe inne niż te wskazane przez nas. Ponieważ złączenie jest lewe, to jeżeli dla danego ID podzbioru nie ma w nim słów kluczowych inne niż te wskazane przez nas, to po złączeniu podstawione zostanie NULL. Te wartości NULL odrzucamy przez
  1. WHERE sw.ID IS NULL

Na koniec grupujemy wyniki po ID podzbioru, tak żeby nam się wyniki nie powtarzały.

Możesz zapuścić takie zapytanie, w którego wynikach widać trochę lepiej co się dzieje.

  1. SELECT
  2. p.nazwa,
  3. s.ID, /* podzbiory w których występują nasze słowa kluczowe */
  4. sw.ID /* podzbiory w których występują inne słowa kluczowe */
  5. FROM
  6. podzbiory AS p
  7. INNER JOIN (
  8. SELECT
  9. pz.podzbiorID AS ID
  10. FROM
  11. slowakluczowe AS s
  12. INNER JOIN
  13. podzbiory_zawartosc AS pz
  14. ON
  15. s.ID = pz.slowoID
  16. WHERE
  17. s.slowo IN ('b','c','e','f','h')
  18. ) AS s
  19. USING (ID)
  20. LEFT JOIN (
  21. SELECT
  22. pz.podzbiorID AS ID
  23. FROM
  24. slowakluczowe AS s
  25. INNER JOIN
  26. podzbiory_zawartosc AS pz
  27. ON
  28. s.ID = pz.slowoID
  29. WHERE
  30. s.slowo NOT IN ('b','c','e','f','h')
  31. ) AS sw
  32. USING (ID)




dyziekwik
brak mi słów... do nóżek padam!!! wszystko kumam, mam tylko jedną wątpliwość, podajemy jakieś tam zadane słowa kluczowe w postaci ('b','c','e','f','h'), czy moge podać tutaj tablice z tymi słowami. będzie ona generowana przez użytkownika więc wpisywanie "ręcznie" za bardzo się nie nadaje.
Jeszcze raz dziękuję i wyrażam pełen podziw i wdzięczność, że chciało Ci się mi pomagać.
Pozdrawiam!!!
Mchl
Jeśli robisz to z PHP, to najprościej zapisać te dane do tablicy, potem implode() z odpowiednimi delimiterami.
Na zapytanie przygotowane niestety nie bardzo się to nadaje.

Cytat(dyziekwik @ 8.12.2009, 20:49:40 ) *
Jeszcze raz dziękuję i wyrażam pełen podziw i wdzięczność, że chciało Ci się mi pomagać.


Spoko. Ja to lubię, bo 3/4 tego co umiem nauczyłem się rozwiązując cudze problemy tongue.gif
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.