Marcin Chyłek Blog

Symfony - przyśpieszanie Propela z wykorzystaniem widoków (view) baz danych

Szybkie serwisy, zoptymalizowane pod względem zużycia pamięci i ilości odwołań do bazy – czasami mogą być kluczowym elementem w powodzeniu naszego projektu. Chciałbym przedstawić jedną z takich możliwości, czyli użycie w Symfony widoków baz danych. Przykład można zastosować w bazach: PostgreSQL, MySQL, Oracle, itd. Najważniejszym elementem jest to, czy baza danych obsługuje widoki.

Dla przykładu użyję tabeli użytkownik i grupa.

schema.yml

propel:

  groups:
    id:              { type: integer, required: true, primaryKey: true, autoincrement: true }
    owner_id:        { type: integer, foreignTable: users, foreignReference: id, index: true }
    last_user_id:    { type: integer, foreignTable: users, foreignReference: id, index: true }
    name:            { type: varchar, size: 80, index: true }
    routing_name:    { type: varchar, size: 80, index: true, uniq: true }
    description:     { type: varchar, size: 400 }
    created_at:      { type: timestamp }
    user_count:      { type: integer, index: true }
    position_rank:   { type: integer }

  users:
    id:              { type: integer, required: true, primaryKey: true, autoincrement: true }
    login:           { type: varchar, size: 15, index: true, uniq: true }
    password:        { type: varchar, size: 255 }
    name:            { type: varchar, size: 255 }
    created_at:      { type: timestamp }
    updated_at:      { type: timestamp }
    last_login_at:   { type: timestamp }
    last_request_at: { type: timestamp }
    group_id:        { type: integer, foreignTable: groups, foreignReference: id, index: true }

Załóżmy, że mamy template w którym pokazujemy 20 grup według ilości użytkowników, w której wyświetlamy: nazwę grupy wraz z linkiem do profilu grupy, właściciela grupy, ostatniego dodanego użytkownika do tej grupy i ilość użytkowników w grupie. Stosując klasyczne wykorzystanie modelów Propela, dostaniemy modele grup z zależnymi 2 modelami użytkowników – właściciel i ostatnio dodany użytkownik. Od razu widać że większość danych jest zbędna, a co z tym idzie wykorzystanie pamięci będzie większe i czas zwracania danych z bazy będzie dłuższy.

Definiowanie widoku (views) w schema

Aby rozdzielić pliki w którym są definicje tabel i widoki, warto utworzyć osobny plik w którym zapiszemy naszą definicje widoku.

config/views_schema.yml

propel:
  groups_view:
    _attributes:              { skipSQL: true, readOnly: true }
    id:                       { type: integer }
    name:                     { type: varchar }
    routing_name:             { type: varchar }
    user_count:               { type: integer }
    owner_name:               { type: varchar }
    last_user:                { type: varchar }

Kolejnym krokiem jest przygotowanie SQL z definicją naszego vidoku. Dobrym rozwiązaniem jest by każdy widok umieszczać w osobnym pliku i dodawać do sqldb.map, w celu zbudowania widoku z automatu (nie musimy już ręcznie wywoływać SQL).

Tworzymy plik sql

data/sql/views/groups_view.sql

CREATE OR REPLACE VIEW groups_view AS
  SELECT groups.id,
         groups.name ,
         groups.routing_name,
         groups.user_count,
         owner.login AS owner_name,
         last.login AS last_user
    FROM groups
    JOIN users owner ON owner.id = groups.owner_id
    JOIN users last ON last.id = groups.ast_user_id;

Dodajemy widok do sqldb.map

Edytujemy plik sqldb.map i dodajemy nową pozycję

data/sql/sdldb.map

views/groups_view.sql=propel

Kolejnym krokiem jest zbudowanie bazy danych, dla przykładu użyje polecenia, które tworzy modele, dodaje SQL do bazy i wczytuje przykładowe dane.

./symfony propel:build-all-load

Po wygenerowanie powstał model o nazwie GroupsView, teraz tylko nam zostaje dodanie metody, która będzie zwracać 20 grup z największą ilością użytkowników.

Edytujemy GroupsViewPeer.class.php

Dodajemy metodę

public static function getTopGroups( $limit = 20 )
{
  $c = new Criteria();
  $c->addDescendingOrderByColumn( GroupsViewPeer::USER_COUNT );
  $c->setLimit( $limit );

  return GroupsViewPeer::doSelect( $c );
}

Metoda ta zwraca 20 obiektów, w których mamy tylko i wyłącznie pola, które będą nam potrzebne do wyświetlenia.

Często na rożnych forach spotyka się opinie, że Symfony jest wolnym i zasobożernym frameworkiem, jeśli nie znamy możliwości, zasad jego działania jak i sposobów optymalizacji to niestety ale taka teoria dla pewnych osób jest prawdziwa. Wykorzystując możliwości baz, takie jak plsql, vidoki, triggery i funkcje można osiągnąć rewelacyjne efekty i obsługa milionowych tabel na “słabym” sprzęcie jest czymś realnym.

