Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL] Relacja 1:1
tadeurz
post 11.06.2013, 23:41:54
Post #1





Grupa: Zarejestrowani
Postów: 70
Pomógł: 1
Dołączył: 25.04.2009

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


Nie mogę sobie poradzić z prostą rzeczą, głupią relacją 1:1.
Rozwiązanie znałazem w 2 zapytaniach, ale coś czuje że można to zrobić w lepiej.

Mam 2 tabele:
  1. //tabela user_box user_id(PRIMARY) plus setka pól z nazwami jako zwykłe cyfry. W każdej szufladzie(box) znajduje się ID prezentu.
  2. user_box -> user_id,1,2,3,4....97,98,99,100
  3. gift -> id,type,who


Chce pobrać wszystkie szufladki i typ prezentu który się tam znajduje.

Ten post edytował tadeurz 11.06.2013, 23:43:34
Go to the top of the page
+Quote Post
nospor
post 12.06.2013, 08:19:49
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




manual mysql -> LEFT JOIN


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
tadeurz
post 12.06.2013, 13:22:17
Post #3





Grupa: Zarejestrowani
Postów: 70
Pomógł: 1
Dołączył: 25.04.2009

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


Nawet nie muszę zaglądać do manuala.

JOIN LEFT z 2 upośledzeniami będzie wyglądało tak:
  1. SELECT
  2. user_box.*
  3. gift.type,
  4. FROM
  5. user_box
  6. LEFT JOIN gift ON
  7. gift.id = user_box.1 OR
  8. gift.id = user_box.2 OR
  9. gift.id = user_box.3 OR
  10. gift.id = user_box.4 OR
  11. gift.id = user_box.5 OR
  12. .........
  13. gift.id = user_box.98 OR
  14. gift.id = user_box.99 OR
  15. gift.id = user_box.100
  16. WHERE user_box.id = ?

Trudno to nazwać problemami raczej upośledzenia mySQL biggrin.gif
1. Przy złączeniu trzeba wypisać pola 0-100. Zamienienie tego na SELECT ? WHERE id IN (SELECT? ) nic nie da bo pola i tak trzeba będzie wypisać (w klauzuli IN będziemy chcieli wszystkie pola BOXów oprócz id(PRIMARY) a nie da się tego zrobić inaczej niż wypisać).
Przy 2 SELECT używam pętli, więc na jedno wychodzi.
2.Tabele wynikowa będzie cholernie wielka. Napisze kilka przykładowych WIERSZÓW:
1. (ID) _ (ID_GIFT_1) ? (ID_GIFT_2) _ (ID_GIFT_3) - ... - (ID_GIFT_98) _ (ID_GIFT_99) _ (ID_GIFT_100) _ (TYP_GIFT_1)
2. (ID) _ (ID_GIFT_1) ? (ID_GIFT_2) _ (ID_GIFT_3) - ... - (ID_GIFT_98) _ (ID_GIFT_99) _ (ID_GIFT_100) _ (TYP_GIFT_2)
3. (ID) _ (ID_GIFT_1) ? (ID_GIFT_2) _ (ID_GIFT_3) - ... - (ID_GIFT_98) _ (ID_GIFT_99) _ (ID_GIFT_100) _ (TYP_GIFT_3)
....
99. (ID) _ (ID_GIFT_1) _ (ID_GIFT_2) _ (ID_GIFT_3) - ... - (ID_GIFT_98) _ (ID_GIFT_99) _ (ID_GIFT_100) _ (TYP_GIFT_99)
100. (ID) _ (ID_GIFT_1) _ (ID_GIFT_2) _ (ID_GIFT_3) - ... - (ID_GIFT_98) _ (ID_GIFT_99) _ (ID_GIFT_100) _ (TYP_GIFT_100)

