Projekt logiczny
1. 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.
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.
Kod SQL generujący bazę
2. 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
3. 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
Wszystkie pola są zależne od klucza głównego i nie mogą bez tego istnieć.
Wszystkie pola zależne od klucza głównego
Parametry niekluczowe (user_comment, ratio) zależne od klucza głównego.
Atrybuty is_promo oraz activation_key są zależne od klucza głównego restauracji
Ponownie wszystkie atrybuty niekluczowe są zależne tylko od klucza głównego
Wszystkie atrybuty zależne od klucza
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).
4. 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
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)
INSERT INTO "accounts_contactdata" ("city", "street", "flat_number", "pna", "phone", "lat", "lng") VALUES (city, street, flat_number, zip, phone_number, None, None)
INSERT INTO "accounts_userprofile" ("user_id", "contact_data_id", "activation_key") VALUES (2, 1, a1d96ad94e96abc3247c41c888fbf7bc4c7a9770)
Rejestracja restauracji
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)
INSERT INTO "accounts_contactdata" ("city", "street", "flat_number", "pna", "phone", "lat", "lng") VALUES (krakow, lea, 5, zip, tel, 50.0694749, 19.9237717)
INSERT INTO "restaurants_description" ("name", "description", "img") VALUES (Nazwa, Opis, )
INSERT INTO "restaurants_restaurant" ("user_id", "is_promo", "activation_key", "contact_data_id", "description_id") VALUES (4, False, 1e7628f58f2ef403653e42fbd9ed2a4891fa5907, 2, 2)
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)
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)
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