MySQL DATE() dla pola DATETIME

Jul 17

MySQL DATE() dla pola DATETIME

Oblicza MySQL nie są do końca znane przy tworzeniu aplikacji, a problemy optymalizacyjne stają się nie lada problemem przy funkcjonowaniu wersji produkcyjnej projektu. Nie sposób przewidzieć wszystkich możliwości użycia pól, założenia zarówno wspólnych, jak i pojedynczych indeksów posiadających zakładaną przez nas moc i zajętą pamięć na dysku.

Ostatnimi czasy budowałem dość skomplikowany projekt, jeżeli chodzi o złożoność zapytań i wykonywanych przez nie operacje matematyczne. Pomimo tego, że aplikacja była doskonale przemyślana, a struktury bazy danych perfekcyjnie jej podporządkowane, gdzieś tkwił problem, bowiem jedno z zapytań generowało pozornie prosty (wizualnie) rezultat, baza reagowała na zapytanie dopiero po 2.5 sekundy dla 30k+ rekordów. Patrząc na strukturę kluczy i zapytania, zwłaszcza, że pola, na których operowałem były różnego rodzaju liczbami i datami zacząłem się poważnie martwić i rozkładać zapytanie na czynniki pierwsze, kończąc na warunkach. Wyobraźcie sobie moje zdziwienie, gdy doszedłem do tego, że całe obciążenie (ponad 2.3 sekundy) generował warunek:

WHERE DATE(ticket_date) >= " ... "

Gdzie ticket_date to pole typu DATETIME. Od razu doszedłem do wniosku, że w parze idzie złe przygotowanie danych przez PHP, a angażowana jest w to wszystko baza, na której forsuje się użycie funkcji DATE(). Przynajmniej dla 30k+ rekordów zindeksowanego pola. Prosty zabieg zamiany jednej linijki kodu na drugą przyniósł porządane efekty.

$aTerms[] = 'DATE(ticket_date) >= "' . $sDate . '"'
$aTerms[] = 'ticket_date >= "' . date('Y-m-d H:i:s', strtotime($sDate)) . '"'

Budując aplikację zwracam szczególną uwagę na strukturę bazy, indeksowanie pól, rysuję diagramy przewidujące wykorzystanie danych pod różne zapytania, ale… tak banalny błąd przy przeanalizowanej aplikacji rozłożył mnie na łopatki. Z drugiej strony, zapomniałem o jednej bardzo ważnej rzeczy: maksymalnym odciążeniu bazy danych przy preparowaniu argumentów warunków, skoro warunki te mogą być w odpowiedni i przede wszystkim szybki sposób spreparowane na poziomie modelu (abstrakcyjnie rzecz ujmując, pozbywam się pojęcia PHP), który przygotują zapytanie tylko do wykonania operacji na surowych danych, bez konieczności ich ewentualnego przeliczania. Oczywiście nie zawsze taki efekt da się uzyskać, ale należy to maksymalnie optymalizować.

Jedno jest wiadome: przeliczanie DATE() dla rekordów w warunku jest nieoptymalne dla pola DATETIME.

Read More

Allegro nie zawsze wygodne

Jul 30

Allegro nie zawsze wygodne

Jestem zwolennikiem ułatwiania sobie życia wykorzystując Internet do robienia zakupów i zarządzania swoim kapitałem. Natomiast po ostatniej akcji na Allegro, zacząłem wątpić w moje ograne ideały, uznaję to za ostrzeżenie i poprawiam markerem cienką linię pomiędzy realnym shoppingiem, a dokonywania zakupów via Allegro na znacznie grubszą. Zamiast kupić pada do Play Station 3 kiloma kliknięciami, musiałem ruszać tyłek po kilku instytucjach.

Wszystko zaczęło się 25 czerwca, kiedy postanowiłem zakupić wcześniej wspominanego pada. Mam zwyczaj, że jeżeli jest opisana procedura płatności za przedmioty, a kontrahent jest Super Sprzedawcą, robię to od razu po dokonaniu zakupu – tak było i tym razem. System Sello wysłał mi potwierdzenie złożenia zamówienia.

Od 26.06 do 07.07 obserwowałem status wysyłki. Przelewu nie zaksięgowano po 13 dniach, stąd status wysyłki zakolorowany na czerwono. Sprawa zaczyna śmierdzieć, bowiem nie mogę się dodzwonić do kontrahenta (number busy), a gdy już mi się to udaje – nikt nie odbiera. Kilkukrotna próba kontaktu telefonicznego i mailowego pozostawiona bez odpowiedzi motywuje mnie, żeby…

09.07 wypełniłem wniosek w Centrum Sporów Allegro. Tego samego dnia wybrałem się na Policję, aby złożyć zawiadomienie o popełnieniu przestępstwa na tle wyłudzenia internetowego. Na komendzie czekałem około 40 minut zanim mnie przesłuchali, potem straciłem 30 minut na przesłuchanie i sporządzenie raportu.

