Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Formularz, walidacja i inne
Forum PHP.pl > Forum > Przedszkole
mirobor
W ramach edukacji, wyznaczyłem sobie zadanie nad którym poległem. Złe założenia na początku spowodowały, że muszę zasięgnąć porady/pomocy.
Oczywiście nie proszę o gotowe rozwiązanie a o kopniaki w dobrą stronę.
Temat w sumie wydaje się prosty. Użytkownik wybiera/głosuje na 10 filmów z 50.
Formularz zawiera 50 chceckboxów i tyle.
W bazie mam tabele dla film_votes oraz user_votes.
W film_votes mam

|id|director|title|votes|

Ponieważ chcę mieć także głosy poszczególnych userów (tylko dla zalogowanych) wymyśliłem to tak:

user_votes
|user_id|f1|f2|f3|f4|f5|f6|f7|f8|f9|f10|

z czego fx to film_votes.id na które oddał głosy

Chcę, aby po walidacji formularza były zliczane głosy i jeżeli np zagłosowano na 7 to user mógł jeszcze zagłosować na 3, ale oczywiście nie te same filmy.

Pytanie 1.
Czy struktura user_votes jest optymalna dla tego co chcę wytworzyć?

Pytanie 2.
Przy pierwszym głosowaniu dla user_votes użyję INSERT, przy kolejnych(jeżeli nie wykorzystał 10 głosów) UPDATE. Jak optymalnie napisać oba zapytania sprawdzając jednocześnie:
Czy user nie oddał więcej niż 10 głosów?
Czy user nie głosuje 2 razy na ten sam film?

Na razie tyle. CDN. Z góry dziękuję za pomoc w edukacji.
markuz
Twoja tabela user_votes nie jest optymalna. A co jeśli stwierdzisz, że można głosować jednak na 5 filmów? Poza tym, przez taką strukturę nie możesz w łatwy sposób wychwytywać czy np. użytkownik juz zagłosował na dany film, ile istnieje głosów na dany film, na ile filmów uzytkownik zagłosował itp.

Moja propozycja:

films
- id
- director
- title

users
- id
- login
- password

votes
- film_id
- user_id

Teraz wprowadzając małą modyfikację - dodając do tabeli votes pole created_at (DATETIME) możesz wyłonic np. najpopularniejsze filmy w miesiącu itp.

Poczytaj o relacjach tabel, o łączniu tabel w SQL (JOIN).
mirobor
Bardzo dziękuję. Właśnie o to mi chodziło. Faktycznie Twoja propozycja z votes wydaje się być optymalna. Poczytam napiszę trochę kodu i CDN.
kartin
Poczytaj sobie o postaciach normalnych, normalizacji baz danych.
mirobor
Poczytałem o normalizacji i zrozumiałem, że taki układ tabel będzie optymalny. Czytam o JOIN.
Przy wcześniejszym podejściu do bazy głosy były zapisywane dla każdego filmu w tabeli film_votes Każdy nowy głos uaktualniał pole votes (). Mogłem dzięki temu w prosty sposób prezentować aktualne wyniki dla każdego filmu.
Przy aktualnym podejściu muszę zliczać ilość wystąpień id filmu w tabeli votes. Czy to oznacza, że dla 50 flmów muszę wykonać 50 zapytań?
kartin
Cytat(mirobor @ 24.05.2014, 13:24:02 ) *
Przy aktualnym podejściu muszę zliczać ilość wystąpień id filmu w tabeli votes. Czy to oznacza, że dla 50 flmów muszę wykonać 50 zapytań?


Poczytaj sobie tez ogólnie o składni SQL (w szczególności SELECT) i co do czego służy.

Jeśli chcesz pobrać liczbę głosów oddanych na każdy z filmów to można to zrobić za pomocą jednego zapytania:
  1. SELECT f.title, COUNT(f.id) AS vot
  2. FROM votes v JOIN films f ON (v.film_id = f.id)
  3. GROUP BY f.id
  4. ORDER BY 2 DESC


Jeśli chodzi o te co mają np. więcej niż 10 głosów to:
  1. SELECT f.title, COUNT(f.id) AS vot
  2. FROM votes v JOIN films f ON (v.film_id = f.id)
  3. GROUP BY f.id
  4. HAVING COUNT(f.id) > 10
  5. ORDER BY 2 DESC
mirobor
Dziękuję, ale ja chcę pobrać całą listę z films i przedstawić wyniki. Nawet te na które nie oddano żadnych głosów (0).
Tak aby pętla:
  1. foreach ($rows as $row) {
  2. echo $row->title.'-'.$glosy;
  3. }

gdzie $glosy to ilość głosów.
Kombinuję jak zmodyfikować zapytanie:
  1. SELECT *, COUNT(f.id) AS vot
  2. FROM votes v JOIN films f ON (v.film_id = f.id)
  3. GROUP BY v.film_id
  4. ORDER BY 2 DESC

... ale coś mi nie idzie.
Czytam o JOIN, ale nie idzie to łatwo.



Dobra. Doczytałem i zrozumiałem, że będzie to: $row->vot.
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.