Marcin Mackiewicz

Programista JAVA, RS Adware Polska

Wypowiedzi

  • Marcin Mackiewicz
    Wpis na grupie PHP w praktyce... w temacie Generowanie wielopoziomowego menu

    Aby mieć możliwość przeczytania tego posta musisz być członkiem grupy PHP w praktyce...

  • Marcin Mackiewicz
    Wpis na grupie Administratorzy w temacie dobry szybki, bezpieczy i tani router/firewall dla malej...
    17.07.2012, 23:28

    OK. Sprzęty koledzy wymieniają prawidłowo... Ja się pytam po co router skoro za nim stoi komp który robi za bramkę dla reszty sieci?
    Z tego co czytam to jest modem który ma być podpięty do routera a za tym stoi komp na serwer ftp'a i drugi komp który robi udostępnianie dla reszty sieci w firmie.

    Ja bym wziął te bramkę na sieć wewnętrzną i do niej podpiął modem. Potem zrobiłbym tam blokadę na połączenia z zewnątrz z wyjątkiem na port ftp'a a następnie udostępnianie na sieć.
    Dodatkowo postawiłbym tam dhcp'a.
    Serwer ftp jako, że inny komp to przekierowanie portu.

    Po kłopocie. Nie trzeba niczego kupować... kwestia linux'a i odpowiedniej konfiguracji tego co jest...

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie łamigłówka
    16.07.2012, 09:29

    Daniel Wloochacz Grabowski:
    Marcin Mackiewicz:
    Normalne polecił bym Ci crosstab
    select * from crosstab('select "data", id_serii, wartosc from pomiary') as ct( dt date, wartosc_p text, wartosc_q text);
    ale z tego co wiem to w SQLite nie ma takich funkcji....
    Administrator baz danych nie znający podstawowej sztuczki jak zrobić PIVOT'a za pomocą CASE?
    Normalnie nienormalne ;-)

    Kolego zajmuje się PostgreSQL a tam PIVOTE robi się właśnie tak... a z SQLite nie miałem do czynienia...
    http://www.postgresql.org/docs/9.1/static/tablefunc.html

    Mogłem przeczytać manual i podpowiedzieć ale pytający mógł zrobić to samo... Podrzuciłem tylko pomysł...

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie łamigłówka
    15.07.2012, 17:25

    Normalne polecił bym Ci crosstab

    select * from crosstab('select "data", id_serii, wartosc from pomiary') as ct( dt date, wartosc_p text, wartosc_q text);
    ale z tego co wiem to w SQLite nie ma takich funkcji....

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie Budowa zestawu pod PostgreSQL
    14.07.2012, 21:11

    Ze sprzętem super dużo nie pomogę bo mistrzem świata nie jestem. Na moje oko to dużo więcej z tego sprzętu już nie wyciśniesz.
    Jeszcze tylko mam pytanie. Po co tak uparcie pozostajesz przy Windowsie na tym serwerze? Aplikacja gry tego wymaga czy jak?
    Pytam bo bazy przywykłem stawiać na systemach unixowych...

    Tak samo za journaling z tego co wiem odpowiada system plików partycji a przy NTFS'ach czy innych pokrewnych z rodziny Windowsa nie pomoge bo ich nie znam za dobrze i szczerze mówiąc nawet nie wiem czy tam można wyłączyć księgowanie.

    Kilkadziesiąt tysięcy rekordów w tabelach w bazie to nie jest problem bo to tyle co nic. A jak sporządzane są same statystyki? Robi to aplikacja czy engine bazy w postaci zapytania SQL?
    Statsy wyliczane są on-line dla gracza czy to tylko do raportowania wyników gry?

    A o jakich czasach wykonywania przykładowej statystyki rozmawiamy?

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie Budowa zestawu pod PostgreSQL
    13.07.2012, 20:16

    Czytałem tek tekst... tak cały...

    Kolega tu dużo czytał na temat PostgreSQL i jego optymalizacji. Chciał także zastosować podstawkę sprzętową pod bazę w taki sposób jak jest napisane w manual'u dla tej bazy.

    Zastanawia mnie jak wygląda struktura tej bazy i jak są tworzone zapytania sql skoro posuwasz się do dzielenia plików bazy na różne dyski dla bazy mającej kilka GB. To bardzo mała baza.

    Czy na pewno wszystkie zapytania oraz struktura jest tak zoptymalizowana, że więcej wycisnąć się nie da? Czy bawiłeś się konfiguracją samej bazy?

    Swego czasu tej wielkości bazy miałem postawione na 2x550Mhz i 2GB ramu DDR 300 i dostęp do danych mozolny nie był.

    Co do tekstu to poruszasz w nim wiele aspektów dlatego bardzo trudno się do niego odnieść...
    Na twoim miejscu bał bym się przyśpieszać wydajność przez stworzenie systemu pliku bez journaling'u i wyłączenie fsync. Jak serwer padnie i nie odtworzysz wszystkiego.

    Tak samo jeżeli masz dyski SCSI albo SAS (nie pamiętam co tam pisałeś) to nie kombinuj z wrzucaniem WAL'a na jakiś dysk na USB czy jakieś SATA. Strony plików super duże nie są i mogą być obsługiwane przez szybsze dyski.

    Nie powiem nic na pytanie dotyczące podziału na partycje i zachowanie się kontrolera którego używasz. W moim przypadku nie widziałem zasadniczej różnicy przy podziale dysku na partycje i bez podziału.

    Jak dla mnie konfiguracja jest ok i na pewno wiesz co zrobić aby sprzętowo przyśpieszyć wydajność bazy ale czy to na pewno dobra droga?

    Nie pamiętam czy pisałeś jakie planujesz obciążenie tego serwera, ilość użytkowników, ilość żądań do bazy, itp...

    Do użytkowników wypowiadających się:
    Nie macie wrażenia po tym tekście, że Adam orientuje się w temacie i pyta o szczegóły które zna baaardzo wąska grupa osób?

  • Marcin Mackiewicz
    Wpis na grupie Programiści WWW w temacie Prośba o przetestowanie.
    6.07.2012, 00:32

    Ubuntu 12.04 LTS amd_64; Kernel: 3.2.0-26-generic

    Firefox 13.0.1: OK
    Chromium 18.0.1025.168: OK
    Epiphany Browser 3.4.1: OK

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie Archiwizacja zmian w bazie
    3.07.2012, 09:28

    Ogólnie to zależy od tego czy zbierasz do jednej tabeli czy do wielu.

    Ja mam w PostgreSQL tak, że wszystkie dane loguje do jednej tabeli:
    schemat::varchar, tabela::varchar, atrybut::varchar, zmiana::timestamp, uzytkownik::varchar, nowa_wartosc::varchar

    W odpowiednich tabelach mam wyzwalacze które uzupełniają tabelę. Jeżeli zakładam wyzwalacz to zaraz po jego założeniu robie update kolumna = kolumna aby wpisać pierwszą wartość która jest w tabeli.

    Akurat loguje wybrane pola a nie wszystkie i ten sposób się sprawdza bo zawsze wiem jaka była wartość w danym okresie czasu.Marcin Mackiewicz edytował(a) ten post dnia 03.07.12 o godzinie 09:29

  • Marcin Mackiewicz
    Wpis na grupie PHP w temacie tablice otrzymane z _POST i ich wskaźniki
    30.06.2012, 20:04

    Właśnie miałem ci to samo przekleić :)

  • Marcin Mackiewicz
    Wpis na grupie PHP w temacie tablice otrzymane z _POST i ich wskaźniki
    30.06.2012, 19:47

    Pisze drugi raz bo się rozmowa rozwinęła...
    To jak sobie użytkownik posortuje, poprzekłada czy poklika nie powinno mieć znaczenia :)
    Ważne aby konkretna wartość była przypisana konkretnemu identyfikatorowi. Mnie nie interesuje czy element 204 tabeli jest wyświetlany użytkownikowi w wierszu 5. User może sobie np wpisać coś w wierszu 5 a ja zrobię update w bazie danych w wierszu o id = 204

  • Marcin Mackiewicz
    Wpis na grupie PHP w temacie tablice otrzymane z _POST i ich wskaźniki
    30.06.2012, 19:41

    Bardzo dziwne pytanie... Element search[1] o wartości 3 zawsze będzie pod elementem search[1]. To samo dotyczy innych wartości tablicy. Nie ma różnicy jak masz ułożone elementy w strukturze. Zawsze zostaną zwrócone wartości na tych konkretnych miejscach tablicy. Jak chcesz mieć je w innej kolejności to użyj sortowania elementów. Wg tego kodu ostatni element w strukturze DOM będzie pierwszym elementem w tablicy. Piszesz, że chcesz mieć tak jak w DOM...
    Pozmieniaj identyfikatory w DOM albo odwróć tablicę (sortowanie odwrotne) tak aby wartość elementu search[5] znalazła się w search[1].

  • Marcin Mackiewicz
    Wpis na grupie PHP w temacie Problem z duplikatami w zapytaniu MySQL
    30.06.2012, 19:06

    Wiesz w sumie podstawowy błąd to zapisanie tej samej informacji na kilku atrybutach. Przecież przynależność do grupy to rodzaj informacji. Sama informacja powinna być przechowywana w krotkach (wierszach).
    Pała dla osoby projektującej te bazę.
    Skoro zmieniamy zależność mówiącą o przynależności użytkownika do grupy z 1:1 na 1:n to niezbędne jest dodanie tabeli przechowującej listę grup do których należy użytkownik.

    Jeżeli tego nie poprawisz to z tego co kojarze z teoretyki poziom złożoności zapytań będzie mocno rósł. Nie wspomnę już o czasie ich wykonywania oraz potrzebnych do tego zasobach sprzętowych.

    Najgorsze jednak jest to, że ilość grup jest ograniczona z góry do 2 i każdorazowe zwiększenie tego ograniczenia spowoduje, że będziesz musiał przepisywać wszystkie zapytania które wykorzystujesz.

    Dodatkowa tabela, że nie będziesz musiał się tym zajmować w przyszłości. Nie powiem aby to posprzątać to trochę pracy jest ale po jej wykonaniu nie wrócisz do tego tematu już nigdy :)

    Jeżeli jednak nie możesz zmieniać bazy to dodaj te tabele i przepisuj informacje z tych pól do tabeli (zestaw wyzwalaczy) tak abyś mógł pisać prostsze zapytania do bazy. Musisz tylko pamiętać aby a źródłowej tabeli wprowadzić ograniczenie takie, że: id_grupy1 <> id_grupy2Marcin Mackiewicz edytował(a) ten post dnia 30.06.12 o godzinie 19:10

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie Problem - usuwanie starych danych
    27.06.2012, 16:09

    Koledzy się uprali na select count(*) które nie użyje index'u jeżeli jakikolwiek atrybut nie posiada założonego index'u. A'propos ostatniego przykładu... Zliczamy ilość wierszy. Dlaczego zatem planer ma patrzeć na wszystkie atrybuty? Wystarczy że popatrzy na jeden. W tym wypadku najlepiej zrobić count z klucza głównego: select count(i)... Nie będzie sekwencyjnego skanu bo klucz główny z założenia dostaje index.

    Pierwszą rzeczą jaką bym zrobił to partycjonowanie tej tabeli na mniejszych x tabel. Nie wiem jak stare tam są dane ale 1 tabela = 1 rok lub 1 tabela = 1 miesiąc spowodowało by ze zapytania wykonują się szybciej i możesz proces usuwania danych rozłożyć w czasie.

    Proponuje dla tabeli:

    create table klienci (
    id varchar(1),
    dzien date,
    stan int)

    z wpisanymi tymi przykładowymi danymi zrobić zapytanie
    select distinct on (stan) * from klienci where id = 'A';

    To zapytanie zminimalizowane do jednego klienta zwraca te wartości których potrzebujesz (przynajmniej w moim PostgreSQL 9.1.2 tak jest).
    Proponuje napisać funkcje z parametrem przyjmującym id klienta i zrobic
    select nazwa_funkcji(id) from ( select distinct id from klienci);

    w samej funkcji natomiast zrobic
    insert into klienci_new select distinct on (stan) * from klienci where id = '$1';
    Przepisuje potrzebne mi wiersze dla konkretnego klienta. Po zakończeniu starą tabelę można usunąć.
    Pod żadnym pozorem nie korzystaj z identyfikatorów z tej tabeli jeżeli masz słownik klientów (po co skanować tak dużą tabelę nawet z wykorzystaniem index'u jeżeli masz o wiele krótszą).
    Co do przenoszenia do tabeli historycznej proponuje napisać jakiś wyzwalacz który zapisze w historii daną tylko i wyłącznie jeżeli nastąpi zmiana stanu na inny. Jest to trochę śliskie ponieważ, jeżeli w obrębie jednego dnia nastąpi kilka zmian stanu i na końcu dnia stan będzie identyczny jak na początku to system tego nie zarejestruje.

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie Zależności funkcyjne w bazie danych
    26.06.2012, 00:36

    Oj tam. Płatności cząstkowe nie są wcale takie złe jak je malują.

    Wszystko opiera się na odpowiednim przemyśleniu mechanizmu i zaprojektowaniu bazy.
    Zauważ proszę, że każda wpłata (nawet 1 przelew = kwota 2 fv) jest przypisana do konkretnego kontrahenta. To samo dotyczy wysokości należności wynikającej z faktu wystawienia tych fv.

    Zatem kwestia opracowania mechanizmu rozliczania należności względem wpłat...

    Same fv posiadają swój identyfikator, datę wystawienia, termin zapłaty oraz formę płatności. Co za problem automatycznie rozliczać należności według np terminów płatności a jeżeli termin jest ten sam po identyfikatorze. Przy płatności zapisuje jaka kwota została rozliczona (wyjątkiem są wpłaty gotówkowe które powinny być rozliczone przy tej konkretnej fv) czyli przechowuję kwotę pozostałej należności. Jeżeli kwota do zapłaty jest równa 0 to oznacza że płatność została rozliczona. Jeżeli nie jest równa 0 to bardzo łatwo mogę obliczyć jaką kwotę wpłaty (lub całej fv) rozliczyłem:
    KP - KDZ = KRW (kwota płatności - kwota płatności do zapłaty = kwota wpłaty rozliczona dla tej płatności)

    Przy wpłacie natomiast pamiętałbym które płatności (lub całe fv) były rozliczane z danej wpłaty. Nie muszę pamiętać jaka kwota wpłat nie została rozliczona bo nie jest to potrzebne (przy płatnościach jest to wymagane - należy wiedzieć dla których płatności należność nie została uregulowana).

    To czy wszystko zostało rozliczone wiem z salda:
    SW - SP = S (suma wpłat - suma płatności = saldo)

    Teraz jeżeli saldo jest ujemne to znaczy, że kontrahent nie uregulował należności w całości (pomijam branie pod uwagę terminu aby uprościć schemat). Wartość bezwzględna z tej wartości powinna być równa sumie pozostałych do zapłaty płatności (kolumna przechowująca wartość do zapłaty dla konkretnych płatności). Jeżeli wartość jest dodatnia to znaczy, że kontrahent ma nadpłatę a jego wszystkie płatności są uregulowane (kolumny do zapłaty wszędzie mają wartość 0)

    Kwestia tylko nałożyć na to terminy zapłaty w przypadku fv lub terminy ściągnięcia części w przypadku płatności cząstkowych.
    To ma w sumie związek z księgowaniem memoriałowym. Ale to nie działa dla wystawionych FV (bo z tego co wiem to dla każdej księgowej wystawiona FV zawsze wchodzi w przychody danego miesiąca).

  • Marcin Mackiewicz
    Wpis na grupie Programiści WWW w temacie Prośba o ocenę.
    26.06.2012, 00:03

    Oj tam czepia się kolega. Zauważmy, że wiek autora strony to 13 lat. Jak byłem w tym wieku to IE był wersji 4 a proce rzędu prosys 386, 486. Z aplikacjami (stronami) webowymi zaczynałem jak miałem 20. Aż się boje pomyśleć co kolega będzie młody wyczyniał za 7 lat :)

    Jak mnie uczyli tworzenia stron www to się siedziało na notepad'dzie i klepało <html><body> ... i używało podstawowych 16 kolorów a o css nikt nie słyszał (przynajmniej w mojej dawnej szkole)

    Mimo wymienionych wcześniej szczegółów (bo więcej dodać się nie da) ja koledze gratuluje zaciętości i chęci do poznawania / uczenia się.

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie Zależności funkcyjne w bazie danych
    21.06.2012, 20:42

    Nadal nie rozumiem idei cząstkowania kwoty należności. Liczy się tylko czy kwota należności jest równa sumie wpłat.

    Weźmy:
    faktura_v: id, kwota_fv, do_zaplaty, plat_termin, plat_forma

    faktura: id, kwota, plat_termin, plat_forma
    faktura_pozycje: id_faktury, lp_pozycji, vat, kwota_netto, produkt, opis, komentarz

    wplaty_faktury: id, id_faktury, kwota_platy, rodzaj_dokumentu, id_wyciagu, lp_pozycji_wyciagu

    wplaty_wyciagi: id, data_wyciagu, data_importu
    wplaty_wyciagi_pozycje: id_wyciagu, lp_pozycji, id_faktury, kwota_pozycji

    Faktura i fv pozycje opisuja fakture (z grubsza), Wplaty_faktury to lista wpłat dokonanych przez np KP lub przez ręczne księgowanie wyciągu z banku lub automatyczne księgowanie (np MT940).

    Faktura_v to widok na bazie który zwraca listę faktur wraz z informacją o tym jaka kwota pozostała do zapłaty.

    Cząstkowanie płatności to dla mnie zupełnie inna sprawa. Np. mój dostawca internetu wystawia mi jedną, zbiorczą fakturę za cały rok. Ja zaś płacę równą kwotę co miesiąc. Faktura jest jedna a płatności (polecenia zapłaty wystawiane przez dostawcę) dwanaście. Jest to swoiste rozłożenie kwoty należności na x części. Tylko w takim przypadku dzielenie FV ma sens; w każdym innym wierzyciel ma nadpłatę lub niedopłatę względem kwoty należności. Teraz każda płatność jest przypisana do fv a wpłata korelowana jest zarówno z FV jak i z konkretną płatnością.

  • Marcin Mackiewicz
    Wpis na grupie PHP w temacie UTF-8 to latin2
    20.06.2012, 21:27

    Grzegorz Wieczorkowski:
    piki czcionek mam z innej wersji sklepu tj. PrestaShop.PL_1.4.4.1-stable i tam to wszystko działa. w sumie to też nie rozumiem dlaczego tam nie jest to załatwiane bezpośrednio utf-8 w zasadzie całego fpdf pliki podmieniłem z tego sklepu. Mapy czcionek próbowałem poszukać niestety nie udało się a konwertowanie programem tt... coś tam dalej wywaliłem go bo wcale nie chciał działać. ale skoro pliki ze sklepu presty tam działają, to zupełnie nie rozumiem dlaczego to ś u mnie nie chce.
    Jakieś pomysły ??

    Jeżeli tylko przy generowaniu pliku *.pdf nie ma polskich znaków i używasz gotowego narzędzia takiego jak 'fpdf' lub 'mpdf' to problemem są zawsze czcionki które mimo prawidłowego kodowania nie posiadają polskich znaków w swojej mapie. Nie pozostaje nic innego jak stworzenie własnych czcionek z prawidłową mapą. Z tego co kojarze to przy 'fpdf' jest dokładny opis jak to sobie zrobić ale nie ukrywam, że na pewno napotkasz problemy (dopasowanie tego dla mnie nie było takie proste).

  • Marcin Mackiewicz
    Wpis na grupie PHP w temacie UTF-8 to latin2
    20.06.2012, 21:04

    A dlaczego po prostu nie podać bazie w jakim kodowaniu ma zwracać? To przecież rozwiąże cały problem.
    Szkoda, że nie ma informacji co to za baza danych...

    Dla PostgreSQL:

    set client_enciding = 'UTF-8';

    Dla MySQL:
    set names 'utf8';
    set character set utf;

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie Zależności funkcyjne w bazie danych
    20.06.2012, 09:46

    Hmm,

    Dziwne że przy relacji 1 faktura <-> n pozycji miałeś problem a przy relacji 1 kontrahent <-> n faktur takiego problemu nie miałeś :)

    Fajny diagram tylko nie rozumiem dlaczego można przypisywać rodzaj płatności do konkretnej pozycji. Z tego co wiem to cała fv jest albo przelew albo gotówka. Na to tylko się narzuca wpłaty a przy fv wylicza (lub przechowuje) ile pozostało do zapłaty...

  • Marcin Mackiewicz
    Wpis na grupie Bazy Danych w temacie Postgresql - widok i wydajność, pytanie
    13.06.2012, 23:49

    Moim skromnym zdaniem to kwestia indeksów. Najprawdopodobniej na samym końcu planer porównuje daty w loop'ie. Mówiłeś, że tabele są spore objętościowo... Mam nadzieje, że co jakiś czas indeksy są przebudowywane oraz jest robione vacuum :)

    Czy samo zapytanie źródłowe z tymi dodatkowymi parametrami w where działa taka samo czy w każdym przypadku szybko?

    Może zamiast dwóch parametrów w where spróbuj użyć jedego

    beetwen data_od and data_do

    Rozwiązania dwa:
    Dodanie indeksów lub przeniesienie danych z where do warunków w join'ie.

    Prawdą jest, że przy dużym skomplikowaniu zapytania w widoku planer glupiał i zamiast korzystać z indeksów porównywał wiersze 1:1 ale tylko przy starszych bazach (Postgres < 8.3).

    Kiedyś rozwiązałem takie coś wykonywaniem zapytania w funkcji gdzie odpowiednie dane wrzucałem do warunków w join'ach co pozwalało znacznie ograniczyć ilość rekordów która zwracała tabelkę o kształcie danego widoku/tabeli.

    Tak jak piszą przedmówcy wszystko do odczytania z explaine z zapytania. Michał ma rację. Każdorazowe wywołanie widoku powoduje wykonanie zapytania z definicji widoku (taki skrót do często używanych złączeń tabel) i w sumie jest traktowane prawie jak
    select * from ( select ... ) as widok...
    Marcin Mackiewicz edytował(a) ten post dnia 13.06.12 o godzinie 23:50

Dołącz do GoldenLine

Oferty pracy

Sprawdź aktualne oferty pracy

Aplikuj w łatwy sposób

Aplikuj jednym kliknięciem

Wyślij zaproszenie do