Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Gra internetowa - hierarchia klas
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
KOMPsognat
Witam!
Wiem, że jest już jeden temat o tym samym zagadnieniu, lecz dyskusja tam jest według mnie bez sensu.

Do rzeczy: piszę aktualnie dość zaawansowaną grę i chciałbym, żeby była jak najbardziej elastyczna. W grze jest kilka ras (każda ma inne ceny budynków, produkcję itp... ) oraz niektóre parametry są zależne od pory roku (jak na przykład produkcja). Wydaje się, że wystarczy zastosować dekorator, lecz sprawa jest trochę bardziej skomplikowana. Różne pory roku w mniejszym lub większym stopniu modyfikują parametry u różnych ras. Na chwilę obecną było mnóstwo różnych klas w stylu WinterCarthageBakery, SpringCarthageBakery... więc w finalnej wersji wyszłoby mi ponad 600 klas co jest niedopuszczalne i nieelastyczne. Kolejnym pomysłem było coś takiego:

Każda klasa budynku dla danej rasy dziedziczyłaby po jakiejś klasie abstrakcyjnej w której zaimplementowany byłby mechanizm wyboru odpowiedniej zmiennej z danymi (tzn. czy zimową czy może letnią tablicę z kosztami).

W ten sposób ograniczyłbym liczbę klas do ok. 150, lecz rozwiązanie znowu nie jest zbyt elastyczne.

Może macie jakiś propozycje, jak zbudować elastyczniejszy system? Może trzymać ceny w bazie danych i cache'ować tylko te dla danej pory roku? Czekam na wszystkie opinie na ten temat.
NuLL
Cytat
wyszłoby mi ponad 600 klas co jest niedopuszczalne i nieelastyczne
A dlaczego niedopuszczalne ?
KOMPsognat
Ech... złe słowo smile.gif Ale nieelastyczne jak najbardziej. Na jeden budynek przypadałoby wtedy 20 klas (nie licząc interfejsów), więc nie jest to najlepsze rozwiązanie.

Wydaje mi się, że to z bazą danych jest najlepszym rozwiązaniem, gdyż wtedy wszystko można by zmodyfikować z poziomu panelu admina, ale czekam na inne propozycje.

PS. Przy aktualnym systemie należy do tych 600 klas dolicz ok. 200 klas dla jednostek i 100 dla różnych bogów w świątyni... Wychodzi spora liczba samych danych, a modyfikacja tego to byłby koszmar.
dr_bonzo
Kilka przemyslen, moze cie gdzies doprowadza.
[przyjmuje do obliczen 4 pory roku, 3 klasy]

1. pora roku nie moze byc zapisana w klasie budynku, bo gdy zmieni sie pora roku ot bedziesz musial wymienic obiekt budynku (zniszczyc stary utworzyc nowy), czyli SpringCarthageBakery odpada.

2. jak bardzo sa podobne sa do siebie budynki? Wszystkie maja tylko atrybut Produkcja? czy roznia sie ? Produkcja Tego, Prod. Tamtego,inny budynek Tego nie produkuje?

3. jak bardzo roznia sie od siebie budynki roznych ras? To sa te same budydnki rozniace sie tylko wielkoscia produkcji? czy kazda rasa ma specyficzne budynki, o roznej produkcji?

4. jak bardzo rozne sa reguly modyfikujace produkcje? Dla danej pory roku i danej rasy modyfilkator dla wszystkich budynkow bedzie taki sam (4x3 klas) czy inny (4x3xilosc_rodzai_budynkow)?

5. przechowywanie modyfikatorow (dla pogody i rasy) w samym budynkow tez odpada: dodanie nowej rasy to wyedytowanie wszystkich klas budynkow

//
6. Wlasciwie wszytko zalezy od jednolitosci budynkow i jednolitosci wyznaczania modyfikatorow. Jesli budynki sa identyczne a modyfikatory wyrazaja sie "pojedynczym" prostym wzorem

i wtedy:
  1. <?php
  2. $modifier = $season->getProductionModifierFor( $player->race );
  3. $production = $building->getProduction( $modifier )
  4. ...
  5. function getProduction( $mod )
  6. {
  7. return $this->baseProduction * $mod
  8. }
  9.  
  10. // albo
  11.  
  12. return $mod->modifyProduction( $this->baseProduction )
  13. ?>


