emil1702
24.06.2012, 18:24:35
Witajcie
Moja jedna z tabel wygląda wygląda następująco
nazwa: biegi
idbiegu z1 z2 z3 z4 cz1 cz2 cz3 cz4
z1, z2, z3, z4 - to id zawodnika, natomiast cz1, cz2, cz3, cz4 - to czasy zawodników.
Chciałbym, aby wszystko zostało posortowane według czasów, a więc.
z2, czas 44:44
z1, czas 45:44
z3, czas 45:45
z4, czas 60:00
dodatkowo, aby czasy zawodnika 1 były zawsze oznaczone kolorem czerwonym, zaw 2 niebieskim itd.
Jakie zapytanie do bazy mysql pomoże mi to najłatwiej wykonać?
Crozin
24.06.2012, 18:29:21
Masz nieprawidłową strukturę tabeli. Powinieneś mieć dwie tabele: 1) biegi (id), 2) uczestnicy (id, id_biegu, id_zawodnika, czas). Mając normalną strukturę danych, będziesz mógł to bez problemu posortować i wyświetlić.
emil1702
24.06.2012, 18:33:45
Dziękuje za podpowiedź, zrobie tak jak mówisz. Pozdrawiam
lukaskolista
25.06.2012, 07:37:45
struktura tabeli jest prawidlowa - jezeli w biegu moze brac udzial 4 zawodnikow (gra zuzlowa) i nigdy nie bedzie moglo byc ich wiecej
phpion
25.06.2012, 07:57:09
@lukaskolista:
Nie jest prawidłowa. Czy jeśli chciałbyś przechowywać statystyki przebiegniętych kilometrów przez piłkarzy (akurat na czasie) to stworzyłbyś 22 kolumny? W sumie nawet to byłoby mało - w międzyczasie wchodzą jeszcze przecież rezerwowi, więc musiałbyś przewidzieć 28 kolumn
d3ut3r
25.06.2012, 07:58:28
Cytat
struktura tabeli jest prawidlowa - jezeli w biegu moze brac udzial 4 zawodnikow (gra zuzlowa) i nigdy nie bedzie moglo byc ich wiecej
Ja bym się z tym nie zgodził, trzeba poczytać o normalizacji baz danych i ogólnie o projektowaniu struktur, najkrócej tworząc tabelę biegi przechowujesz dane dotyczące biegu (dystans,nazwa trasy,data rozpoczęcia itp.) czas zawodnika nie jest daną która do tego kryterium pasuje . Właśnie dlatego są to relacyjne bazy danych aby z tych relacji skorzystać.
lukaskolista
25.06.2012, 09:58:51
Tak tak, mialem teorie na studiach... Chyba nie powiecie mi, ze lepiej miec 4x wiecej rekordow do przeszukiwania. Czasami trzeba zrobic cos inaczej, niz mowi teoria, aby bylo to bardziej optymalne. Widzialem skrypt oparty na takiej strukturze (wlasnie gra zuzlowa) i wlasnie taka struktura spelnila swoje zadanie.
phpion:
sa tabele po 100 kolumn i jakos to dziala

Cytat
W sumie nawet to byłoby mało - w międzyczasie wchodzą jeszcze przecież rezerwowi,
nie porownuj tego do pilki noznej, tutaj liczby sa stale, w zuzlu nie ma zmiennej ilosci zawodnikow. Bazy danych projektuje sie pod konkretne rozwiazania, a nie zgodnie z jakas tam teoria. Jak juz mowimy o normalizacji, to zadam Wam pytanie: nigdy nie robicie redundancji w celu przyspieszenia czeogs? A wlasnie... jednak zdarzaja sie odstepstwa od teorii.
Crozin
25.06.2012, 10:07:21
Cytat
Chyba nie powiecie mi, ze lepiej miec 4x wiecej rekordow do przeszukiwania.
Tutaj? Zdecydowanie lepiej. Dodawanie, pobieranie (wyszukiwanie) i aktualizacja danych będzie w zdecydowanej większości przypadków szybsza. Ach, i najważniejsze. Praca programisty będzie wielokrotnie szybsza.
Cytat
Wam pytanie: nigdy nie robicie redundancji w celu przyspieszenia czeogs? A wlasnie... jednak zdarzaja sie odstepstwa od teorii.
Oczywiście, że się takie coś robi. Ale w większości przypadków nadal pozostawia się znormalizowane dane i jedynie część z nich dubluje na potrzeby jednego, dwóch czy pięciu mechanizmów. Dla reszty - i na przyszłość - pozostaje normalna forma danych.
phpion
25.06.2012, 10:08:16
@lukaskolista:
Tyle tylko, że już teraz ~emil1702 ma problem z sortowaniem danych. Później może chcieć uzyskać jakieś dodatkowe statystyki zawodników i znowu pojawią się problemy. Jeśli nie ma jasnych przesłanek ku temu by denormalizować strukturę bazy (np. wybitne kwestie wydajności) to moim zdaniem nie należy tego robić. Prędzej czy później dostaniemy pstryczka w nos
lukaskolista
25.06.2012, 10:17:24
Cytat
Tyle tylko, że już teraz ~emil1702 ma problem z sortowaniem danych
Jezeli wszystko na sile chce zrobic po stronie bazy danych to ze wszystkim bedzie mial problemy.
$result = mysql_quert("SELECT * FROM...");
$row->z1 => $row->cz1,
$row->z2 => $row->cz2,
$row->z3 => $row->cz3,
$row->z4 => $row->cz4,
);
juz nie ma problemu

