![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Witam. Pytanie czysto teoretyczne: jak najlepiej trzymać kategorie artykułu przyjmując, że będzie go można przydzielić do kilku kategorii?
Naczytałem się trochę w Google, ale mam mątwik w głowie - wszystkie znalezione przeze mnie sposoby mają tylko wady a żaden ni jednej zalety (tak twierdzą postujący). |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
W osobnej tabeli, przy czym mogłaby ona posiadać dodatkową kolumnę mówiącą o priorytecie kategorii.
CATEGORIES: { id, name } ARTICLES: { id, title, content } ARTICLES_CATEGORIES: { article_id, category_id, category_priority } EDIT: Jeśli nie ma jakiejś kategorii głównej dla danego artykułu, to ta trzecia kolumna jest zbędna. Ten post edytował mortus 1.01.2012, 12:32:10 |
|
|
![]()
Post
#3
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
|
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Domyślam się. Musisz to zmienić, jeśli jeden artykuł może posiadać więcej niż jedną kategorię, to potrzebujesz dodatkowej tabeli realizującej relację wiele do wielu. W tej chwili masz relację jeden do wielu - jedna kategoria może być przypisana wielu artykułom.
|
|
|
![]()
Post
#5
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Czyli trzymanie w tut_kat_id ID wielu kategorii, nie jest dobrym (optymalnym) rozwiązaniem?
|
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Czyli trzymanie w tut_kat_id ID wielu kategorii, nie jest dobrym (optymalnym) rozwiązaniem? Jakimś rozwiązaniem jest, ale na pewno nieoptymalnym. EDIT: Gwoli uzupełnienia. Jeśli każdy z artykułów może mieć - dajmy na to - trzy do pięciu kategorii, to i takie rozwiązanie przejdzie. Ale jeśli liczba artykułów i kategorii z biegiem czasu znacznie wzrośnie, podobnie jak i liczba użytkowników, to np. przeszukiwanie po kategorii będzie prawdziwą katorgą dla serwera baz danych. Według mnie jedynym słusznym rozwiązaniem jest stworzenie dodatkowej tabeli, bowiem przy takiej strukturze bazy danych zbudowanie zapytania będzie dużo łatwiejsze, a samo manipulowanie danymi będzie bardziej wydajne. Ten post edytował mortus 1.01.2012, 13:28:05 |
|
|
![]()
Post
#7
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Czy tak wystarczy, czy mam jakieś indeksy zakładać?
Jak mam rozwiązać zapytania? Do tej pory miałem tak (kategorie):
Ten post edytował Kshyhoo 1.01.2012, 13:46:46 |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Zdaje się, że operacje na tabeli zdecydowanie przyspieszy PRIMARY KEY na dwie kolumny jednocześnie, czyli:
Co do zapytania, to jakoś tak:
Choć to tak na szybko wymyślone i dopiero później mogę ewentualnie poprawić. Ten post edytował mortus 1.01.2012, 14:02:48 |
|
|
![]()
Post
#9
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Przeglądając to, coś spłodziłem i nawet nieźle wygląda:
gdzie dwie pierwsze kolumny to poziomy kategorii a trzecia to zagłębienie. Mam teraz jedynie problem, ze zliczeniem artykułów w poszczególnych kategoriach. Przedtem działałem tak:
|
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
A to zapytanie, które wyżej napisałem daje jakieś wyniki? Pisałem "na szybko", bo musiałem wyjść i nie wiem, czy działa i czy działa prawidłowo.
|
|
|
![]()
Post
#11
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Zwraca błąd Unknown column 'kat_id' in 'field list' .
W sumie, ja nadal nie wiem, jak to trzymać w bazie - jak artykuł ma mieć wiele kategorii. |
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
To może po polsku (kolumny przykładowe).
KATEGORIE: { id_kategorii (klucz główny) nazwa } ARTYKUŁY: { id_artykułu (klucz główny) tytuł, data_utworzenia } KATEGORIE_ARTYKUŁÓW: { id_kategorii (klucz obcy połączony z tabelą KATEGORIE kolumną id_kategorii) id_artykułu (klucz obcy połączony z tabelą ARTYKUŁY kolumną id_artykułu) ważność (kolumna dodatkowa określająca, która z kategorii jest ważniejsza - kolumnę tę można pominąć) } Nie do końca wiem, co ma robić to zapytanie. Ma liczyć liczbę artykułów/tutoriali w każdej z kategorii? Czy może ma liczyć do ilu kategorii należy dany artykuł/tutorial? Z tymi kategoriami jest dokładnie tak samo, jak z tagami (słowami kluczowymi) opisującymi dany artykuł. |
|
|
![]()
Post
#13
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Czyli, jak dobrze rozumiem, KATEGORIE_ARTYKUŁÓW ma wiązać całość:
Kod id_artykułu | id_kategorii 1 | 1 1 | 4 1 | 5 2 | 1 2 | 2 2 | 4 2 | 6 Czyli, że artykuł ID=1 należy do kategorii ID=1, 4, 5 a artykuł ID=2, do kategorii ID=1, 2, 4, 6... Ten post edytował Kshyhoo 1.01.2012, 20:11:25 |
|
|
![]()
Post
#14
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Dokładnie, wtedy zapytaniem:
wyciągniesz identyfikatory, nazwy oraz liczbę artykułów dla każdej z kategorii. |
|
|
![]()
Post
#15
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Mam problem jedynie z kluczami obcymi, bo baza w MyISAM.
No i muszę znaleźć sposób, na wybór i zapis (również edycję) wpisów w bazie poprzez PHP. No i pobierałem artykuł tak:
Teraz trzeba będzie to zmienić. Ten post edytował Kshyhoo 1.01.2012, 20:53:55 |
|
|
![]()
Post
#16
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Nie ma znaczenia, czy to MyISAM, czy InnoDB. Najwyżej nie założysz kluczy obcych, a poza tym i tak wszystko w PHP musisz zrealizować. Wybór to proste potrójne złączenie, a zapis to po prostu dwa zapytania w tym MULTIINSERT.
|
|
|
![]()
Post
#17
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Jak mniemam, moje zapytanie o pojedynczy rekord powinno wyglądać tak:
Zmieniłem nieco moje zapytanie i wygląda ono obecnie tak:
Jednak, gdy artykuł ma kilka kategorii, w phpMyAdmin mam kilka takich samych wyników, różniących się jedynie ID kategorii. Jaki mam zastosować warunek, żeby tego uniknąć? |
|
|
![]()
Post
#18
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Ta nadmiarowość jest jak najbardziej zrozumiała (i nawet do wybaczenia), ale można się jej pozbyć łącząc wszystkie kategorie za pomocą GROUP_CONCAT:
|
|
|
![]()
Post
#19
|
|
Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Ja bym się już zastanawiał nad silnikiem. Liczba artykułów z czasem rośnie. Modyfikacje tabeli złączeniowej będą może nie tak częste, ale w MyISAM głupi update czy insert robią lock na całą tabelę :/ Lepiej przejść na InnoDB w przypadku złączeniówki i mieć tylko lock na konkretne wiersze. Ogólnie mortus dobrze radzi i sam identycznie postępuję. Co do edycji lub dodania to masz zapewne MySQL, więc nie widze problemu:
1) Dodajesz nowy artykuł: INSERT zwróci Ci id nowo dodanego. Tylko go podstaw do złączeniówki (IMG:style_emoticons/default/smile.gif) 2) Uaktualniasz artykuł: Najprościej DELETE istniejących aktualnie i insert wybranych przez usera. W wersji inteligentniejszej porównujesz stare i nowe. Usuwasz to, które są w starej wersji i dodajesz te, których w starej nie ma. Plus jest taki, że może Ci się zredukować całość do tylko usuwania albo tylko dodania. Minus? Zapewne usunięcie i dodanie według pierwszej metody będą szybsze niż po stronie php z kombinowaniem co ma być dodane, a co usunięte (IMG:style_emoticons/default/smile.gif) |
|
|
![]()
Post
#20
|
|
Grupa: Opiekunowie Postów: 3 855 Pomógł: 317 Dołączył: 4.01.2005 Skąd: że ![]() |
Ufff, udało mi się wymodzić takiego potwora:
Odebrać mógłbym tak:
I działa. Nie wiem teraz tylko, jak mam do zapisać do bazy, gdzie mam takie pola
czyli muszę zapisać, kilka id_kat z jednym id_tut Podpowie mi ktoś? Da się to zrobić na raz, czy pętlą? PS. Oczywiście, brak filtrowania (nie bijcie za mocno)... EDIT. Coś Geshi się buntuje, całe szczęście miałem kopię (IMG:style_emoticons/default/wink.gif) Ten post edytował Kshyhoo 3.01.2012, 23:27:49
Powód edycji: [Spawnm]: hmm coś się zepsuło :P
|
|
|
![]() ![]() |
![]() |
Aktualny czas: 10.10.2025 - 17:29 |