2009-04-08 16 views
5

Tworzę DB Access do użytku w aplikacji C# w szkole. Nie miałem zbyt dużego doświadczenia w pracy z DB, więc jeśli to brzmi głupio, po prostu zignoruj ​​to. Chcę, aby użytkownik mógł wybrać klasy, które pewien student miał w naszym dziale IT. Mamy około 30, a maksymalna, jaką dana osoba może mieć w ciągu 4 lat liceum, wynosi 15. Teraz mój DB ma 15 różnych kolumn dla każdej klasy, którą może mieć użytkownik. Jak mogę skompresować to do jednej kolumny (jeśli jest sposób)?Jak pozbyć się wielu kolumn w bazie danych?

Odpowiedz

18

Doskonałe pytanie Lucasa, a to zagłębia się w akcie normalizacji bazy danych.

Fakt, że uznano, że posiadanie wielu kolumn do reprezentowania klas jest złe pokazuje, że masz duży potencjał.

Co jeśli chcemy dodać nową klasę? Teraz musimy dodać zupełnie nową kolumnę. Ta elastyczność jest niewielka.

Co można zrobić?

Tworzymy TRZY tabele.

Jedna tabela jest dla studentów:

Student 
    |-------------------------| 
    | StudentID | Student_Name| 
    |-------------------------| 
    |  1  |  John | 
    |  2  |  Sally | 
    |  3  |  Stan | 
    --------------------------- 

Jedna tabela jest dla klasy:

Class 
    ------------------------ 
    | ClassID | Class_Name| 
    ------------------------ 
    | 1  | Math | 
    | 2  | Physics | 
    ------------------------ 

I wreszcie, jedna tabela przechowuje relacje między uczniami i ćwiczenia:

Student_Class 
    ----------------------- 
    | StudentID | ClassID | 
    ----------------------- 

Gdybyśmy chcieli zapisać Johna do fizyki, wstawilibyśmy wiersz do tabeli Student_Class.

INSERT INTO Student_Class (StudentID, ClassID) VALUES (1, 2); 

Teraz mamy zapis mówiący, że Student nr 1 (John) uczęszcza do klasy nr 2 (fizyka). Pozwólmy Sally uczestniczyć w matematyce, a Stan będzie uczęszczał na zajęcia z fizyki i matematyki.

INSERT INTO Student_Class (StudentID, ClassID) VALUES (2, 1); 
    INSERT INTO Student_Class (StudentID, ClassID) VALUES (3, 1); 
    INSERT INTO Student_Class (StudentID, ClassID) VALUES (3, 2); 

Aby wyciągnąć te dane z powrotem w czytelny sposób, możemy połączyć trzy tabele razem:

SELECT Student.Student_Name, 
     Class.Class_Name 
    FROM Student, 
     Class, 
     Student_Class 
    WHERE Student.StudentID = Student_Class.StudentID 
     AND Class.ClassID = Student_Class.ClassID; 

Dałoby to nam wynik ustawiony tak:

------------------------------ 
    | Student_Name | Class_Name | 
    ------------------------------ 
    | John  | Physics | 
    | Sally  | Math  | 
    | Stan  | Physics | 
    | Stan  | Math  | 
    ------------------------------ 

i że jak działa normalizacja baz danych w pigułce.

+0

Doskonała odpowiedź. Oprócz dodanych (cennych, poprawnych) informacji, dodałbym, że możesz przechowywać dodatkowe dane o zajęciach. Jeśli DB jest użyteczny dla Org, to będzie ulepszany w późniejszych latach. Ten projekt pozwala na to. Można dodać klasę roku, korepetycje, wyniki itp. – Karl

+0

Dzięki za komplement, ale szczerze mówiąc po prostu nie mogłem znieść horiszontalnie przez 15 lekcji. Twoja odpowiedź naprawdę pomogła i teraz zacząłem czytać o normalizacji.Myślę, że dzięki twojemu projektowi będę w stanie stworzyć przyzwoitą aplikację dla mojego nauczyciela (ona faktycznie z niej skorzysta). – Kredns

1

Co powiecie na brak kolumn klas w tabeli ucznia. Skonfiguruj nową tabelę z identyfikatorami ucznia i kolumnami identyfikatora klasy. Każdy wiersz reprezentuje klasę, którą uczeń wziął. Może dodać więcej kolumn, takich jak: rok/semestr, ocena, itp.