Edit:
Cytat
dodatkowo, aby czasy zawodnika 1 były zawsze oznaczone kolorem czerwonym, zaw 2 niebieskim itd.
tego to juz sie niestety w sortowaniu nie zrobi, podczas iteracji tablicy w 1 przebiegu trzeba pokolorowac element w HTML-u.
phpion
25.06.2012, 10:32:57
Hehe, no pewnie. Czasy (jak i inne dane) można zapisywać w postaci stringa bo przecież i tak będą sortowane w PHP

Nie popadajmy w skrajność. To może inny przykład: mamy w bazie X (dużo) informacji o biegach. Chcemy teraz pobrać informację o najszybszym zawodniku. Ok, można użyć LEAST, ale wówczas nie mamy możliwości skorzystania z ewentualnego indeksu.
lukaskolista
25.06.2012, 10:40:22
Cytat
Hehe, no pewnie. Czasy (jak i inne dane) można zapisywać w postaci stringa bo przecież i tak będą sortowane w PHP
Jak w postaci stringa? W bazie danych typ powinien byc float, a nie string, jeszcze ktos wezmie to do siebie i zacznie uzywac typu text do kolumn przechowujacych liczby zmiennoprzecinkowe.
Cytat
Ok, można użyć LEAST, ale wówczas nie mamy możliwości skorzystania z ewentualnego indeksu.
Tak, nie mamy takiej mozliwosci. W tym przypadku niestety trzeba skorzystac z 4 indexow, co jest faktycznie bez sensu. Ja tylko mowie, ze do tego konkretnego zastosowania ta struktura jest dobra

Pozostaje pytanie: jak bardzo przerobka struktury bazy wplynie na aplikacje? Bo jesli trzebaby przerabiac pol aplikacje to nie wiem, czy jest sens.
Crozin
25.06.2012, 10:42:05
@lukaskolista: Na siłę bronisz swojego zdania, tak więc by uświadomić Ci jaką głupotę palnąłeś:
1. Pokaż zapytanie, które poza biegami i identyfikatorami zawodników (bo przecież tylko to tutaj mamy) pobierze: dane zawodnika takie jak imię nazwisko czy data urodzenia z tabeli z zawodnikami, listę osiągnięć dla każdego zawodnika (jeden zawodnik ma wiele osiągnięć) oraz listę ulubionych współzawodników zawodnika (relacja wiele-do-wielu pomiędzy zawodnikami).
2. Pokaż zapytanie, które poda średni czas przejazdu dla danego toru.
3. Pokaż zapytanie, które zwróci rekrod toru - najkrótszy czas przejazdu.
Prawo copy'ego-pasta może się tutaj przydać.
d3ut3r
25.06.2012, 10:43:23
Moim zdaniem lepiej przerobić ją dziś na spokojnie (a w międzyczasie zastosować półśrodek) niż jak baza będzie pokaźna i przeróbka będzie wymagana natychmiast.
phpion
25.06.2012, 10:45:12
Z tym typem pola to był żarcik. Skoro sortujesz w PHP to typ danych po stronie MySQL nie ma większego znaczenia.
Jeśli natomiast chodzi o sortowanie to nawet jeśli założysz 4 indeksy to nic Ci to nie da. Musiałbyś mieć indeks założony na LEAST(cz1, cz2, cz3, cz4) na co MySQL chyba nie pozwala (PostgreSQL już tak). Co do zmian w strukturze bazy: jeśli jest to początek to prac to moim zdaniem warto to za wczasu przerobić. Jeśli natomiast jest to już działający system to szkoda zachodu. Trzeba radzić sobie na tym, co jest.
@Crozin:
Co do Twoich "zadań".
1. Dołączenie danych zawodnika możesz zrobić aliasami - JOIN zawodnicy AS zawodnik_1. Pozostałe 2 punkty nie dotyczą tego konkretnego przypadku, a mając ID zawodnika można je pobrać mniej-więcej w analogiczny sposób.
2. AVG((cz1 + cz2 + cz3 + cz4) / 4).
3. MIN(LEAST(cz1, cz2, cz3, cz4)).
Nie twierdzę, że obecna struktura jest prawidłowa, bo nie jest. Prawda jest jednak taka, że postawione przez Ciebie zadania można spokojnie zrobić. Mniej wydajnie niż przy poprawnej strukturze, ale można
lukaskolista
25.06.2012, 10:48:36
Crozin:
nie pokaze bo byloby troche pisania przy tym. Jak juz napisalem na samym poczatku: dobra do tego, konkretnego rozwiazania (jesli chodzi o sortowanie po czasie zawodnika). Do innych rozwiazan jest beznadziejna.
phpion:
Cytat
Musiałbyś mieć indeks założony na LEAST(cz1, cz2, cz3, cz4) na co MySQL chyba nie pozwala (PostgreSQL już tak)
Chodzi o index nalozony na wiecej, niz 1 kolumne?
phpion
25.06.2012, 11:02:16
Cytat(lukaskolista @ 25.06.2012, 11:48:36 )