A jak to w samej bazie wyliczac? -- woooo, nie wiem
KOMPsognat
Ad.1. Czemu odpada? Mam powiedzmy porę roku pobraną z bazy danych i zapisane w jakiejś zmiennej, rasę gracza i typ budynku. Z tego wszystkiego można skonstruować odpowiedni obiekt:
  1. <?php
  2. $class = $season.$tribe.$building;
  3. $object = new $class($level);
  4. ?>


Ad.2. Każdy budynek ma zapisaną w sobie cenę, produkcję na godzinę oraz kilka atrybutów specyficznych dla danego budynku. Wszystkie mechanizmy są dziedziczone po klasie abstrakcyjnej budynku.

Ad.3. Budynki różnią się produkcją i ceną. Specyficzne budynki po prostu nie mają nazwy klasy z przedrostkiem innej rasy niż tej u której występuje.

Ad.4. I tu jest pies pogrzebany. Modyfikacje mogą być różne. To zostanie podniesione, a to wręcz przeciwnie. W zimie u jednej rasy może być coś zwiększone a u innej zmniejszone.

Ad.5. Dodanie nowej rasy to nie modyfikowanie, lecz dodanie ok. 140 klas (na chwilę obecną).

Ad.6. Co do samej bazy danych. Na chwilę obecną widzę to tak: tabele w formacie "SezonRasa" i tam zapisane ceny i produkcja. Te dane byłyby cachowana przy każdej zmianie pory roku. W sumie działa to tak samo jak te setki klas w formacie SezonRasaBudynek, ale modyfikacje łatwiejsze.
dr_bonzo
1-6.
Sorry -- myslalem za bardzo OOP i o aplikacji dzialajacej w czasie rzeczywistym a nie uruchamianej z kazdym requestem



Jak chcesz to z bazy czytac to raczej proscizna:
- w jednej tabeli masz budynki + ich podstawowa produkcje
- w drugiej dla kazdego budynku masz kilka rekordow z modyfikatorami dla (danej pory roku)X(danej rasy)

lub wrzuc do jednej tabeli z koncowymi wartosciami produkcji.
KOMPsognat
Tak też od początku myślałem, ale wpadała mi do głowy jeszcze taka myśl. Brały by udział trzy klasy: budynek (np. Bakery), plemię (np. Carthage) oraz sezon (czyli np. Winter). I teraz widzę to tak:

1. Konstruktor budynku oczekuje nacji gracza
2. Następnie tworzy egzemplarz klasy nacji i pobiera z nich tylko interesującą tablicę (w tym wypadku Bakery) z modyfikatorami parametrów budynku
3. Podczas tworzenia klasy Carthage ta wywołuje konstruktor klasy Winter która zwraca modyfikatory dla danego budynku danej nacji.
4. Klasa Carthage zwraca już dane po "konfrontacji" z danymi z klasy Winter.
4. Gdy klasa Bakery otrzyma wszystkie dane to zwraca ostateczny koszt budynku.

Wymyśliłem to na szybko jadąc w tramwaju, ale może coś się z tego się urodzi coś sensownego. Bardzo prosiłbym o opinie na ten temat.

Aha. Nie przejmujcie się chwilowo modyfikacją parametrów tych poszczególnych klas... Jako tako również mam to obmyślane.

----------
Edit:
----------
Kolejne przemyślenia:

Całkiem przez przypadek wyszedł mi z tego co wyżej napisałem najzwyczajniejszy dekorator:
  1. <?php
  2. $object = new Winter(new Carthage(new Bakery($lvl)));
  3. ?>


1. Klasa Bakery zwracałaby podstawową cenę.
2. Klasa Carthage sprawdza jaki to budynek i wybiera odpowiednie modyfikatory:

  1. <?php
  2. //tablica
  3. $mods = array(
  4. 'Bakery' => array ('tutaj modyfikatory'),
  5. 'Następny budynek' => array ('modyfikatory'));
  6.  
  7.  
  8. //konstruktor klasy Bakery
  9. public function __construct($building) {
  10. return $this->mods[get_class($building)];
  11. }
  12. ?>


3. Na podobnej zasadzie działa klasa Winter, zwracając kolejną tablicę po modyfikacjach.
dr_bonzo
Dekorator to nie bedzie, bo w dekoratorze wszystkie klasy musza byc z tej samej hiearchi, czyli Winter musialby byc Budynkiem, tak samo jak i nacja/rasa.