Kategoria: Bazy danych, MySQL, Oracle, PHP, PostgreSQL, Propel, Symfony | Marcin Chyłek | Komentarze: 9

PostgreSQL - Procedural Language (przyszłość języków)

Używając PostgreSQL’a możemy wykorzystywać kilka języków proceduralnych:

  • PL/pgSQL podobny składnią do języka PL/SQL w bazie Oracle
  • języki skryptowe: PL/Perl, plPHP, PL/Python, PL/Ruby, PL/sh i PL/Tcl
  • kompilowane: C, C++, PL/Java
  • PL/R

PostgreSQL jest często wykorzystywany przez programistów serwisów WWW (konfiguracja w postaci PostgreSQL + PHP) to mimo tego, że istnieje język plPHP to obecnie najpopularniejszym językiem jest PL/pgSQL - dlatego pewnie, że wywodzi się od PL/SQL (Oracle).

Zastanawiam się dlaczego tak się dzieje, co powoduje że nie używa się pozostałych języków? Weźmy na przykład Ruby - oczywiście w bazie PostgreSQL mamy możliwość jego wykorzystania. PL/Ruby jest rozwijany od 2002 roku, mimo wielkiej popularności Ruby wśród programistów PHP język raczej nie należy do tych prężnie się rozwijających. C, C++ dlaczego nie? Prawie każdy programista miał styczność z tymi językami a jednak PL/pgSQL.

Przeglądając TODO Postgresa i MySQLa widać, że developerzy tych baz starają się implementować większość funkcjonalności, które firma Oracle wprowadziła do swojej bazy jakiś czas temu. Tak czy inaczej Oracle jest pionierem na rynku jeśli chodzi o bazy danych i wprowadzenie zmian lub dodanie nowych mechanizmów powoduje, że reszta systemów bazodanowych podąża za nimi.

Czy warto wdrożyć plPHP czy PL/Ruby? Każdy musi na to pytanie sobie sam odpowiedzieć.

Dla osób chcących wdrożyć się w PL/Ruby lub plPHP zapraszam na:

PL/Ruby
plPHP

Kategoria: Bazy danych, PostgreSQL | Marcin Chyłek | Komentarze: 1

Ubuntu Dapper - Instalacja pgadmin3 1.4.x

Obecnie w repozytoriach Ubuntu Dapper najnowszą wersją pgadmin3 jest wersja 1.2.x. Nasuwa się więc pytanie jak zainstalować wersje 1.4.x. Jest kilka możliwości - najłatwiejszą z nich będzie wykorzystanie paczek z Debiana. Poniżej przedstawię w jaki sposób pobrać paczki z Debiana i przerobić tak aby pasowały do Ubuntu Dapper.

Pierwszą rzeczą jaką musimy zrobić jest usunięcie zainstalowanej wersji pgadmin3.

sudo apt-get remove pgadmin3 pgadmin3-data

Następnie musimy dodać nowe wpisy do repozytoriów (plik /etc/apt/sources.list)

Repozytorium PostgreSQL (obecnie najnowszą wersją jest 1.4)

deb ftp://ftp3.us.postgresql.org/pub/postgresql/pgadmin3/release/debian stable pgadmin

deb-src ftp://ftp3.us.postgresql.org/pub/postgresql/pgadmin3/release/debian stable pgadmin

Lub wpisy do repozytoriów Debiana (obecnie najnowszą wersją jest 1.4.3-1)
deb-src http://http.us.debian.org/debian unstable main

Kolejnym krokiem jest aktualizacja bazy danych pakietów

sudo apt-get update

Po zaktualizowaniu bazy pakietów instalujemy “dpkg-dev”, który zawiera narzędzie do budowania pakietów.

sudo apt-get install dpkg-dev

Przechodzimy do etapu budowania pakietu, w przypadku pgadmina wymagane są: pgadmin3 pgadmin3-data. Pobierane są źródła a następnie budowane są pakiety.

sudo apt-get build-dep pgadmin3 pgadmin3-data
sudo apt-get -b source pgadmin3 pgadmin3-data

Budowanie pakietów może chwile potrwać. Wynikiem będą 2 pliki o rozszerzeniu .deb w aktualnym katalogu. (pgadmin3_1.4.3-1_i386.deb, pgadmin3-data_1.4.3-1_all.deb)

Końcowym etapem jest instalacja:

dpkg -i pgadmin3_1.4.3-1_i386.deb pgadmin3-data_1.4.3-1_all.deb

Jeśli wszystko przebiegło poprawnie pozostaje nam tylko uruchomienie pgadmin3:

/usr/bin/pgadmin3

lub

pgadmin3
Kategoria: Bazy danych, Linux, PostgreSQL | Marcin Chyłek | Komentarze: 0
« Nowsze