| Lesson 4 | Diagramming entities and attributes |
| Objective | Identify conventions for diagramming entities and attributes in Crow's Foot notation. |
A Crow's Foot diagram combines entity boxes, attribute lists, and relationship endpoints. Each part has a distinct purpose: the entity names what is being modeled, its attributes describe instances, and the connectors state how instances may be related.
This lesson uses STUDENT, CLASS, and STUDENT_CLASS to show these conventions together. Here, CLASS means one specific class offering, not a course catalog entry reused across terms. Each student can enroll at most once in that offering. A later offering receives a different ClassID.
Some tools use CPK for composite primary-key members or special corners for associative entities. Those markings are not universal Crow's Foot requirements. Use an explicit legend and consistent PK/FK labels.
A student can enroll in many classes, and a class can have many students. STUDENT_CLASS records each student-class pairing. This associative entity implements the M:N relationship as two 1:N relationships.
STUDENT stores student facts; CLASS stores class-offering facts. STUDENT_CLASS stores the enrollment relationship. A row such as (101, 501) means student 101 is enrolled in class 501. It does not duplicate the student's name or the class name.
The STUDENT and CLASS endpoints each show exactly one. The two endpoints beside STUDENT_CLASS show zero or many. Read the symbols at an endpoint as the number of instances at that end associated with one instance at the opposite end. A student may therefore have no enrollments, and a class may have no students yet.
| Attribute | Role |
|---|---|
| STUDENT.StudID | Primary key identifying a student |
| CLASS.ClassID | Primary key identifying one class offering |
| STUDENT_CLASS.StudID | Part of the composite primary key and a foreign key to STUDENT |
| STUDENT_CLASS.ClassID | Part of the same composite primary key and a foreign key to CLASS |
| EnrolledOn and Grade | Non-key attributes describing the student-class relationship |
The pair must be unique, but either component can repeat. Student 101 may appear with classes 501 and 502, and class 501 may appear with students 101 and 102. Marking either junction column UNIQUE by itself would wrongly restrict this many-to-many design.
An associative table can use a different key strategy when business rules justify it. Here, the pair is sufficient. If the design must record multiple enrollment attempts for the same student and class offering, its identity rule must change; the current key intentionally permits only one row per pair.
This complete example can be run in SQLite with foreign-key enforcement enabled. Run the PRAGMA before beginning a transaction. IDs are supplied explicitly. Other database systems may need different setup or data types; SQLite accepts the ISO date strings shown here but has no dedicated DATE storage type.
PRAGMA foreign_keys = ON;
CREATE TABLE STUDENT (
StudID INTEGER PRIMARY KEY,
LastName VARCHAR(60) NOT NULL,
FirstName VARCHAR(60) NOT NULL
);
CREATE TABLE CLASS (
ClassID INTEGER PRIMARY KEY,
ClassName VARCHAR(120) NOT NULL
);
CREATE TABLE STUDENT_CLASS (
StudID INTEGER NOT NULL,
ClassID INTEGER NOT NULL,
EnrolledOn DATE NOT NULL,
Grade VARCHAR(2),
CONSTRAINT pk_student_class PRIMARY KEY (StudID, ClassID),
CONSTRAINT fk_enrollment_student
FOREIGN KEY (StudID) REFERENCES STUDENT(StudID),
CONSTRAINT fk_enrollment_class
FOREIGN KEY (ClassID) REFERENCES CLASS(ClassID)
);
The primary key prevents a duplicate pairing. The two foreign keys require existing parents, and NOT NULL prevents either reference from being omitted. Grade can be NULL before a grade is assigned. The example does not define a grading scale; any permitted-grade constraint must follow the institution's rules.
INSERT INTO STUDENT VALUES
(101, 'Rivera', 'Elena'),
(102, 'Lee', 'Morgan');
INSERT INTO CLASS VALUES
(501, 'Database Design'),
(502, 'SQL Fundamentals');
INSERT INTO STUDENT_CLASS VALUES
(101, 501, '2026-10-16', NULL),
(101, 502, '2026-10-16', NULL),
(102, 501, '2026-10-16', NULL);
These three enrollments are valid. Student 101 repeats and class 501 repeats, but no pair repeats. Run the following statement separately as an intentional failure:
-- Rejected: student 101 is already enrolled in class 501
INSERT INTO STUDENT_CLASS VALUES
(101, 501, '2026-10-17', NULL);
A different date does not make the pairing unique. An enrollment referencing a nonexistent student or class would fail a foreign key instead. Error messages and transaction recovery vary across database systems.
The next lesson examines data types in ER diagrams. Keep the distinction clear: a key states identity or a reference; a data type describes what values an attribute can store.