http://www.dofactory.com/Patterns/Diagrams/decorator.gif


  1. <?php
  2. public function __construct($building) {
  3. return $this->mods[get_class($building)];
  4. }
  5. ?>

To nie przejdzie w takiej formie smile.gif Konstruktor niczego nie moze zwracac, wiem, pospiech itd.
KOMPsognat
Ad.1. Równie dobrze można to nazwać WinterDecorator. Tak mi było szybciej smile.gif Ważne, że miało działać na podobnej zasadzie.

Ad.2. Ostatnio przyszło mi pracować na PHP3, więc jeszcze nie wróciłem do siebie smile.gif Trochę bez sensu byłoby użycie return w konstruktorze biggrin.gif

PS. Problem rozwiązany. Moje cholerne nawyki po niedawnej pracy w przestarzałej wersji php. Po cholerę samym kosztom wydzielać klasę rolleyes.gif Zrobię po prostu stałe z cenami i gotowe.

PS.2. Wystarczy to rozwiązać w taki sposób:
  1. <?php
  2. $building = new Bakery($season, $tribe, $lvl);
  3. ?>

a konstruktor będzie składał to w całość z wartości zapisanych w stałych.
Secator
Swoją drogą w nie lepiej stosować czegoś w stylu:

funkcja pobierzcene( )
{
cena = cena_podstawowa* (1 + rasa1*2 + rasa2*2) + 666*zima +333*wiosna -100*lato
return cena
}

gdzie rasa1 = 1 jesli gracz jest rasą 1, zero jesli jest jakąs inną i podobnie z innymi parametrami...
(w tym wypadku przy cenie podstawowej 1000 cena w lecie dla rasy 1 wynosi np.
3*1000-100=2900)

Jest to chyba prostsze i do wykonania i do późniejszych modyfikacji i wystarczy wtedy mieć tyle klas ile jest różnych budynków bedacych rozszerzeniem klasy budynek zawierajacej wszystko to co każdy budynek posiada ;]
edit:: Ew. żeby budynek dziedziczył modyfikatory po klasie nacji zawierajacej parametr 'pora roku'??
KOMPsognat
Napisałem, że modyfikatory są zróżnicowane. Nie ma zasady, że u rasy1 będzie zawsze 0.7 a u rasy2 1.3 . Modyfikator jest różny dla każdego budynku itp.

Co do rozwiązania problemu. Rozwiązałem to w taki sposób:

Struktura:
Kod
costs
|- rasa1.php
|- rasa2.php
|- ...


Kod poszczególnych plików:
  1. <?php
  2. $budynek1 = array(
  3.  'Winter' => array('Gold' => x, 'Wood' => x, '...'),
  4.  'Spring' => array('Gold' => x, 'Wood' => x, '...'),
  5.  '...' => '...'
  6.  );
  7.  
  8. $budynek2 = array(
  9.  'Winter' => array('Gold' => x, 'Wood' => x, '...'),
  10.  'Spring' => array('Gold' => x, 'Wood' => x, '...'),
  11.  '...' => '...'
  12.  );
  13. ?>


Oraz sama implementacja:
  1. <?php
  2. //...
  3. public function getCosts($lvl, $season, $tribe)
  4. {
  5. include_once ('./costs/'.$tribe.'.php');
  6. return $$this->building[$season]; //zmienna building przechowuje informacje jaki to budynek
  7. }
  8. //...
  9. print_r($building->getCosts(x, 'Winter', 'Romans');
  10. ?>
KG-
No i to jest wg mnie najlepsze rozwiązanie, bawienie się w 600 klas z dziedziczeniem i dekoratorami, jeśli można coś zrobić dużo łatwiej na tablicach to zdecydowanie przerost formy nad treścią, w końcu gra docelowo będzie obsługiwana przez tysiące ludzi więc chodzi o to żeby kod działał jak najszybciej (i jednocześnie był łatwy w modyfikacji) smile.gif

Jedynie zamiast zmiennych $budynek1, $budynek2 itd zrobiłbym po prostu tablice budynków, chyba że to ma jakiś głębszy sens którego nie dostrzegam smile.gif
Secator
Cytat
Napisałem, że modyfikatory są zróżnicowane. Nie ma zasady, że u rasy1 będzie zawsze 0.7 a u rasy2 1.3 . Modyfikator jest różny dla każdego budynku itp.
Myśle ze trzymanie modyfikatorów jako zmiennych nie jest problemem... ale rób jak chcesz :] Sam wiesz lepiej co Ci jest potrzebne.

