[SQL] Wartości unikalne w dwóch kolumnach bez klucza

Witam

Mam do zrobienia bazę danych. Nakreśliłem sobie poglądowy schemat w Accessie. Przepisuje do MSSql jednak napotkałem problem. Najlepiej najpierw zamieszczę schemat tabel.

schematc.png

Jest to prosty system rejestracji ocen końcowych

Założyłem, że jeden student może dostać tylko jedną ocenę z jednego przedmiotu prowadzonego przez jednego wykładowcę.

Problem napotkałem przy ID_PrzedWykl. W jednej tabeli jest to klucz złożony (po to żeby jeden student nie mógł dostać dwóch ocen z tego samego), a w drugiej nie jest kluczem a może powinien? Jednak wtedy tabela przyjmuje dane np. takie gdzie wpisuje dwa razy ten sam przedmiot i daję ocenę albo wpisuje z duplikowane wpisy w przemiot_wykładowca.

Ma ktoś jakiś pomysł? Jak tu klucze powinny być ustawione?

Najpierw częściowo odpowiem na Twoje pytanie. W przypadku tabeli PrzedmiotWykladowca możesz zrobić coś takiego, że na kolumnie ID_PrzedmiotWykladowca będziesz mieć klucz główny, a na kolumnach ID_Wykladowca oraz ID_Przedmiot będziesz mieć ustawiony indeks zapewniający unikalność. Reasumując dla jednej tabeli możesz mieć utworzoną dowolną ilość indeksów zapewniających unikalność na różnych kombinacjach kolumn.

Teraz odnośnie samego schematu bazy danych … musisz go przemyśleć :stuck_out_tongue: Przykładowo:

tabela Przedmiot - w ramach danego przedmiotu można uzyskać różną ilość punktów ECTS w zależności od tego na jakim kierunku się studiuje (na wszelki wypadek dopytaj w dziekanacie). Możesz też wprowadzić kolumnę Opis (krótka charakterystyka przedmiotu, tzn. co jest na nim przerabiane), która będzie zależna od kierunku i semestru studiów.

tabela Wykladowca, Student - może warto dodać osobne dwie tabele Osoba oraz OsobaAdres. Niech tabele Wykladowca oraz Student korzystają z tych dwóch tabel. Wprowadzisz coś na kształt obiektowości do danych relacyjnych.

Właśnie o te indeksy unikalności mi chodzi.

Create Index name

on Tabela (kol1, kol2);

Co do tabeli przedmiot nie mam zbytnio czasu na dopytywanie w dziekanacie :wink: trochę się to odłożyło i tak przeszło. Różna ilość punktów na różnych kierunkach hmm… Ciekawe jak z kodem przedmiotu, wpisałem kod przedmiotu w wyszukiwarkę i znalazło tylko jedną stronę na stronach politechniki opisującą ten przedmiot. Co do Osoba i OsobaAdres pamiętam w technikum tak robiliśmy ale z tego co pamiętam z wykładów (jak nie spałem) to babka mówiła właśnie o tym że wszyscy próbują tą obiektowość wprowadzać do baz danych i raczej tonem taki że tego nie poleca.

INDEX :stuck_out_tongue:. Sęk w tym, że Ty słów kluczowych nie musisz znać. Od tego jest MS SQL Server Management Studio, żeby sobie takowe indeksy paroma kliknięciami wygenerować.

No jak nie masz czasu dopytywać, to trudno. A jak z ilością godzin? Też jest zawsze taka sama dla każdego przedmiotu niezależnie od wydziału/kierunku/semestru?

Aha … ciekawe. No to pewno lepiej będzie jeśli będziesz się trzymał tego co wykładowca Ci powiedział (różnie może zareagować jak zaproponujesz inne rozwiązanie). Jeśli jednak będziesz chciał wprowadzić tą obiektowość, to zobacz jak to jest zrobione w AdventureWorks (takiej bazie danych opracowanej przez Microsoft).

Tu ma nie być żadnych kliknięć :wink: Mam mieć jeden pliczek .sql z tworzeniem tabel, wpisywaniem danych, wyzwalaczami, funkcjami, kwerendami. Ewentualnie ja bym dał wszystko w różnych plikach. A co do Obiektowości, wiadomo, życie, jednemu wykładowcy się spodoba, innemu nie, więc mimo iż wiemy swoje trzeba zrobić po wykładowemu żeby nie mieć obniżonej oceny.

A jak mam rozumieć Twoją wypowiedź? Jest funkcja w Management Studio żeby zrobić bazę a następnie dostać jej kod ?

Co do ilości godzin, nie projektuje tutaj systemu żeby go sprzedać tylko żeby pokazać że umiem posługiwać się w sqlu, podzieliłem jedynie na ćwiczenia i wykłady. Też bym chciał żeby to było na tiptop ale nie ma po prostu na to czasu.