JOIN LEFT ? Może tutaj jest błąd struktury bazy danych, którą trzeba inaczej zaprojektować i wtedy cały problem zniknie.
Mam użytkowników którzy mają plansze 10x10 -> na niej chowają prezenty. Pozostali gracze strzelają w pole odkrywając prezent który się tam skrywa. Zrobienie z tego 1 tabeli w której jest pole i od razu GIFT jest rozwiązaniem na siłę. Każdy strzelony GIFT jest zapisywany, wiec musiałbym po trafieniu go, przenieś do nowej tabeli.

Ten post edytował tadeurz 12.06.2013, 13:29:05
Go to the top of the page
+Quote Post
mmmmmmm
post 12.06.2013, 14:09:24
Post #4





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

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


Masz chorą strukturę.
5 pól:
-id,
-id_gift,
- numer_pola,
-trafiony,
-kto_trafił
Go to the top of the page
+Quote Post
tadeurz
post 12.06.2013, 15:25:09
Post #5





Grupa: Zarejestrowani
Postów: 70
Pomógł: 1
Dołączył: 25.04.2009

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


No właśnie struktura jest dobra.
Powyżej oczywiście skracałem tabele, aby pokazać istotę problemu. mmmmmmm dla informacji z jednego pola (w przykładach powyżej chciałem tylko wiedzieć jaki jest typ prezentu ) Twoje rozwiązanie jest dobre.
Tabela gift jest bardziej rozbudowana, sam prezent to obiekt z 10 polami:
  1. Gift:
  2. ID
  3. owner
  4. typ
  5. name
  6. count
  7. prize
  8. reHit
  9. data_hit
  10. data_limit
  11. creates


Nie chce korzystać z żadnych bibliotek ORM, które zrobią to co chce w 1 linijce. Owe biblioteki muszą to jakoś robić. Sam temat założyłem tylko dla upewnienia się czy nie ma lepszego rozwiązania niż 2 odrębne SELECT, bo byłoby dziwne że mySQL nie ma nic do tak prostej relacji.

Ten post edytował tadeurz 12.06.2013, 15:26:23
Go to the top of the page
+Quote Post
bpskiba
post 12.06.2013, 15:34:38
Post #6





Grupa: Zarejestrowani
Postów: 340
Pomógł: 49
Dołączył: 3.07.2009
Skąd: Rzeszów

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


Jest to wzorcowy przykład z cyklu "jak nie budować struktury bazy"
gdybyś miał tabele:
1 użytkownicy
2 boxy
3 uzytkownicy_boxy(id_uzytkownicy, id_boxy, id_prezentu,id)
4 prezenty
To nie było by problemów z zapytaniami i ilością boxów.




Ten post edytował bpskiba 12.06.2013, 15:40:02
Go to the top of the page
+Quote Post
tadeurz
post 12.06.2013, 16:36:52
Post #7





Grupa: Zarejestrowani
Postów: 70
Pomógł: 1
Dołączył: 25.04.2009

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


Przypuszczam, że niechcący pomyliłeś się w zapisie. Masz 100% racje wprowadzenie jeszcze jednej tabeli pośredniczącej pomiędzy USER<->BOX rozwiąże problem z zapytaniem.

Poprawiona struktura:
  1. USER -> id
  2. BOX -> id, GIFT.id
  3. USER_BOX -> USER.id, BOX.id
  4. GIFT ->id


Takie rozwiązanie bardzo szybko namnoży nam wierszy w tabelach. Dla 1 użytkownika musimy utworzyć 100 wierszy w BOX i USER_BOX.
Mam przeczucie, że to jest PODRĘCZNIKOWE rozwiązaniem mojego problemu (problemu który przy tym rozwiązaniu nie istnieje). Ale jakoś nie jestem przekonany, zostanę przy 2 SELECT.

Nie chce zamykać tematu, dlatego jak ktoś miał podobny problem i rozwiązał go jakoś inaczej niż 2 SELECT to śmiało. Osobiście czekam na odpowiedź nospor'a.
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: 13.06.2025 - 06:12