Swoja droga to wydaje mi sie że ta gra bedzie tak skomplikowana że gracze nie beda w stanie sie połapać biggrin.gif X budynków dla Y nacji z Z parametrami zależnych od Ź czynników... :] Masz już jakąs wersje beta do testów?? Chętnie bym po testował, może własnie coś wartego uwagi powstaje biggrin.gif

pozdro
KOMPsognat
Hehe... akurat w tym przecież nie ma nic trudnego (z punktu widzenia gracza). Każda rasa ma inne ceny budynków i ich produkcję. Trudności może przynieść obsługa pór roku, ale myślę, że gracze sobie poradzą. smile.gif

Co do bety: Chwilowo nie ma. Co do możliwości gry:
  • 5 nacji: Kartagina, Partia, Rzym, Egipt, Grecja
  • 4 pory roku
  • ok. 30 budynków: http://atofaq.yoyo.pl
  • 10 jednostek na każdą nację.
  • możliwość "zbierania" i handlowania niewolnikami.
  • losowe zdarzenia zależne od zadowolenia bóstw w świątynii
  • zaawansowany system bitewny: możliwość grupowania w oddziały, generałowie, dowódcy, formacje wojenne, typy ataku (szarża lub normalny), doświadczenie oddziałów...
  • hołd lenny (przydatna opcja dla osób, którym nie chce się farmić :] )
bacca
Miałem kiedyś taki problem. Jeśli mogę jakoś pomóc to spróbuję.

1. Olej zawieranie takich ilości powiązanych danych na twardo w kodzie. Zrób sobie klasę (lub kilka), która odczytuje swoje parametry dynamicznie na podstawie otrzymanych parametrów. Zrób sobie tabelę i z niej odczytuj wszelkie parametry budynków. W ten sposób znacznie ograniczysz liczbę klas.

2. Zrób sobie edytor parametrów do obsługi tejże tabeli. Tak, żebyś sobie dla danej rasy i pory roku i typu budynku edytowal parametry. W ten sposób łatwiej Ci będzie wypełnić tabelę danymi i korygować późniejszą rozgrywkę.

3. Wszelkie możliwe konfiguracje parametrów danego budynku serializuj i buforuj np. do pliku, żeby nie zarzynać bazy milionami odczytów.

4. Możesz się też zapoznać z wzorcem Prototype i technikami buforowania. To załatwi problem całkowicie.

Gdybym wyraził się niejasno spróbuję zilustrować pseudokodem.

  1. <?php
  2. class Budynek {
  3. private $nazwa;
  4. private $rasa;
  5. private $typ;
  6. private $cena;
  7. private $produkcja;
  8. // itd....
  9.  
  10. public function __construct($typ, $rasa, $pora_roku, $itd, $itp) {
  11. $result = $db->query('SELECT * FROM `budynki` WHERE `rasa` = $rasa AND `pora_roku` = $pora_roku itd.it
    p. '
    );
  12. foreach ($result as $prop) {
  13. $this->$propname = $prop;
  14. }
  15. }
  16. }
  17. ?>

U mnie wyglądało w dużym uproszczeniu mniej więcej tak. Na pocieszenie dodam, że problem da się rozwiązać w kilku do kilkunastu klasach. Powodzenia
KOMPsognat
Chyba zostanę przy swoim pomyśle, gdyż nie będzie trzeba wykonywać zapytania SQL. Podane pliki z cenami będą generowane automatycznie z poziomu admina, więc modyfikacje będą w miarę wygodne.
bacca
Przeczytaj jeszcze raz punkt 3. i 4. Naprawde da sie w ten sposób uzyskać całkiem wydajny sposób odczytywania tych danych.
KOMPsognat
No to muszę przyznać, że Twój sposób drastycznie różni się od mojego... aaevil.gif
Poza tym wydaje mi się, że zapis w postaci tablicy będzie po prostu szybszy (choć testów nie przeprowadzałem). Modyfikacje tego z poziomu admina będą zapisywane w bardzo łatwy sposób - skasowanie i utworzenie nowych plików z cenami.