+0

można wyjaśnić nieco więcej, nie dokładnie śledzić. – Kredns

4

Wygląda na to, że trzeba pomyśleć o schemacie bazy danych w wersji normalizing.

Istnieje many-to-many relationship między uczniami i klasami tak, że wielu uczniów może wziąć wiele zajęć i wielu klas może być zajętych przez wielu uczniów. Najczęstszym podejściem do radzenia sobie z tym scenariuszem jest użycie junction table.

coś takiego

Student Table 
------------- 
id 
first_name 
last_name 
dob 

Class Table 
----------- 
id 
class_name 
academic_year 

Student_Class Table 
------------------- 
student_id 
class_id 
year_taken 

wówczas zapytań dołączy na stołach, na przykład,

SELECT 
    s.last_name + ', ' + s.first_name AS student_name, 
    c.class_name, 
    sc.year_taken 
FROM 
    student s 
INNER JOIN 
    student_class sc 
ON 
    s.id = sc.student_id 
INNER JOIN 
    class c 
ON 
    sc.class_id = class.id 
ORDER BY 
    s.last_name, sc.year_taken 

Jedno słowo rady, że chciałbym wspomnieć, jest to, że dostęp wymaga użycia nawiasów gdy dołączając więcej niż tabelę w zapytaniu, uważam, że dzieje się tak dlatego, że wymaga ona określenia kolejności, w której chcesz do nich dołączyć. Osobiście uważam to za niezręczne, szczególnie gdy jestem przyzwyczajony do pisania dużo SQL bez projektantów. W programie Access zalecam używanie projektanta do łączenia tabel, a następnie modyfikowanie wygenerowanego kodu SQL dla własnych celów.

4

Masz 15 kolumn (np. Klasa 1, klasa 2, klasa 3 ... klasa 15)?

Wygląda na to, że masz klasyczny many-to-many relationship. Powinieneś utworzyć nową tabelę, aby powiązać uczniów i klasy.

student { StudentID, StudentName ... } 
classes { ClassID, ClassName ... } 
student_classes { StudentID, ClassID } 

Jeśli śledzisz zajęcia w oparciu o rok po roku, można dodać kolumnę rok do relacji, a także:

student_classes { StudentID, Year, ClassID } 
2

Jest to problem normalizacyjny. W efekcie zadajesz niewłaściwe pytanie. Zamiast tego zadaj sobie pytanie, jak możesz przechowywać 0 lub więcej zajęć klas? Jakie inne szczegóły musisz przechowywać w odniesieniu do każdej z lekcji? Na przykład. tylko podjęte zajęcia, dane, wyniki itp.?

Na przykład rozważyć coś jak na poniższym

 
table Student 
id int 
name varchar(25) 
... 

table classes 
id int 
name varchar(25) 
... 

table clases_taken 
student_id int (foreign key to student.id) 
class_id int (foreign key to class.id) 
data_started datatime 
result varchar(5) 
tutor_id int (foreign key to tutor.id) 
... 

2

Nigdy nie powinno mieć kolumny jak Class1, Klasa2 Klasa3, class4 itp w tabeli bazy danych. To, co powinieneś mieć, to powiązana tabela. Twój stucture byłoby coś jak:

Student Table with the following columns 
StudentID 
StudentLastName 
StudentFirstName 
(and so forth for all the data to describe a student) 

Następnie

Course table with the following columns 
CourseId 
CourseName 

Następnie

StudentCourse Table with the following columns 
StudentId 
CourseID 
CourseDate 

teraz, aby dowiedzieć się, jakie kursy osoba miały dołączyć do tych tabel razem. Coś jak:

Select StudentID,StudentLastName,StudentFirstName, CourseName, CourseDate 
from Student 
join StudentCourse on student. studentid = StudentCourse.StudentID 
join Course on Course.courseID = StudentCourse.CourseID 

Proszę przeczytać ten link, aby rozpocząć naukę podstaw baz danych: http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx

+0

I aqree ... wyrzuć flagę, jeśli masz więcej niż jedną kolumnę wskazującą na to samo FK * i * ta kolumna ma numer następujący po nazwie. – dotjoe

Powiązane problemy