Czas płynie i płynie…

27.07 – kontrahent dzwoni z wyjaśnieniami. “Okazało się”, że odwiedziła go Policja. Tłumaczenie: padła im baza klientów i zamówień, przez co nie mogli mnie zidentyfikować, pomimo szukania transakcji w historii sprzedaży na Allegro (przecież jest lista czarno na białym). Na moim koncie powinny być już zaksięgowane zwrócone pieniążki, ale niestety nie mogą wysłać mi mojego pada ze względu na to, że są zablokowani przez skarbówkę… muszą się rozliczyć. Za wszystko jeszcze raz przeprasza…

28.07 godz 11:00, telefon z Policji. Wezwanie na jutro, punkt 9 rano w pokoju numer 53. Sprawdzam konto, pieniążki są. Drukuję potwierdzenie zaksięgowania zwrotu jako załącznik do jutrzejszych zeznań.

29.07 godz 9:00 (wakacje są, daliby pospać). Zaniechujemy ściganie, dziękuję za pomoc. Kończę spór transakcyjny w panelu na Allegro i wystawiam negatywny komentarz:

Towar nie dotarł do mnie do dziś. Po interwencji Policji sprawa się wyjaśniła. Natomiast nieuczciwym wobec innych użytkowników Allegro byłoby wystawienie poz. lub neut. komentarza za transakcję, która nie doszła do skutku. Miesiąc w plecy.

Read More

Asus Eee PC 1000H – recenzja

Feb 14

Asus Eee PC 1000H – recenzja

Od dwóch dni jestem posiadaczem netbooka Asus Eee PC 1000H. Intensywnie sprawdzałem jego możliwości i powiem szczerze, że jestem mile zaskoczony. Pomimo tego, że niektórzy jego minimalizm przedstawiają jako minus – ja jestem zadowolony. Z łatwością mieści się do wewnętrznej kieszeni kurtki zimowej, posiada eleganckie etui. Podstawowym minusem jest brak napędu optycznego, ale problem rozwiązuję udostępnieniem DVD z komputera PC jako zasób sieciowy. Rzadko potrzebuję cokolwiek zainstalować, w moim przypadku do transferu najczęściej używam standardowych złącz USB (włącznie z dyskiem twardym peceta) oraz standardowo Internetu, najczęściej ftp.

Design i obudowa.

Cały komputer wygląda przyzwoicie, pomimo tego zdecydowałem się kupić oklejkę na klapę, aby odkleić ją po jakimś czasie i mieć niezarysowaną powierzchnię obudowy. Klapa jest wykonana w “modnym” stylu serii HP, czyli krótko mówiąc – błyszcząca. Minusem są pozostawione odciski palców. Jest zima… palce mniej się pocą, strach pomyśleć, jak będzie wyglądała w lato. Pozostała część obudowy jest matowa, co dla mnie jest wielkim plusem – nie pozostawiamy odcisków palców, na takiej powierzchni mniej widoczne są zarysowania. Autorzy dobrze wkomponowali zawiasy obudowy, tworząc walec zakończony metalowymi kołami z zębatą krawędzią, co mnie się podoba. Denerwująca dla oka jest metalowa obudowa na touchpad, bowiem widoczne są podłużne pasy frezarki. Nie wiem, czy jest to zamierzony efekt – mnie nie przypadł do gustu. Na marginesie: Eee PC ma brzydkie logo :P

Kontrowersyjny touchpad…

… a raczej pushpad. Na początku miałem wrażenie, że trzeba go naciskać, nie dotykać, ale po 2 dniach używania już się przyzwyczaiłem. W moim poprzednim laptopie fizyka działania tego elementu była nieco inna. Często wymienianym minusem w recenzjach są przyciski w touchpadzie… mocno trzeba je wciskać. Nie, wciska się je łatwo i są bardzo wygodne, pod warunkiem, że przyciskamy je pod kątem 45 stopni w stosunku do klawiatury. Na początku wydawać się, że jest to nietypowe ułożenie ręki, musiałem się przyzwyczaić, ale teraz ciężko mi działać na jakimkolwiek innym touchpadzie – bardzo wygodna pozycja dłoni.

Klawiatura… bardzo mały odskok, nieznacznie mniejsze klawisze niż w standardowym notebooku, duży plus. Dodatkowo znalazło się miejsce na hotkeye (kombinacje w Fn) takie jak: sleep, włącz/wyłącz bluetooth oraz manager zadań. Standardowo brighnes, volume, mute i przełączenie monitora na zewnętrzne złącze karty graficznej (np rzutnik lub zewnętrzny monitor).  I minusy się znajdą, brak osobnych przycisków PgUp/Down oraz Home/End. Zamiast tego ulokowane są na strzałkach, używamy ich z wciśniętym Fn – niewygodne. Klawisz Fn ustawiony jest obok Ctrl po jego prawej stronie – plus. W Fujitsu-Siemens który miałem poprzednio było odwrotnie, często się myliłem.

