Ich erstelle eine Access DB für die Verwendung in einer C# -Anwendung in der Schule. Ich habe nicht viel Erfahrung mit DBs gearbeitet, also wenn das dumm klingt, ignoriere es einfach. Ich möchte, dass der Benutzer alle die Klassen auswählen kann, die ein bestimmter Student in unserer IT-Abteilung gehabt hat. Wir haben ungefähr 30 in allen und das Maximum, dass eine Person in 4 Jahren der Highschool nehmen kann, ist 15. Im Moment hat meine Datenbank 15 verschiedene Spalten für jede Klasse, die ein Benutzer haben könnte. Wie kann ich dies auf eine Spalte komprimieren (wenn es einen Weg gibt)?Wie werden mehrere Spalten in einer Datenbank gelöscht?
Antwort
Ausgezeichnete Frage Lucas, und diese vertieft sich in die Handlung der Datenbanknormalisierung.
Die Tatsache, dass Sie erkannt haben, warum mehrere Spalten zur Darstellung von Klassen schlecht sind, zeigt bereits, dass Sie ein großes Potenzial haben.
Was wäre, wenn wir eine neue Klasse hinzufügen möchten? Jetzt müssen wir eine ganz neue Spalte hinzufügen. Es gibt wenig Flexibilität dafür.
Was kann also getan werden?
Wir erstellen drei Tabellen.
Ein Tisch ist für Studenten:
Student
|-------------------------|
| StudentID | Student_Name|
|-------------------------|
| 1 | John |
| 2 | Sally |
| 3 | Stan |
---------------------------
Eine Tabelle für die Klassen ist:
Class
------------------------
| ClassID | Class_Name|
------------------------
| 1 | Math |
| 2 | Physics |
------------------------
Und schließlich eine Tabelle hält die Beziehung zwischen Schüler und Klassen:
Student_Class
-----------------------
| StudentID | ClassID |
-----------------------
Wenn wir John in Physik einschreiben wollten, würden wir eine Zeile in die Tabelle Student_Class einfügen.
INSERT INTO Student_Class (StudentID, ClassID) VALUES (1, 2);
Jetzt haben wir eine Aufzeichnung, die besagt, dass Student # 1 (John) Klasse 2 (Physik) besucht. Lass uns Sally Mathe besuchen und Stan Physik und Mathe besuchen.
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);
Um diese Daten wieder in einer lesbaren Art und Weise zu ziehen, verbinden wir die drei Tabellen zusammen:
------------------------------
| Student_Name | Class_Name |
------------------------------
| John | Physics |
| Sally | Math |
| Stan | Physics |
| Stan | Math |
------------------------------
Und das:
SELECT Student.Student_Name,
Class.Class_Name
FROM Student,
Class,
Student_Class
WHERE Student.StudentID = Student_Class.StudentID
AND Class.ClassID = Student_Class.ClassID;
Das uns ein Ergebnis wie dieses Set geben würde, So funktioniert die Datenbanknormalisierung auf den Punkt gebracht.
Wie wäre es mit keiner Klasse Spalten in der Schüler-Tabelle. Richten Sie eine neue Tabelle mit Spalten für Studenten-IDs und Klassen-IDs ein. Jede Zeile repräsentiert eine Klasse, die der Schüler belegt hat. Vielleicht fügen Sie weitere Spalten wie: das Jahr/Semester, Klasse usw.
Können Sie diese ein wenig mehr erklären, verstehe ich nicht genau. – Kredns
Es klingt wie Sie über normalizing Ihr Datenbankschema denken müssen.
Es gibt eine many-to-many relationship zwischen Schülern und Klassen, so dass viele Schüler viele Klassen belegen können und viele Klassen können von vielen Schülern belegt werden. Der am häufigsten verwendete Ansatz zur Handhabung dieses Szenarios ist die Verwendung eines junction table.
So etwas wie dieses
Student Table
-------------
id
first_name
last_name
dob
Class Table
-----------
id
class_name
academic_year
Student_Class Table
-------------------
student_id
class_id
year_taken
Dann Ihre Anfragen auf den Tischen, zum Beispiel anschließen würden,
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
Ein Wort der Beratung, die ich erwähnen möchte, ist, dass Access erfordert, dass Sie Klammern zu verwenden, wenn Ich glaube, dass dies der Grund dafür ist, dass Sie eine Reihenfolge angeben müssen, in der Sie sie verknüpfen möchten. Persönlich finde ich das peinlich, besonders wenn ich es gewohnt bin, ohne Designer viel SQL zu schreiben. In Access würde ich empfehlen, den Designer zum Verknüpfen von Tabellen zu verwenden und dann das generierte SQL für Ihre Zwecke zu ändern.
Sie haben also 15 Spalten (z. B. Klasse1, Klasse2, Klasse3 ... Klasse15)?
Sieht aus, als ob Sie eine klassische many-to-many relationship haben. Sie sollten eine neue Tabelle erstellen, um Schüler und Klassen zu verbinden.
student { StudentID, StudentName ... }
classes { ClassID, ClassName ... }
student_classes { StudentID, ClassID }
Wenn Sie Klassen auf einem Jahr-für-Jahr Basis verfolgen, könnten Sie auch ein Jahr Spalte der Beziehung hinzu:
student_classes { StudentID, Year, ClassID }
Dies ist ein Normalisierungsproblem. In der Tat stellen Sie die falsche Frage. Stelle dir stattdessen die Frage, wie kannst du 0 oder mehr class_taken speichern? Welche weiteren Informationen müssen Sie zu jeder Klasse speichern? Z.B. nur die Klasse genommen, oder Daten genommen, Ergebnis, etc?
Zum Beispiel betrachten somethin wie die folgenden
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) ...
Sie nie Spalten wie class1, class2, class3, class4 etc in einer Datenbanktabelle haben sollten. Was Sie haben sollten, ist eine verwandte Tabelle. Ihre stucture wäre so etwas wie:
Student Table with the following columns
StudentID
StudentLastName
StudentFirstName
(and so forth for all the data to describe a student)
Dann
Course table with the following columns
CourseId
CourseName
Dann
StudentCourse Table with the following columns
StudentId
CourseID
CourseDate
Nun, um herauszufinden, welche Kurse die Person, die Sie zusammen diese Tabellen zusammenfand. Etwas wie:
Select StudentID,StudentLastName,StudentFirstName, CourseName, CourseDate
from Student
join StudentCourse on student. studentid = StudentCourse.StudentID
join Course on Course.courseID = StudentCourse.CourseID
diesen Link Bitte lesen Sie lernen Datenbank Grundlagen zu starten: http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx
I aqree ... die Flagge werfen, wenn Sie mehr als eine Spalte haben, die auf den gleichen FK zeigt * und * die Spalte eine Nummer hat, die dem Namen folgt. – dotjoe
Ausgezeichnete Antwort. Zusätzlich zu den (wertvollen, korrekten) Informationen möchte ich hinzufügen, dass Sie zusätzliche Daten über die genommenen Klassen speichern können. Wenn deine DB der Org nützlich ist, wird sie in späteren Jahren verbessert. Dieses Design ermöglicht das. Jahr genommene Klasse, Tutor, Ergebnis, usw. können addiert werden. – Karl
Danke für das Kompliment, aber ehrlich gesagt konnte ich es einfach nicht ertragen, horizontal durch 15 Klassen zu scrollen. Ihre Antwort hat mir sehr geholfen und jetzt lese ich über die Normierung.Ich denke, mit Hilfe deines Designs werde ich in der Lage sein, eine anständige App für meinen Lehrer zu machen (sie wird sie tatsächlich benutzen). – Kredns