To your specific question of (easily satisfied) plausibility, the answer is yes. Since you seem to be looking for a broader critique. You seem to be mostly on the right track, but a few things are making your description overly complex.
It looks like your Classes table is more like what I would consider a course to be and your departments_teachers_and_classes is more of what I would expect a Classes table to be. A course would be Math, but a class would be the Math course taught by a particular teacher during a particular school term. A class is like an instance of a course.
To carry this change through, your departments_teachers_classes_and_students could simply be ClassStudents.
It seems as though you are using the department concept on several different levels. You should decide where the department belongs and stop referencing it everywhere else. You've said that a teacher can teach for multiple departments, so we can't put the department in the teachers table. This leaves Classes and Courses. Whichever you decide, it need only have a foreign key to the Departments table (unless you decide that one can be in multiple Departments). This eliminates the Departments_and_teachers table.
Teachers_and_Students could be replaced with a teacher foreign key in the Classes table and students/classes foreign keys in a ClassStudents table.
In short, for the portion of the design you have described, you probably need the following tables:
Departments
Teachers
Students
Courses
Classes
ClassStudents
Terms
Kudos for trying to get it right, and understand the principles. I've been doing this for years and still find it difficult to label existing structures with precisely accurate relational theory terminology at times.
Normal forms, it's important to note, only describe individual relations (that is, "tables," in SQL), and not the relationships between them... so the frequent appearance of justification_id does not in any sense move your tables further from 2NF. Indeed, these are all tables of attributes about justifications, so it's only sensible that the justification would appear.
The justification_id seems to be a candidate key, or at least a prime attribute, in each table... isn't it? Candidate keys, pretty much by definition, can't have a denormalizing effect. It's the other attributes that must be analyzed.
I'm confused about category and category_id. Would "category" be (e.g.) "ticket" and "category_id" be (e.g.) "27"...? If so, your naming is a little counter-inituitive, and you're going off in a direction that normalization doesn't really address, but that may cause you difficulty later -- you're mixing data domains in a single attribute (column).
By that, I mean this: the value of "category_id" might be an id from the "ticket" table or an id from the "order" table, etc., depending on which type of category. If I am right about what these columns are being used for, then you don't want to do this, because (among other reasons) it is impossible for the database to correctly impose a foreign key constraint on this column. As a rule of thumb, a value in a column should mean the exact same thing regardless of what's contained in any other column. It might be more correct if there were junction tables, "ticket_has_justification" (with a ticket_id and justification_id), "order_has_justification" (order_id, justification_id), etc. You can still outer join all justifications to the various types of things they justify, but this is a cleaner approach, at least in my opinion.
The "questions" column also might be more appropriate in a "question" table, with justification_response having a question_id column referencing it, but here again, this isn't really addressed by normalization -- whether it's stored in this table as the words of the question, or as a surrogate for the words (question_id), the "question" column is still a prime attribute, with (justification_id, question) being the candidate key and response being dependent on both, so this one is at least 3NF, despite having what looks to me like room for improvement.
Fundamentally, though, I don't see what isn't 2NF about any of these... depending on exactly what "category" and "category_id" mean.
Best Answer
NOTE
Many-to-Many relationships are represented by a linking table.
You are missing the link between Student(s) and Class(es)
Adjustment
Your
Grades
table can then be modified to reference the PK ofclass_enrollment
.Overall Grade
If you can always calculate a Summary value, You can hide the calculation in a
VIEW
(or aMATERIALIZED VIEW
).But, since teachers can override the calculated value, you'll want to store the Summary in the "parent table".
In your case, the "parent table" to
Grades
would beClass_Enrolement
.