Witam,
Mam nadzieję, że nadaje się ten wątek na to forum, gdyż raczej bliżej temu tematyce baz danych niż tematyce forum oceny.
Bardzo proszę o ocenę, wskazanie błędów i uwag następującego projektu bazy danych (opartym na mysql’u). Poniżej przedstawiam obrazek, gdzie zostało wszystko przedstawione graficznie:
[img]
http://members.lycos.co.uk/michalhyzy/img/projekt.gif
[/img]
Poniżej kod w języku SQL:
[sql:1:563b2e35b1]
CREATE TABLE uzytkownicy (
uzyt_nazwa CHAR(16) NOT NULL,
uzyt_haslo CHAR(32) NOT NULL,
uzyt_email VARCHAR(255) NOT NULL,
PRIMARY KEY (uzyt_nazwa),
UNIQUE KEY uzytkownicy(uzyt_nazwa)
);
CREATE TABLE uzytkownicy_www (
uzyt_nazwa CHAR(16) NOT NULL,
uzyt_www_adres VARCHAR(255) NOT NULL,
uzyt_www_opis TEXT NOT NULL,
PRIMARY KEY (uzyt_nazwa)
);
CREATE TABLE uzytkownicy_komunikatory (
uzyt_kom_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
uzyt_kom_nazwa CHAR(64) NOT NULL,
uzyt_kom_opis VARCHAR(255) NOT NULL,
PRIMARY KEY (uzyt_kom_id),
UNIQUE (uzyt_kom_nazwa),
UNIQUE KEY komunikatory(uzyt_kom_nazwa)
);
CREATE TABLE uzytkownicy_uprawienia (
upr_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
upr_nazwa CHAR(32) NOT NULL,
upr_opis VARCHAR(255) NOT NULL,
PRIMARY KEY (upr_id)
);
CREATE TABLE uzytkownicy/uzytkownicy_uprawienia (
uzyt_nazwa CHAR(16) NOT NULL,
upr_id INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (uzyt_nazwa, upr_id)
);
CREATE TABLE uzytkownicy/komunikatory (
uzyt_nazwa CHAR(16) NOT NULL,
uzyt_kom_id INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (uzyt_nazwa, uzyt_kom_id)
);
CREATE TABLE uzytkownicy_dane (
uzyt_nazwa VARCHAR(16) NOT NULL,
uzyt_dane_imie CHAR(20),
uzyt_dane_nazwisko CHAR(30),
uzyt_dane_miejscowosc VARCHAR(50),
uzyt_dane_data_urodzenia DATE,
uzyt_dane_data_rejestracji TIMESTAMP(14) NOT NULL,
uzyt_dane_ostatnia_wizyta TIMESTAMP(14) NOT NULL,
PRIMARY KEY (uzyt_nazwa),
UNIQUE KEY uzytkownicy_dane(uzyt_nazwa)
);
CREATE TABLE wiadomosci (
wiad_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
wiad_dzial_id INTEGER UNSIGNED NOT NULL,
uzyt_nazwa CHAR(16) NOT NULL,
wiad_tytul VARCHAR(128) NOT NULL,
wiad_naglowek TEXT NOT NULL,
wiad_czas TIMESTAMP(14) NOT NULL,
wiad_wyswietlenia INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (wiad_id)
);
CREATE TABLE wiadomosci_dzialy (
wiad_dzial_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
wiad_dzial_nazwa CHAR(20) NOT NULL,
PRIMARY KEY (wiad_dzial_id)
);
CREATE TABLE wiadomosci_teksty (
wiad_id INTEGER UNSIGNED NOT NULL,
wiad_tekst TEXT NOT NULL,
PRIMARY KEY (wiad_id)
);
CREATE TABLE wiadomosci_obrazki (
wiad_obrazek_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
wiad_id INTEGER UNSIGNED NOT NULL,
wiad_obrazek_plik CHAR(15) NOT NULL,
wiad_obrazek_opis VARCHAR(255) NOT NULL,
PRIMARY KEY (wiad_obrazek_id)
);
CREATE TABLE wiadomosci_wyszukiwarka (
wiad_wysz_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
wiad_id INTEGER UNSIGNED NOT NULL,
wiad_wysz_fraza CHAR(40) NOT NULL,
wiad_wysz_waga ENUM('1','2','3','4','5','6') NOT NULL,
PRIMARY KEY (wiad_wysz_id),
KEY wiadomosci_wyszukiwarka(wiad_wysz_fraza)
);
CREATE TABLE wiadomosci_komentarze (
wiad_kom_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
wiad_id INTEGER UNSIGNED NOT NULL,
wiad_kom_tytul VARCHAR(32) NOT NULL,
wiad_kom_tresc TEXT NOT NULL,
uzyt_nazwa CHAR(16) NOT NULL,
wiad_kom_czas TIMESTAMP(14) NOT NULL,
PRIMARY KEY (wiad_kom_id)
);
CREATE TABLE sondy (
sonda_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
sonda_pytanie VARCHAR(255) NOT NULL,
sonda_czas TEXT NOT NULL,
uzyt_nazwa CHAR(16) NOT NULL,
PRIMARY KEY (sonda_id)
);
CREATE TABLE sondy_opcje (
sonda_opcja_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
sonda_id INTEGER UNSIGNED NOT NULL,
sonda_opcja_nazwa VARCHAR(255),
PRIMARY KEY (sonda_opcja_id)
);
CREATE TABLE sondy_glosy (
sonda_glos_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
sonda_opcja_id INTEGER UNSIGNED NOT NULL,
sonda_glos_czas TIMESTAMP(14) NOT NULL,
uzyt_nazwa CHAR(16),
PRIMARY KEY (sonda_glos_id)
);
CREATE TABLE sondy_biezaca (
sonda_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (sonda_id)
);
ALTER TABLE uzytkownicy_www
ADD FOREIGN KEY (uzyt_nazwa) REFERENCES uzytkownicy (uzyt_nazwa);
ALTER TABLE uzytkownicy/uzytkownicy_uprawienia
ADD FOREIGN KEY (uzyt_nazwa) REFERENCES uzytkownicy (uzyt_nazwa);
ALTER TABLE uzytkownicy/uzytkownicy_uprawienia
ADD FOREIGN KEY (upr_id) REFERENCES uzytkownicy_uprawienia (upr_id);
ALTER TABLE uzytkownicy/komunikatory
ADD FOREIGN KEY (uzyt_nazwa) REFERENCES uzytkownicy (uzyt_nazwa);
ALTER TABLE uzytkownicy/komunikatory
ADD FOREIGN KEY (uzyt_kom_id) REFERENCES uzytkownicy_komunikatory (uzyt_kom_id);
ALTER TABLE uzytkownicy_dane
ADD FOREIGN KEY (uzyt_nazwa) REFERENCES uzytkownicy (uzyt_nazwa);
ALTER TABLE wiadomosci
ADD FOREIGN KEY (wiad_dzial_id) REFERENCES wiadomosci_dzialy (wiad_dzial_id);
ALTER TABLE wiadomosci
ADD FOREIGN KEY (uzyt_nazwa) REFERENCES uzytkownicy (uzyt_nazwa);
ALTER TABLE wiadomosci_teksty
ADD FOREIGN KEY (wiad_id) REFERENCES wiadomosci (wiad_id);
ALTER TABLE wiadomosci_obrazki
ADD FOREIGN KEY (wiad_id) REFERENCES wiadomosci (wiad_id);
ALTER TABLE wiadomosci_wyszukiwarka
ADD FOREIGN KEY (wiad_id) REFERENCES wiadomosci (wiad_id);
ALTER TABLE wiadomosci_komentarze
ADD FOREIGN KEY (wiad_id) REFERENCES wiadomosci (wiad_id);
ALTER TABLE sondy
ADD FOREIGN KEY (uzyt_nazwa) REFERENCES uzytkownicy (uzyt_nazwa);
ALTER TABLE sondy_opcje
ADD FOREIGN KEY (sonda_id) REFERENCES sondy (sonda_id);
ALTER TABLE sondy_glosy
ADD FOREIGN KEY (sonda_opcja_id) REFERENCES sondy_opcje (sonda_opcja_id);
ALTER TABLE sondy_biezaca
ADD FOREIGN KEY (sonda_id) REFERENCES sondy (sonda_id);
[/sql:1:563b2e35b1]
Teraz kilka słów komentarza i mój punkt widzenia na to:
Każdy kto zechce się zarejestrować musi podać dane z tabeli użytkownicy. Jako dodatkowe dane będzie mógł podać informację, które zostały przedstawione w tabeli: użytkownicy_dane. Oprócz pól uzyt_nazwa oraz użyt_dane_data_rejestracji i użyt_dane_ostatnia_wizyta pozostałe mogą pozostać puste (nie użyto atrybutu NOT NULL). Zdecydowałem się na umieszczenie tego w jednej tabeli (mimo iż niektóre rekordy mogą zawierać puste pola) gdyż nie chciałem tworzyć dodatkowych tabel z jednym polem a następnie relacji wiele do wielu przy użyciu tabeli łączącej. Wg. mnie to za bardzo „rozdrobniłoby” projekt. Dodatkowo użytkownik może podać z jakich komunikatorów korzysta (relacja n – n). Podobnie ze możliwością podania adresu strony WWW wraz z dodatkowym opisem (relacja 1 – n). Każdy użytkownik będzie miał przypisane prawa jakie mu przysługują: w tabeli użytkownicy_uprawnienia będą wszystkie „tyty” praw na stronie (np. administrator, pisarz tekstów, dostęp do forum itp.).
Jeżeli chodzi o system wiadomości to główna tabela wiadomości zawiera dane (zob. rysunek). Każda wiadomość zostanie przypisana do jednego z działów na stronie (np. aktualności, artykuły, inne). Zostało to przedstawione na schemacie. Nie wiem tylko, czy powinienem zrobić tutaj zrobić relację wiele do wielu i wstawić tabelę łączącą czy też pozostawić tak jak to jest. Proszę o komentarz, bo takich sytuacja mam w tym projekcie więcej. Aby oddzielić nagłówek (pierwszy akapit tekstu) tworzę dodatkową tabelę zawierającą numer wiadomości i treść. Do każdej wiadomości może zostać zamieszczona pewna ilość obrazków (właśnie przypomniałem sobie, że powinienem ustalić stopień uczestnictwa tabeli w relacji – hmm…. jak to zrobić??, jak wygląda to w języku sql??). Każdy kto będzie pisał wiadomośc uzupełnić będzie musiał słowa kluczowe dla wiadomości oraz ich wagę. Będzie to wykorzystywane przy wyszukiwarce. Każda wiadomość będzie mogła zostać skomentowana.
Na stronie będzie możliwość wzięcia udziału w sondzie. Każda sonda będzie miała przypisanego użytkownika (mającego prawo do tego). W sondzie będzie istniała możliwość oddania głosu na jedną z dowolnej ilości opcji (właśnie zastanawiam się, czy też nie ograniczyć tego). Każdy głos będzie rejestrowany w tabeli sondy_głosy. Przypisany jest on do jednej z opcji. Dodatkowo rejestrowany jest czas oddania głosu (np. aby ustalić w jakich dniach, porach użytkownicy najczęściej oddają głosy). Dodatkowo istnieje możliwość (brak atrybuty (NOT NULL) zapisania użytkownika, który oddał głos.
To jest dopiero część mojego projektu. Zostało do napisania trochę (forum, jakiś system subskrypcji, itd.). Jednak chciałem się w tej chwili zorientować poprzez komentarze osób znających się o wiele lepiej na bazach danych i ich projektowaniu czy to co jest do tej pory jest zaprojektowane poprawnie.
Nie ustaliłem reguł usuwania rekordów – będzie to musiała być metoda restrykcyjna.
Uff, trochę tego jest. Nie wiem czy komuś będzie się chciało to wszystko czytać i analizować w związku z tym już w tej chwili dziękuję za wszystkie wskazówki. Postokroć dzięki!!
===============
Uaktualnienie:
Zapomniałem zamieścić jednej tabeli dot. sond (zostało mi na wersji papierowej). Otóż dołożona jest tabela sondy_bieżąca w której znajduje się id bieżącej (czyli wyświetlanej na stronie www) sondy.