Trudne? Nie sądzę.
Elastyczne? Tak.
Szybkie? Tak.

Same zalety :]
Ace
heh... Nie po to sa bazy danych, zeby zapisywac potrzebne rzeczy w plikach...

To moze zrob sobie zarzadzanie tego z poziomu bazy, a takie generowanie plikow php z dokladnymi informacjami potraktuj jako cache?

Ja osobiscie wykonalbym to na bazie danych. Latwo znalezc, latwo zmienic, latwo dodac.
KOMPsognat
I łatwo zerżnąć komputer. Jeżeli mam wykonywać ok. 1000 zapytań na sekundę po same ceny to ja dziękuję...
Ace
Przeczytaj dokladnie to co napisalem.

Baza to podstawa, a twoja watpliwosc to cache? heh
KOMPsognat
Racja. Nie dopatrzyłem tego cache :]
Nie muszę mówić, że zmęzenie, pośpiech itp... ? biggrin.gif

Myślę, że temat jest już do zamknięcia (nie wiem jak inni) smile.gif
KG-
Cytat(Ace @ 12.02.2007, 13:22:40 ) *
Przeczytaj dokladnie to co napisalem.

Baza to podstawa, a twoja watpliwosc to cache? heh


Pozwolisz że zapytam - cache zapytań masz na czym? Na plikach? smile.gif No chyba że na memcache, co i tak nie zmienia faktu że memcache także ma ograniczone możliwości (choć przyznam że są one ogromne).

Druga kwestia - wyobraź sobie że coś zmieniasz, np statystyki przedmiotu (co w dorosłej produkcji robi się bardzo rzadko - gracze nie cierpią gdy zmienia się coś w trakcie rozgrywki i przy pierwszej okazji cię za to zagryzą, zwłaszcza jeśli płacą za grę) i zmieniasz to na 500 serwerach. Teraz musisz połączyć się do 500 serwerów, wykonać zapytania a potem jeszcze dodatkowo uruchomić skrypt który wyczyści cache aby zmiany były widoczne. Musisz przy tym mieć ustawione w bazie danych by można się było łączyć z zewnątrz (mało bezpieczne rozwiązanie).
Zapisując dane w plikach odpalasz skrypt który wykonuje svn update po kolei na każdym serwerze a php acceleratory same zauważają że plik się zmienił. Oba rozwiązania są dobre ale to drugie wydaje mi się wygodniejsze na dłuższą metę (choć jest to kwestia gustu i przyzwyczajeń).
Pozdrawiam smile.gif
dr_bonzo
Cytat
Teraz musisz połączyć się do 500 serwerów, wykonać zapytania a potem jeszcze dodatkowo uruchomić skrypt który wyczyści cache aby zmiany były widoczne. Musisz przy tym mieć ustawione w bazie danych by można się było łączyć z zewnątrz (mało bezpieczne rozwiązanie).
Zapisując dane w plikach odpalasz skrypt który wykonuje svn update po kolei na każdym serwerze a php acceleratory same zauważają że plik się zmienił.