Praca i entertejment.

Nie można wymagać wiele od procesora 1,6 GHz, 1GB RAM DDR2, ale daje radę. Produkt jest przedstawiony jako notatnik, ale świetnie radzi sobie z jednocześnie odpalonym softem takim jak Office 2007, Photoshop CS3, Google Chrome. Moje ulubione gry (NFS Underground, Diablo 2, GTA 2) działają bez zarzutów, więc pretensji nie mam. W tle działa Windows Blinds oraz Yomd3d.

10 cali, nie za mało?

Do programowania i photoshopa – tak, do przeglądania Internetu, pisania notatek etc. w zupełności wystarczy. Jednak nawet przy najprostszych czynnościach warto minimalistycznie podchodzić do zagospodarowania przestrzeni na ekranie. W tym celu właśnie zainstalowany jest Windows Blinds – skin imitujący Mac OS posiada bardzo niskie belki. Z pomocą przychodzi nam również Google Chrome, który minimalnie wykorzystuje ekran, w przeciwieństwie do FireFox’a. Zaletą Chroma jest to, że posiada ukryty pasek narzędzi oraz zakładki na pasku tytułu.

Bateria.

6600 mAh Li-ion. Przy włączonym trybie Asus Safe Energy i wyłączonym bluetooth bateria faktycznie trzyma 5 godzin. Przy odpaleniu ciężkiego softu, wifi oraz wyłączonym trybie oszczędzania energii bateria utrzymuje netbooka przy życiu przez 3h i 40 min. Bardzo dobry wynik, jeżeli chodzi w ogóle o netbooki. Standardowo na netbooku pracuję 4h i 20 min.

Ważnym jest to, aby dobrze używać baterii, tj. wyjąć ją, gdy netbook podłączony jest do prądu, a stan baterii jest równy 100%. Warto wcześniej  kilka razy (wolno) rozładować do zera i ponownie naładować na max. Obecnie wykonuje taki zabieg włączając stan czuwania na noc podładowując baterię już na następny wieczór. Cykl będę powtarzał tydzień.

Podsumowanie.

Moje zadowolenie to 95%, czyli netbook spełnił moje oczekiwania prawie celująco. Kupiłem go przez Allegro, miałem fart, niska cena, aukcja wystawiona przed diametralnym spadkiem PLN.

  • Wygląd: 4/5
  • Cena: 5/5
  • Wydajność: 4/5
Read More

Logowanie po nickname i email (usability)

Dec 28

Logowanie po nickname i email (usability)

Projektując serwisy zaczynam ostrożnie podchodzić do usability. Temat jest bardzo wrażliwy, każdy webmaster to inne zdanie. Dziś chciałbym przedstawić problem logowania do serwisu. Oprócz hasła, przy logowaniu używamy:

  • standardowo nazwy użytkownika,
  • w niektórych serwisach adresu email, rzadziej spotykane zjawisko.

W trosce o użytkowników w kilku moich serwisach zastosowałem możliwość logowania się na adres email lub nazwę użytkownika. Wszystko po to, aby ułatwić dostęp do ukrytej części witryny, aby nikt nie “zwątpił” bo nazwy użytkownika, lub adresu email, który podał przy zakładaniu profilu. Sam używam w sieci kilku adresów email oraz kilku prefixów i suffixów do nicka Athlan. Mam problem z zalogowaniem, gdy danie nie pasują, a potrzebuję dostęp tylko na chwilę.

Przygotujmy zatem tok myślenia programu, który pobierze dane, w zależności od tego, jakie dane podał użytkownik. Pomijam walidację hasła etc:

  1. Wykrycie, czy nick jest adresem email.
  2. Jeżeli tak, pobierz dane użytkownika po polu user_mail i zapisz je do zmiennej $aUser.
  3. Jeżeli nie, pobierz dane identyfikując rekord po kluczu user_name i zapisz pobrane dane do zmiennej $aUser.

Jak możemy zauważyć, w obu przypadkach dane zapisujemy do tej samej zmiennej $aUser, więc możemy je dalej tak samo wykorzystywać. Różni się tylko pobieranie, dlateg nie trzeba w żadnym wypadku powielać kodu.

Jak słusznie zauważył devnull, należy wykluczyć możliwość użycia znaku małpy w loginie przy rejestracji użytkownika. Wyjaśnienie znajdziecie w komentarzach.