Chodzi o index nalozony na wiecej, niz 1 kolumne?
Nie, o indeks będący wynikiem funkcji.
emil1702
4.07.2012, 21:43:50
Witajcie ponownie
Zmieniłem wygląd bazy na następujący:
id - idbieg - idzaw - czass - czas1 - czas2 - czas3 - czas4
czass - czas startu, czas1 - czas pierwszego okr itd
Jak teraz najlepiej posortować i pokolorować dane czasy, aby jak najmniej obciążać stronę.
Chciałbym, aby wyglądało to tak.
idzaw z najlepszym czas4, drugi, trzeci, czwarty.
najlepszy czass, drugi, trzeci, czwarty
najlepszy czas1, drugi, trzeci, czwarty itd
Kolory czasów według tabeli id, najniższa liczba to kolor czerwony, potem niebieski, biały i żółty
Crozin
4.07.2012, 21:48:12
Czy mnie oczy nie mylą czy masz dokładnie ten sam problem co w pierwszym poście?
emil1702
4.07.2012, 21:52:25
Cytat(Crozin @ 4.07.2012, 22:48:12 )

Czy mnie oczy nie mylą czy masz dokładnie ten sam problem co w pierwszym poście?
Zmieniłem układ tabeli według Waszych, m.in. Twojej podpowiedzi, ale chciałbym poznać Waszą opinię dotyczącą sposobu na najlepsze posortowanie tych danych.
d3ut3r
5.07.2012, 00:27:11
Cytat
Zmieniłem wygląd bazy na następujący:
id - idbieg - idzaw - czass - czas1 - czas2 - czas3 - czas4
Raczej nie o to nam chodziło

(Mi na pewno nie o to, Crozin podejrzewam również miał coś innego na myśli).
Chodziło mi o tabele:
Kod
Zawodnicy:
id|imie|nazwisko
Biegi:
id|nazwa_biegu
Wyniki
id_zawodnika|id_biegu|czas
i teraz, za pomocą selecta możesz pobrać wszystkich zawodników biorących udział w biegu x i posortować wg kolumny czas z tabeli wyniki.
emil1702
5.07.2012, 17:14:17
Cytat(d3ut3r @ 5.07.2012, 01:27:11 )

Raczej nie o to nam chodziło

Zrobiłem oczywiście inne też, tylko ich nie podałem, bo chodzi mi teraz o operacje na jeden tabeli gdzie są czasy zawodników, czyli
biegzaw.

Kod
zawodnicy:
id | imie | nazwisko | wiek | umiejetnosc1 | umiejetnosc2 | talent | itd
mecz:
id | data | godzina | gosp | gosc | wynikgo | wynikgc
meczzaw:
id | idmecz | idteam | idzaw | pkt
bieg:
id | idmecz | nrbiegu | wynikgo | wynikgc
biegzaw:
id | idbieg | idzaw | czass | czas1 | czas2 | czas3 | czas4
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.