Capistrano (http://manuals.rubyonrails.com/read/book/17 ): umozliwia ci wykonanie tych zamych (lub innych) zadan (skrypty schellowe) na wielu maszynach, obsluga SVN, laczy sie przez ssh. Trzeba dopisac wlasne taski (zadania -- czyli te skrypty updatujace) i update robisz jednym poleceniem smile.gif
Turgon
Szczerze powiem jak update się robi, to tak czy siak jest to rzadkie... W przypadku zwłaszcza komercyjnych systemów smile.gif Dlategóż, można też przyjąć strategię jak plemiona.pl . Nowy serwer = nowa wersja gierki smile.gif
KOMPsognat
No właśnie ten cennik będzie dość często modyfikowany przy produkcji nowych gier. Mimo wszystko myślę jednak, że oparcie tego na plikach w formacie jaki pokazałem wcześniej będzie najlepszym rozwiązaniem.
Ace
Hehe, a powiedz mi jaka jest roznica miedyz wykonaniem na 500 serwerach svn up... a uzyciem jakiegos skryptu bashowego ktory sciagnie tobie plik PHP z instalacja nowej wersji, ktory sam bedzie wiedzial jak zmigorwac caly system do nowej wersji. Czasem roznice w plikach, a czasem w bazie? A tak plik z update sciagasz sobie, z konsoli jest uruchamiany powiedzmy w nocy. Sciaga skrypt SQL, wykonuje go w transakcji + zmienia pliki kodu (Tu mozna uzyc np: svn up) i po ptakach...

Trzymanie wszystkiego w plikach textowych - uwierz mi, ze to sie nie uda. Po to wymyslil ktos baze danych, zeby tam skladowac potrzebne inforamcje, a nie rozrzucac je po katalogach na dysku w formacie plikow textowych... Cache powiedzmy moze sie odswiezac co jakis czas... np: Po takim update moze automatycznie cache byc kasowane.

@KG-:
Nie udostepniasz bazy na zewnatrz...

Logujesz sie po ssh, wykonujesz komende i tyle. Zawsze mozesz przemycic do kodu gry jakas akcje odpowiedzialna za update systemu. Cron co dzien w nocy laczy sie z twoim serwerem, sciaga definicjie xml'a, sprawdza czy jest nowsza wersja - JEST. Sciaga paczke, unzipuje, wykonuje komendy sql, wgrywa nowe pliki, uruchamia pliki php odpowiedzialne np: za skonwertowanie starej bazy do nowego formatu, przeprowadza testy jednostkowe, i jesli jest wszystko ok, to konczy proces.

Masz 500 serwerow - bo o takiej skali zaczoles mowic smile.gif to ulatwi proces jeszcze bardziej niz zalogowac sie 500 razy i zrobic svn up...
KG-
Cytat
Trzymanie wszystkiego w plikach textowych - uwierz mi, ze to sie nie uda.

Uwierz mi że nie tylko się uda ale już się udało, działa bardzo ładnie przy 1000+ użytkowników jednocześnie smile.gif

Cytat
Masz 500 serwerow - bo o takiej skali zaczoles mowic smilingsmiley.gif to ulatwi proces jeszcze bardziej niz zalogowac sie 500 razy i zrobic svn up...

Ja nigdzie nie pisałem żeby się logować, można odpalać svn update zdalnie na wszystkich serwerach jednocześnie. Jakbym przy każdym update-cie się musiał logować na ssh po kolei na wszystkie serwery, to bym chyba jakiejś choroby nerwowej dostał winksmiley.jpg

Jak pisałem wyżej - kwestia przyzwyczajeń, ja wychodzę z założenia żeby oszczędzać bazę i memcache bo one mają ważniejsze rzeczy do roboty niż wczytywać dane które się zmieniają raz na 2 miesiące albo rzadziej.
Ace
Czyli robiłeś testy i mówisz, że baza nie wytrzyma 1000+ użytkowników?
KG-
Wytrzyma czy nie wytrzyma to zbyt generalne pojęcie winksmiley.jpg
Zależy która baza, jaki engine, na jakim sprzęcie, co musi zrobić w pojedynczym żądaniu itd.
Na mysql 4.1 bez cache-owania było już momentami ciężko przy ok 1400 użytkownikach jednocześnie (klikających w miarę często, w końcu to gra) na dedyku z 3gb ramu. Obciążenie bazy danych potrafiło osiągnąć 50-60%, po zastosowaniu memcache spadło do ok 15-25%. Mimo wszystko wolę zapisywać takie rzeczy w plikach, łatwiej mi edytować plik pod edytorem niż logować się do bazy i wykonywać zapytania + czyścić cache.

A jak ktoś nie używa memcache i robi cache na plikach, to wrzuca do bazy dane, które i tak zostaną zapisane w pliku i z pliku będą odczytywane. Kolejna kwestia - wolisz zapis w bazie ze względu na wygodę zmian - jak pisałem wcześniej w dorosłej produkcji nie dasz rady zmieniać czegoś co chwilę, gracze naprawdę nie lubią jak zmienia się coś w trakcie gry winksmiley.jpg
Vogel
MySQL lepiej sobie odpuścić do takich projektów. PostgreSQL albo MSSQL. Od kiedy przerzuciłem się na postgresa to mysqla wspominam tylklow koszmarach winksmiley.jpg zupelnie inny komfort pracy
mike
~Vogel przerzuć się na wspomnianego przez siebie MS SQL'a. Dopiero będziesz miał koszmary. Ta baza to porażka.

W tej sytuacji PostgreSQL wydaje się być najlepszym rozwiązaniem.
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.