Dla programisty nie jest wiele pracy, a warto ułatwić dostęp użytkownikowi do serwisu. Usability na pierwszym miejscu ;-)

Read More

Podtrzymanie sesji

Dec 26

Podtrzymanie sesji

Dla niektórych wygasanie sesji jest zabezpieczeniem (banki, etc.). Realizując jeden z projektów oczekiwałem od systemu tego, aby użytkownik nigdy nie gubił sesji, gdy ma otwarte okno w przeglądarce. Dlaczego? Może dodaje posta, być może uzupełnia dość obszerny tekst na stronie. Gdy klika zapisz, przerzuca go do strony logowania, a cały tekst zniknął za sprawą tego, że jego przeglądarka nie zapisuje wartości pól formularza. Skąd to znamy.

Jak użytkownik gubi sesję?

  1. Jego ciastko wygasa, więc serwer nie może go zidentyfikować z sesją.
  2. Po jakimś czasie, choćby odtworzył ciastko, plik sesji znika z naszego serwera (garbage collection).

Rozwiązania:

  1. Wydłużenie czasu wygasania ciastka i sesji.
  2. Odświeżenie strony w interwale mniejszym, niż wynosi czas wygasania sesji i ciastka.

Rozmyślając nad podtrzymaniem sesji, próbowałem znaleźć wszystkie metody oraz wybrać najlepszą. Wszystkie sprowadzają się do “odświeżenia” strony lub jej fragmentu tak, aby nasz silnik wykonał tylko potrzebne session_start(); czyli podtrzymanie aktywności sesji. Jest kilka mniej lub bardziej zadowalających sposobów:

  1. Odświeżenie całej strony.
    To może spowodować, że dane wprowadzane przez użytkownika w formularzu zostaną utracone. Ponad to, jeżeli użytkownik czyta newsy, denerwującym może być fakt, że lista nagle zostanie przescrollowana do góry (prócz opery).
  2. Wysłanie requestu ajax w tle.
    Minusem jest to, że trzeba używać biblioteki ajax lub pisać dodatkowy kod javascriptu. Jeżeli ktoś na stronie używa jakiegoś ajaxa – co za różnica. Poza tym same plusy.
  3. Odświeżanie ukrytej ramki iframe lub elementu frameset.
    Minusów usablity prawie brak. Brak potrzeby instalacji javascriptów i ajaxa. Odświeżacz powinien wysłać nagłówek Refresh lub odpowiedni metatag.

Sposób 3 wydaje mi się najlepszy. Można go ulepszyć w ten sposób, aby ramka nie wysyłała żądania zaraz po załadowaniu strony. Powodowałoby to podwójne requesty do serwera.

Zapewne znajdą się osoby, które powiedzą: a co z użytkownikami, którzy mają wyłączone ramki, lub ich przeglądarki w ogóle ich nie obsługują. Zapytam wówczas: a co z użytkownikami, którzy nie akceptują cisteczek (wówczas sesje nie są dla nich użyteczne, chyba, że użyjemy przesłyki jej identyfikatora w adresie url). Dopytam również: a co z użytkownikami, którzy mają wyłączony Javascript? Patologiczne przepadki się po prostu pomija ;)

Read More

Upload filmów z Zend_Gdata_YouTube

Dec 20

Pisząc nowy projekt natknąłem na problem z procesem uploadu filmiku do serwisu YouTube. Sam upload jest bardzo łatwy do napisania z Zend_Gdata_YouTubeprzykład można znaleźć w manualu. Myślę, że zainteresowani przeczytają manual i wszystko będzie jasne. Więc jeżeli to takie proste, to w czym problem?

Zakładamy, że userzy uloadują filmiki bezpośrednio na nasz serwis. Nasz serwer ma za zadanie:

  1. Skompresować video i zapisać go w formacie flv.
  2. Nałożyć watermark.
  3. Wysłać obrobiony film do serwisu Youtube logując się na zdefiniowane przez użytkownika konto lub założone przez administratora strony.

Pierwsze 2 kroki wykonają się błyskawicznie w porównaniu do trzeciego. Kompresja i nałożenie watermarku na 30 megowy plik z wykorzystaniem FFMPEG to nic nadzwyczajnego. Natomiast wysyłka pliku na serwery Youtube’a może zawiesić apache’a, gdy jest ich kilka.

Rozwiązanie? Wpadłem na pomysł, aby upload filmików ustawiony był w pewnego rodzaju kolejce, która uruchamiana by była co minutę (cron), a czas jednego wysłania elemntu nie mógłby przekroczyć 50 sekund. Oczywiście takie działanie uruchamiałoby swój osobny proces apache’a. Ten sposób jest ograniczony dwoma limitami: wielkością pliku oraz czasem jego uploadu na serwer (jednocześniem interwałem uruchamiania kolejki).

Read More