Dokładnie tak. Klikasz prawym na nazwę bazy danych -> Tasks -> Generate Scripts… -> i jazda. Możesz sobie później ręcznie wprowadzić jakieś poprawki - oczywiście jeśli będzie taka potrzeba. Poza tym możesz podejrzeć kod SQL dla każdego obiektu w danej bazie danych. Załóżmy wygenerowałeś właśnie ten indeks, to teraz kliknij na jego nazwie prawym myszy -> Script Index as > Create to … -> np. New Query Editor Window -> i jazda.

Rozumiem.

Już wygenerowałem ten skrypt, strasznie sztucznie on wygląda, dużo przeróbek będzie trzeba tam wprowadzić. żeby wyglądał tak normalnie bez żadnych dodatkowych parametrów.

Tabela Przedmiot_wykladowca jest w ogóle niepotrzebna, a nawet szkodliwa, bo niepotrzebnie komplikuje strukturę bazy, a jej jedynym efektem jest zamiana dwóch wartości w jedną.

Tutaj wystarczyłaby tabela Oceny z kluczem głównym złożonym z ID_Przedmiot, ID_Wykladowca, ID_Student. Tylko to mało sensowne, bo co wówczas np. z poprawkami?

Myślę, że te trzy kolumny powinny być po prostu kluczami obcymi w tabeli Oceny, która miałaby też oczywiście swój własny PK ID_Oceny, ale również datę wystawienia oraz swój typ (termin normalny, poprawka). A baza danych nie powinna w ogóle dbać o unikalność przedmiotu, wykładowcy i studenta.

Jak najbardziej słuszne byłoby wprowadzenie tych tabel. Tylko to nie jest żadna obiektowość, tylko porządne podejście do projektowania baz danych. Ktoś mądry powiedziałby pewno, że to się nazywa trzecia postać normalna.

Nie, celem tej tabeli jest uwzględnienie sytuacji, że dany przedmiot może być prowadzony przez kilka różnych osób. Jednak na ile jest to możliwe, to już niestety nie wiem.

Z tego co pisał autor tematu wynika, że jednak nie. Może podpaść u wykładowcy.

Wykładowczyni :wink: bo pamiętam jak mieliśmy podstawy baz danych z kimś innym to właśnie bardzo nas męczył ze wszystkimi postaciami normalnymi :wink: a tutaj trochę inaczej. Mogę oczywiście tak zrobić a później zabłysnąć wiedzą o postaciach normalnych :wink:

Z tego co pisał autor, to wprowadzanie obiektowości jest “zuem”, a jako stwierdził, że spał i kojarzy zapewne pi * drzwi, to obiektowość, to umieszczenie obiektu, w tabeli (sprzeczne z atomową wartością), umieszczanie całych tabel itd. To jest po prostu jak stwierdzono powyżej 3 postać normalna. Chroni przed redundacją w przypadku, gdy np. magister studiuje, ale też jest wykładowcą. Zapiszesz go w dwóch tabelach?

Dodane 19.01.2012 (Cz) 23:21

Ja bym proponował, zrobić historię ocen i w ocenach trzymać ocenę aktualną, a w historii ocen wszystkie poprawki co by dało się wyliczyć średnią (bo one chyba też się liczą do średniej?), dodatkowo stare oceny (z zaliczonych semestrów), też możesz tam przekładać, i łatwiej będzie wybrać z tabeli aktualne przedmioty którymi katują studenta :stuck_out_tongue:

@Marcin511

Zabłysnąć, to Ty w ten sposób przed wykładowcą nie zabłyśniesz. Jeśli faktycznie chcesz podnieść Swoją ocenę w jego oczach, to zrób ten schemat porządnie. Tylko, że żeby to zrobić, to musisz się dopytać w dziekanacie jak to faktycznie jest z tymi punktami ECTS, godzinami i formą zaliczenia (wykład, ćwiczenia, laboratoria) :stuck_out_tongue: Wydaje mi się, że jest tutaj zależność od wydziału/kierunku/semestru studiów (być może też rodzaju studiów? - zaoczne, dzienne, jednolite, niejednolite, itp.), ale pewności nie mam.

W takim razie ta tabela jest zbyt uboga, powinna mieć też np. daty (albo lata akademickie/semestry) od kiedy do kiedy dany wykładowca prowadził ten przedmiot.

No cóż, w każdym razie, w prawdziwych systemach tak się po prostu robi. A jeśli wykładowca tego nie uznaje, to wiadomo już przynajmniej, czemu jest wykładowcą, a nie pracuje w branży.

Średnią z poprawkami będzie łatwiej wyliczyć, jeśli wszystkie oceny będą w jednej tabeli. Nie widzę też sensu przekładania ocen z poprzednich semestrów do innej tabeli, po co to wszystko?

Przedmiotów chcesz szukać w tabeli Ocen? Bez sensu, wystarczy z tabeli Przedmioty wybrać te, w których wartość pola Semestr jest równa numerowi semestrowi danego studenta. Jeśli natomiast na uczelni jest swoboda wyboru przedmiotów w semestrze przez studenta, to należy się zastanowić nad trochę bardziej złożonym schematem bazy.