Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Inser z podzapytaniem wielowierszowym
Forum PHP.pl > Forum > Bazy danych > MySQL
Avatarus
witam
mam 2 tabele:
  1. CREATE TABLE IF NOT EXISTS `handlarze` (
  2. `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `typ` tinyint(3) UNSIGNED NOT NULL,
  4. `id_gracza` bigint(20) UNSIGNED NOT NULL,
  5. `czas` bigint(20) UNSIGNED NOT NULL,
  6. `slot_1` bigint(20) UNSIGNED NOT NULL,
  7. `slot_2` bigint(20) UNSIGNED NOT NULL,
  8. `slot_3` bigint(20) UNSIGNED NOT NULL,
  9. `slot_4` bigint(20) UNSIGNED NOT NULL,
  10. `slot_5` bigint(20) UNSIGNED NOT NULL,
  11. `slot_6` bigint(20) UNSIGNED NOT NULL,
  12. `slot_7` bigint(20) UNSIGNED NOT NULL,
  13. `slot_8` bigint(20) UNSIGNED NOT NULL,
  14. `slot_9` bigint(20) UNSIGNED NOT NULL,
  15. `slot_10` bigint(20) UNSIGNED NOT NULL,
  16. PRIMARY KEY (`id`)
  17. ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=3 ;


Druga tabela zawiera id,nazwa.
Potrzebuje zrobic zapytanie która do 1 tabeli doda id,typ,id_gracz,czas (te dane są z poziomu php generowane) a na dodatek dodaj w pozostałe 10 pól wynik podzapytania:
  1. SELECT id FROM przedmioty ORDER BY rand() LIMIT 10


Próbowałem to zrobić tak:
  1. INSERT INTO handlarze (id,typ,id_gracza,czas,slot_1,slot_2,slot_3,slot_4,slot_5,slot_6,slot_7,slot_8,slot_9,slot_10) VALUES(NULL,1,1,1111111,(SELECT id FROM przedmioty ORDER BY rand() LIMIT 10))

ale nie działa
Macie jakieś sugestie?
cojack
Bo tak się nie da, możesz zrobić:
  1. INSERT INTO
  2. ...
  3. VALUES
  4. SELECT
  5. ....
  6. FROM
  7. ...
  8. ;


@edit
thek Ty to masz natchnienie w pisaniu, kiedy jakaś książka?
thek
Dla mnie sam pomysł z takim układem jest nieco dziwny. Lepiej by było moim zdaniem zrobić osobną tabelę handlarzy-graczy i osobną jego slotów,czyli ta dodatkowa tabela miała by formę mniej więcej:
sloty:
id_gracza: int UNSIGNED NOT NULL,
id_slotu: tinyint UNSIGNED NOT NULL,
zawartosc: bigint UNSIGNED NOT NULL,
index(id_gracza)

Dzięki temu możesz dowolnie modyfikować dostępność slotów zależnie od poziomu, obciążenia czy czego tam chcesz. No i modyfikacja slotów jest znacznie prostsza. To kasowanie lub wyzerowanie danego rekordu. Zaś uzupełnienie mógłbyś oprzeć o wariacje na temat tego co podał cojack smile.gif
Avatarus
tak tylko takie rozwiązanie doprowadzi co znacznej redundancji danych jeśli się nie mylę.
W moim rozwiązaniu zakładając że jest na razie 2 handlarzy po 10 slotów każdy daje nam to max 2 rekordy w bazie z prostą edycją.
Gdyby każdy slot u każdego handlarza byłby osobnym rekordem to w takim wypadku był by 20 rekordów zamiast 1.
Udało mi się to rozwiązać problem przypisywania przedmiotów pod sloty rozbijając to zapytanie na 2 mniejsze i ładowanie wyników pierwszego do tabeli a potem do 2 zapytania z insertem.
thek
Najwyżej ograniczy się i/lub wywali kolumnę nr_slotu jeśli nie jest konieczna i wsio. W takim wypadku powiedz mi co będzie nadmiarowe... 10 slotów z czego 8 puste, czy jedynie 2 rekordy? Bo dla mnie to pierwsze, czyli trzymanie rekordu w którym 8 pól jest wypełnione pustką. Na dodatek architektura jest nie skalowalna, a jakakolwiek ingerencja polegająca na zmniejszeniu lub zwiększeniu schowka wymusza konieczność zmiany liczby kolumn w tej tabeli. O ile jeszcze zwiększanie to nie problem, to zmniejszyć nie można sobie ot, tak, bo mógłbyś użytkownikom coś skasować w usuwanych kolumnach. A tak możesz robić to bez obaw z dodatkowym info: "Skrzynka pęka w szwach i niedługo się rozsypie. Zmniejsz liczbę przedmiotów w niej." i gdy doszła by do określonej wielkości zniknąłby napis ale już niemożliwe byłoby przekroczenie wielkości maksymalnej. Poza tym wyobraź sobie choćby schowek wielkości 70-100 pól. Tabela z 104 kolumnami? Niby wszystko int i powinno być szybkie, ale dużo pól, z czego, przynajmniej początkowo, większość niewykorzystana. Do tego co dochodzi jeszcze? Sprawdzanie które pola są, a które nie są puste. Będziesz leciał pętlą po wszystkich komórkach rekordu by sprawdzać gdzie są 0 a gdzie nie? A może dodatkowy algorytm, który przesuwałby przedmioty z dalszych pozycji ku początkowi, by usuwać owe luki? Jak widzisz, rozwiązanie może jest i fajne na pierwszy rzut oka, ale w przyszłości tylko sprawi więcej problemów. Może i fajnie wygląda teraz, ale gorzej z oprogramowaniem jego działania. Przemyśl to na tym etapie, bo jeszcze zapewne nie implementujesz rozwiązań na sztywno i możesz pozwolić na zmiany w projekcie większe także. Oszczędzisz wkurzania się w przyszłości przy zmianach, gdy będziesz musiał za każdym razem zmieniać liczniki w pętlach by dopasować do zmienianych długości i jakieś algorytmy pisać dziwne. Poza tym jeszcze jedno... Jeśli poprogramujesz trochę, to sam zauważysz, że czasem nadmiarowe dane są lepsze niż wymyślać obciążające zapytania, które zajadą bazę. Przykładem jest licznik postów na forum. Myślisz, że za każdym razem forum to liczy userowi? Byś bazę zarżnął wywołując kilkanaście countów w chwili obciążenia serwisu setkami lub tysiącami userów winksmiley.jpg Od tego jest dodatkowe pole w rekordzie danych usera, które tę daną statystyczną przechowuje.
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.