=====Projekt logiczny ===== ====-. Projekt tabel==== Wraz z postępem prac w bazie pojawiło się kilka poprawek, głównie związanych z sprecyzowaniem działania poszczególnych fragmentów systemu. Aktualny diagram naszej bazy znajduje się poniżej. [[http://ai.ia.agh.edu.pl/wiki/pl:dydaktyka:ztb:2011:projekty:restauracje:logiczny:baza|Diagram bazy danych]] Jak widać oprócz kilku zmian w parametrach doszło także kilka nowych tabel np LogEntry czy Persmision. Są one odpowiedzialne za autentykacje użytkowników -- generowane automatycznie przez Django. Tabele Session, Site i MigrationHistory także są tworzone przez framework Djano i obsługują połączenie klienta z naszym portalrem. Główna struktura tabel podana na ERD jest niezmieniona. Poniżej kod SQL generujący bazę. W naszym przypadku jest to SQLite. [[http://ai.ia.agh.edu.pl/wiki/pl:dydaktyka:ztb:2011:projekty:restauracje:logiczny:sql|Kod SQL generujący bazę]] ====-. Słownik danych==== - auth_user - główne informacje o użytkowniku systemu * id - integer NOT NULL PRIMARY KEY, * username - varchar(100) NOT NULL, nick użytkownika * first_name - varchar(100), imię * last_name - varchar(100), nazwisko * email - varchar(100), adres e-mail * password - varchar(100) NOT NULL, haslo w postaci zahashowanej * is_staff - bool NOT NULL, informacja czy użytkownik to pracownik restauracji * is_active - bool NOT NULL, informacja o aktywności konta * is_superuser - bool NOT NULL, informacja czy użytkownik to administrator * last_login - date NOT NULL, data ostatniego logowania * date_joined - date NOT NULL data utworzenia konta * groups - pole ManyToMany automatycznie generowane, przypisanie użytkownika do grupy * user_permisions - pole ManyToMany automatycznie generowane, nadawanie praw i ról użytkownikowi - accounts_contactdata - tabela przechowująca dane adresowe * id - integer NOT NULL PRIMARY KEY, * city - varchar(100), miasto * street - varchar(100), ulica * flat_number - varchar(10), nr mieszkania * pna - varchar(6), * phone - varchar(12), nr telefonu - accounts_userprofile - informacje o profilu użytkownika * id - integer NOT NULL PRIMARY KEY * user_id - integer NOT NULL UNIQUE, referencja do tabeli auth_user * contact_data_id - integer NOT NULL, referencja do tabeli accounts_contactdata * activation_key - varchar(40) NOT NULL - accounts_comment - komentarze użytkowników * id - integer NOT NULL PRIMARY KEY, * user_comment - text NOT NULL, treść komentarza * ratio - integer unsigned NOT NULL, ocena w skali 1-10 * user_id - integer NOT NULL, referencja do tabeli accounts_userprofile * restaurant_id - integer NOT NULL, referencja do tabeli restaurants_restaurant * dish_id - integer NOT NULL, referencja do tabeli restaurants_dish - accounts_basket - tabela przechowująca aktywne koszyki zleceń * id - integer NOT NULL PRIMARY KEY, * user_id - integer, referencja do tabeli accounts_userprofile * session - varchar(32), numer aktywnej sesji w przeglądarce - restaurants_restaurant - informacje o restauracji * id - integer NOT NULL PRIMARY KEY, * user_id - integer NOT NULL UNIQUE, referencja do tabeli auth_user * is_promo - bool NOT NULL, atrybut pomocyjny * activation_key - varchar(40) NOT NULL, klucz aktywacyjny restaurację * contact_data_id - integer NOT NULL UNIQUE, referencja do tabeli accounts_contactdata * description_id - integer NOT NULL UNIQUE, id opisu restauracji - restaurants_dish - tabela przechowująca informacje o potrawach * id - integer NOT NULL PRIMARY KEY, * name - varchar(100) NOT NULL, nazwa potrawy * description - varchar(500) NOT NULL, opis potrawy * price - varchar(7) NOT NULL, cena * category_id - integer NOT NULL, id kategorii * restaurant_id - integer NOT NULL, referencja do tabeli restaurants_restaurant - restaurants_category - kategorie potraw * id - integer NOT NULL PRIMARY KEY, * name - varchar(200) NOT NULL, nazwa kategorii - restaurants_description - informacje o restauracjach * id - integer NOT NULL PRIMARY KEY, * name - varchar(200) NOT NULL, nazwa restauracji * description - text, opis tekstowy o restauracji * img - varchar(100) NOT NULL, zdjęcie restauracji - restaurants_orderingdish - tabela z zamawianymi potrawami * id - integer NOT NULL PRIMARY KEY, * count - integer unsigned NOT NULL, liczebność zamówienia * dish_id - integer NOT NULL, referencja do tabeli restaurants_dish * basket_id - integer, referencja do tabeli accounts_basket * order_id - integer, id zamowienia - restaurants_order - tabela z zamówieniami * id - integer NOT NULL PRIMARY KEY, * state - varchar(1) NOT NULL, obecny stan zamówienia * order_date - date NOT NULL, data zamówienia * contact_data_id - integer NOT NULL, referencja do tabeli accounts_contactdata ====-. Analiza zależności funkcyjnych==== W tym punkcie należy sprawdzić czy nasza baza jest w trzeciej postaci normalnej (3NF). Pierwszym krokiem jest sprawdzenie drugiej postaci normalnej (2NF) a następnie czy wszystkie atrybuty niekluczowe są zależne tylko od parametrów kluczowych. == Sprawdzenie 2NF === Specyfika pracy z Django sprawia, że uzyskane tabele składają się tylko z kluczy prostych, z tego powodu baza napewno jest w drugiej postaci normalnej. == Sprawdzenie zależności pomiędzy atrybutami niekluczowymi == * **auth_user** - informacje o użytkowniku systemu * id - PRIMARY KEY, * username * first_name * last_name * email * password * is_staff * is_active * is_superuser * last_login * date_joined * groups * user_permisions Wszystkie pola są zależne od klucza głównego i nie mogą bez tego istnieć. * **accounts_contactdata** - dane adresowe * id PRIMARY KEY, * city * street * flat_number * pna * phone Wszystkie pola zależne od klucza głównego * **accounts_userprofile** - informacje o profilu użytkownika * id PRIMARY KEY * user_id FOREIGN KEY * contact_data_id FOREIGN KEY * activation_key - Prametr zależny od klucza głównego. * **accounts_comment** - komentarze użytkowników * id - PRIMARY KEY, * user_comment * ratio * user_id - FOREIGN KEY * restaurant_id - FOREIGN KEY * dish_id - FOREIGN KEY Parametry niekluczowe (user_comment, ratio) zależne od klucza głównego. * **accounts_basket** - koszyki zleceń * id - PRIMARY KEY, * user_id - FOREIGN KEY * session - zależny od aktywnego koszyka (klucza głównego) * **restaurants_restaurant** - informacje o restauracji * id - PRIMARY KEY, * user_id - FOREIGN KEY * is_promo * activation_key * contact_data_id - FOREIGN KEY * description_id - FOREIGN KEY Atrybuty is_promo oraz activation_key są zależne od klucza głównego restauracji * **restaurants_dish** - informacje o potrawach * id - PRIMARY KEY, * name * description * price * category_id - FOREIGN KEY * restaurant_id - FOREIGN KEY Ponownie wszystkie atrybuty niekluczowe są zależne tylko od klucza głównego * **restaurants_category** - kategorie potraw * id - PRIMARY KEY, * name - zależne od klucza * **restaurants_description** - informacje o restauracjach * id - PRIMARY KEY, * name * description * img Wszystkie atrybuty zależne od klucza * **restaurants_orderingdish** - tabela z zamawianymi potrawami * id - PRIMARY KEY, * count - liczebnośc zamówienia, zależna od zamówionej potrawy (klucza głównego) * dish_id - FOREIGN KEY * basket_id - FOREIGN KEY * order_id - FOREIGN KEY * **restaurants_order** - tabela z zamówieniami * id - PRIMARY KEY, * state * order_date * contact_data_id - FOREIGN KEY Oba atrybuty state oraz order_date są specyficzne dla zamówienia, dlatego są zależne od klucza. == Wynik == Na postawie tej analizy wynika, że są spełnione oba założenia zatem możemy stwierdzić, że nasza bazie __**jest w trzeciej postaci normalnej**__ (3NF). ====-. Operacje na danych==== ==Pobranie listy restauracji== SELECT "restaurants_restaurant"."id", "restaurants_restaurant"."user_id", "restaurants_restaurant"."is_promo", "restaurants_restaurant"."activation_key", "restaurants_restaurant"."contact_data_id", "restaurants_restaurant"."description_id" FROM "restaurants_restaurant" ==Rejestracja użytkownika== * User NSERT INTO "auth_user" ("username", "first_name", "last_name", "email", "password", "is_staff", "is_active", "is_superuser", "last_login", "date_joined") VALUES (restauracja, , , restauracja@gmail.com, sha1$2cde6$02b068ba3bf0bdb0b40878d357c879bd4c716c47, False, True, False, 2011-06-16 02:00:20.516032, 2011-06-16 02:00:20.516032) * ContactData INSERT INTO "accounts_contactdata" ("city", "street", "flat_number", "pna", "phone", "lat", "lng") VALUES (city, street, flat_number, zip, phone_number, None, None) * UserProfile INSERT INTO "accounts_userprofile" ("user_id", "contact_data_id", "activation_key") VALUES (2, 1, a1d96ad94e96abc3247c41c888fbf7bc4c7a9770) ==Rejestracja restauracji== * User INSERT INTO "auth_user" ("username", "first_name", "last_name", "email", "password", "is_staff", "is_active", "is_superuser", "last_login", "date_joined") VALUES (user, , , user@gmail.com, sha1$d3c29$db8cca0d71b4a26d5a2a5ee01db6f13a3161f090, False, True, False, 2011-06-16 01:51:41.714921, 2011-06-16 01:51:41.714921) * ContactData INSERT INTO "accounts_contactdata" ("city", "street", "flat_number", "pna", "phone", "lat", "lng") VALUES (krakow, lea, 5, zip, tel, 50.0694749, 19.9237717) * Description INSERT INTO "restaurants_description" ("name", "description", "img") VALUES (Nazwa, Opis, ) * Restaurant INSERT INTO "restaurants_restaurant" ("user_id", "is_promo", "activation_key", "contact_data_id", "description_id") VALUES (4, False, 1e7628f58f2ef403653e42fbd9ed2a4891fa5907, 2, 2) * Category INSERT INTO "restaurants_category" ("name", "restaurant_id") VALUES (Dania z kurczaka, 1) INSERT INTO "restaurants_category" ("name", "restaurant_id") VALUES (Dania z wieprzowiny, 1) INSERT INTO "restaurants_category" ("name", "restaurant_id") VALUES (Napoje, 1) ==Logowanie== SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."username" = restauracja SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_date" FROM "django_session" WHERE ("django_session"."session_key" = 897afbf7b884bf9afd90aaaa214f321f AND "django_session"."expire_date" > 2011-06-16 02:06:12.307045 ) SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_date" FROM "django_session" WHERE "django_session"."session_key" = 35d4742a49267bfae806fd8f55b210bf INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES (35d4742a49267bfae806fd8f55b210bf, ZjEwOTM1YzhhMjFhNzVmNWY3ZjlmNzViNTIyNGRlY2JmNzk0ZmE0YTqAAn1xAS4= , 2011-06-30 02:06:12.341886) ==Dodawanie potrawy do menu restauracji== SELECT "restaurants_restaurant"."id", "restaurants_restaurant"."user_id", "restaurants_restaurant"."is_promo", "restaurants_restaurant"."activation_key", "restaurants_restaurant"."contact_data_id", "restaurants_restaurant"."description_id" FROM "restaurants_restaurant" WHERE "restaurants_restaurant"."user_id" = 4 SELECT "restaurants_category"."id", "restaurants_category"."name", "restaurants_category"."restaurant_id" FROM "restaurants_category" WHERE "restaurants_category"."name" = Dania z kurczaka INSERT INTO "restaurants_dish" ("name", "description", "price", "category_id", "restaurant_id") VALUES (Kurczak na ostro, kurczak w ostrym sosie, ryż, surówka, 22, 1, 1) ==Pobieranie menu restauracji== SELECT "restaurants_dish"."id", "restaurants_dish"."name", "restaurants_dish"."description", "restaurants_dish"."price", "restaurants_dish"."category_id", "restaurants_dish"."restaurant_id" FROM "restaurants_dish" WHERE "restaurants_dish"."restaurant_id" = 1 ==Pobieranie komentarzy o restauracji== SELECT "accounts_comment"."id", "accounts_comment"."user_comment", "accounts_comment"."ratio", "accounts_comment"."user_id", "accounts_comment"."restaurant_id", "accounts_comment"."dish_id" FROM "accounts_comment" WHERE "accounts_comment"."restaurant_id" = 1 ==Pobieranie komentarzy o potrawie== SELECT "accounts_comment"."id", "accounts_comment"."user_comment", "accounts_comment"."ratio", "accounts_comment"."user_id", "accounts_comment"."restaurant_id", "accounts_comment"."dish_id" FROM "accounts_comment" WHERE "accounts_comment"."dish_id" = 1 ==Pobieranie koszyka niezalogowanego użytkownika== SELECT "accounts_basket"."id", "accounts_basket"."user_id", "accounts_basket"."session" FROM "accounts_basket" WHERE "accounts_basket"."session" = b015e7e807f1d0474a870df8cafe570b ==Dodawanie potrawy do koszyka oraz do zamówień restauracji== SELECT "accounts_basket"."id", "accounts_basket"."user_id", "accounts_basket"."session" FROM "accounts_basket" WHERE "accounts_basket"."session" = e8974ec8edc1b95284a6bc351f949f3b INSERT INTO "accounts_basket" ("user_id", "session") VALUES (None, e8974ec8edc1b95284a6bc351f949f3b) INSERT INTO "restaurants_orderingdish" ("count", "dish_id", "basket_id", "order_id") VALUES (1, 3, 1, None) ==Zamawianie potrawy== SELECT "accounts_basket"."id", "accounts_basket"."user_id", "accounts_basket"."session" FROM "accounts_basket" WHERE "accounts_basket"."session" = e8974ec8edc1b95284a6bc351f949f3b INSERT INTO "accounts_contactdata" ("city", "street", "flat_number", "pna", "phone", "lat", "lng") VALUES (Krakow, Lea, 100/5, 32-300, 600600600, None, None) INSERT INTO "restaurants_order" ("state", "order_date", "contact_data_id", "restaurant_id") VALUES (0, 2011-06-16, 3, 1) SELECT "restaurants_orderingdish"."id", "restaurants_orderingdish"."count", "restaurants_orderingdish"."dish_id", "restaurants_orderingdish"."basket_id", "restaurants_orderingdish"."order_id" FROM "restaurants_orderingdish" WHERE "restaurants_orderingdish"."basket_id" = 1 UPDATE "restaurants_orderingdish" SET "count" = 1, "dish_id" = 3, "basket_id" = NULL, "order_id" = 1 WHERE "restaurants_orderingdish"."id" = 1 ==Dodawania komentarza o restauracji i potrawie== INSERT INTO "accounts_comment" ("user_comment", "ratio", "user_id", "restaurant_id", "dish_id") VALUES (Dobry, 5, None, None, 3) INSERT INTO "accounts_comment" ("user_comment", "ratio", "user_id", "restaurant_id", "dish_id") VALUES (Super, 6, None, 1, None) ==Przyjęcie zamówienia do realizacji== SELECT "restaurants_restaurant"."id", "restaurants_restaurant"."user_id", "restaurants_restaurant"."is_promo", "restaurants_restaurant"."activation_key", "restaurants_restaurant"."contact_data_id", "restaurants_restaurant"."description_id" FROM "restaurants_restaurant" WHERE "restaurants_restaurant"."user_id" = 4 SELECT "restaurants_order"."id", "restaurants_order"."state", "restaurants_order"."order_date", "restaurants_order"."contact_data_id", "restaurants_order"."restaurant_id" FROM "restaurants_order" WHERE "restaurants_order"."id" = 1 UPDATE "restaurants_order" SET "state" = 1, "order_date" = 2011-06-16, "contact_data_id" = 3, "restaurant_id" = 1 WHERE "restaurants_order"."id" = 1