Understanding relationships is crucial in database design. Let's break down the difference between Strong and Weak Relationships:
🟩 Strong Relationship
A Strong Relationship exists between two entities when the child entity (dependent) can be uniquely identified without relying on the parent.
Usually occurs between two strong (independent) entities
The related entities have primary keys of their own
📘 Example:
Entities:
Student(Student_ID, Name)Course(Course_ID, Title)
Relationship:
Student ENROLLS in Course
➡️ Both entities (Student and Course) are strong and independent.
<div class="infographic-strong-rel">
<style>
.infographic-strong-rel {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--error: #c0392b;
--error-soft: #fbe9e7;
--success: #2e7d32;
--success-soft: #e8f5e9;
--mono-font: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
background: var(--paper);
color: var(--ink);
max-width: 760px;
margin: 0 auto;
box-sizing: border-box;
}
.infographic-strong-rel[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--error: #e57373;
--error-soft: #3a2222;
--success: #66bb6a;
--success-soft: #1b3320;
}
.infographic-strong-rel *, .infographic-strong-rel *::before, .infographic-strong-rel *::after {
box-sizing: border-box;
}
.infographic-strong-rel h2 {
font-size: 1.4rem;
margin: 0 0 0.25rem;
letter-spacing: -0.01em;
}
.infographic-strong-rel .subtitle {
color: var(--ink-soft);
font-size: 0.92rem;
margin: 0 0 1.5rem;
max-width: 56ch;
}
.infographic-strong-rel .diagram-wrap {
background: var(--paper-alt);
border-radius: 14px;
padding: 1rem 0.5rem 0.5rem;
margin-bottom: 1rem;
}
.infographic-strong-rel svg {
width: 100%;
height: auto;
display: block;
}
.infographic-strong-rel .shape {
fill: var(--paper);
stroke: var(--ink);
stroke-width: 2;
transition: opacity 0.4s ease, filter 0.4s ease, stroke 0.3s ease;
}
.infographic-strong-rel .conn-line {
stroke: var(--ink-soft);
stroke-width: 1.8;
transition: opacity 0.4s ease, stroke 0.3s ease;
}
.infographic-strong-rel .node-label {
font-size: 14px;
font-weight: 700;
fill: var(--ink);
text-anchor: middle;
dominant-baseline: central;
pointer-events: none;
transition: opacity 0.4s ease;
}
.infographic-strong-rel .pk-label {
font-size: 10px;
font-family: var(--mono-font);
fill: var(--ink-soft);
text-anchor: middle;
pointer-events: none;
transition: opacity 0.4s ease;
}
.infographic-strong-rel .grp-deleted .shape { opacity: 0.3; filter: grayscale(1); }
.infographic-strong-rel .grp-deleted .node-label,
.infographic-strong-rel .grp-deleted .pk-label { opacity: 0.35; }
.infographic-strong-rel .grp-safe .shape { stroke: var(--success); stroke-width: 3; }
.infographic-strong-rel .grp-broken .shape { stroke: var(--error); opacity: 0.35; filter: grayscale(1); }
.infographic-strong-rel .grp-broken .node-label,
.infographic-strong-rel .grp-broken .pk-label { opacity: 0.35; }
.infographic-strong-rel .line-broken { opacity: 0.2; }
.infographic-strong-rel .shake { animation: rel-shake 0.4s; }
@keyframes rel-shake {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-4px); }
40% { transform: translateX(4px); }
60% { transform: translateX(-3px); }
80% { transform: translateX(2px); }
}
.infographic-strong-rel .status-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.6rem;
margin-bottom: 1rem;
}
@media (max-width: 520px) {
.infographic-strong-rel .status-grid { grid-template-columns: 1fr; }
}
.infographic-strong-rel .status-card {
border-radius: 10px;
border: 1px solid var(--line);
padding: 0.65rem 0.85rem;
font-size: 0.82rem;
}
.infographic-strong-rel .status-card .s-name {
font-weight: 700;
margin-bottom: 0.15rem;
}
.infographic-strong-rel .status-card.state-ok { color: var(--ink-soft); }
.infographic-strong-rel .status-card.state-safe { border-color: var(--success); color: var(--success); }
.infographic-strong-rel .status-card.state-gone { border-color: var(--error); color: var(--error); }
.infographic-strong-rel .controls {
display: flex;
justify-content: center;
gap: 0.6rem;
margin-bottom: 1.4rem;
flex-wrap: wrap;
}
.infographic-strong-rel .btn {
font: inherit;
font-size: 0.82rem;
font-weight: 600;
padding: 0.55rem 1rem;
border-radius: 999px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
cursor: pointer;
transition: background 0.15s, border-color 0.15s, color 0.15s, opacity 0.2s;
}
.infographic-strong-rel .btn:hover:not(:disabled) {
border-color: var(--accent);
color: var(--accent);
}
.infographic-strong-rel .btn.primary {
background: var(--error);
border-color: var(--error);
color: #fff;
}
.infographic-strong-rel .btn.primary:hover:not(:disabled) { opacity: 0.9; color: #fff; }
.infographic-strong-rel .btn:disabled { opacity: 0.4; cursor: not-allowed; }
.infographic-strong-rel .takeaway {
font-size: 0.88rem;
color: var(--ink-soft);
border-left: 3px solid var(--accent);
padding: 0.5rem 0 0.5rem 0.9rem;
transition: border-color 0.3s ease;
}
.infographic-strong-rel .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-strong-rel *, .infographic-strong-rel *::before, .infographic-strong-rel *::after {
animation-duration: 0.001ms !important;
transition-duration: 0.001ms !important;
}
}
</style>
<div class="diagram-wrap">
<svg viewBox="0 0 640 200" xmlns="http://www.w3.org/2000/svg">
<line class="conn-line" id="ln-student-enrolls" x1="200" y1="100" x2="265" y2="100"/>
<line class="conn-line" id="ln-enrolls-course" x1="375" y1="100" x2="440" y2="100"/>
<g id="grp-student">
<rect class="shape" x="60" y="70" width="140" height="60" rx="10"/>
<text class="node-label" x="130" y="93">Student</text>
<text class="pk-label" x="130" y="112">Student_ID (PK)</text>
</g>
<g id="grp-enrolls">
<polygon class="shape" points="320,60 375,100 320,140 265,100"/>
<text class="node-label" x="320" y="100" style="font-size:12px;">Enrolls</text>
</g>
<g id="grp-course">
<rect class="shape" x="440" y="70" width="140" height="60" rx="10"/>
<text class="node-label" x="510" y="93">Course</text>
<text class="pk-label" x="510" y="112">Course_ID (PK)</text>
</g>
</svg>
</div>
<div class="status-grid">
<div class="status-card state-ok" id="status-student">
<div class="s-name">Student</div>
<div id="status-student-text">alive · Student_ID intact</div>
</div>
<div class="status-card state-ok" id="status-course">
<div class="s-name">Course</div>
<div id="status-course-text">alive · Course_ID intact</div>
</div>
</div>
<div class="controls">
<button class="btn primary" id="btn-delete-student" type="button">🗑️ Delete Student</button>
<button class="btn primary" id="btn-delete-course" type="button">🗑️ Delete Course</button>
<button class="btn" id="btn-reset" type="button" disabled>↺ Reset</button>
</div>
<p class="takeaway" id="rel-takeaway"><strong>Both entities are strong.</strong> Student_ID and Course_ID each identify their entity on their own — neither one needs the other to make sense.</p>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-strong-rel')
|| document.querySelector('.infographic-strong-rel');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
var grpStudent = wrapper.querySelector('#grp-student');
var grpCourse = wrapper.querySelector('#grp-course');
var grpEnrolls = wrapper.querySelector('#grp-enrolls');
var lnStudentEnrolls = wrapper.querySelector('#ln-student-enrolls');
var lnEnrollsCourse = wrapper.querySelector('#ln-enrolls-course');
var statusStudent = wrapper.querySelector('#status-student');
var statusStudentText = wrapper.querySelector('#status-student-text');
var statusCourse = wrapper.querySelector('#status-course');
var statusCourseText = wrapper.querySelector('#status-course-text');
var takeaway = wrapper.querySelector('#rel-takeaway');
var btnDeleteStudent = wrapper.querySelector('#btn-delete-student');
var btnDeleteCourse = wrapper.querySelector('#btn-delete-course');
var btnReset = wrapper.querySelector('#btn-reset');
function shake(el) {
el.classList.remove('shake');
void el.getBoundingClientRect();
el.classList.add('shake');
}
function breakRelationship() {
grpEnrolls.classList.add('grp-broken');
lnStudentEnrolls.classList.add('line-broken');
lnEnrollsCourse.classList.add('line-broken');
}
function deleteStudent() {
grpStudent.classList.add('grp-deleted');
breakRelationship();
grpCourse.classList.add('grp-safe');
shake(grpEnrolls);
statusStudent.className = 'status-card state-gone';
statusStudentText.textContent = '❌ deleted';
statusCourse.className = 'status-card state-safe';
statusCourseText.textContent = '👍 alive · unaffected, Course_ID still valid';
takeaway.innerHTML = '<strong>Course is untouched.</strong> Only this specific Enrolls link disappears — Course_ID never depended on Student to mean something.';
btnDeleteStudent.disabled = true;
btnDeleteCourse.disabled = true;
btnReset.disabled = false;
}
function deleteCourse() {
grpCourse.classList.add('grp-deleted');
breakRelationship();
grpStudent.classList.add('grp-safe');
shake(grpEnrolls);
statusCourse.className = 'status-card state-gone';
statusCourseText.textContent = '❌ deleted';
statusStudent.className = 'status-card state-safe';
statusStudentText.textContent = '👍 alive · unaffected, Student_ID still valid';
takeaway.innerHTML = '<strong>Student is untouched.</strong> Only this specific Enrolls link disappears — Student_ID never depended on Course to mean something.';
btnDeleteStudent.disabled = true;
btnDeleteCourse.disabled = true;
btnReset.disabled = false;
}
function reset() {
grpStudent.classList.remove('grp-deleted', 'grp-safe');
grpCourse.classList.remove('grp-deleted', 'grp-safe');
grpEnrolls.classList.remove('grp-broken');
lnStudentEnrolls.classList.remove('line-broken');
lnEnrollsCourse.classList.remove('line-broken');
statusStudent.className = 'status-card state-ok';
statusStudentText.textContent = 'alive · Student_ID intact';
statusCourse.className = 'status-card state-ok';
statusCourseText.textContent = 'alive · Course_ID intact';
takeaway.innerHTML = '<strong>Both entities are strong.</strong> Student_ID and Course_ID each identify their entity on their own — neither one needs the other to make sense.';
btnDeleteStudent.disabled = false;
btnDeleteCourse.disabled = false;
btnReset.disabled = true;
}
btnDeleteStudent.addEventListener('click', deleteStudent);
btnDeleteCourse.addEventListener('click', deleteCourse);
btnReset.addEventListener('click', reset);
})();
</script>
</div>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});🟥 Weak Relationship
A Weak Relationship is formed between a weak entity and its owner entity.
The weak entity cannot be uniquely identified without a foreign key reference to the strong entity.
The weak entity does not have a primary key of its own
Total participation: Every instance of the weak entity must be related to a strong entity
Often includes partial keys (discriminators)
🔹 Example:
Entities:
Employee
(Emp_ID, Name, Department)→ ✅ Strong EntityDependent
(Name, Relationship, Emp_ID)→ ✅ Weak Entity
🧠 Explanation:
A Dependent (like a spouse or child) cannot exist meaningfully in the database without an Employee. It depends on the existence of the employee.
This is a classic example of a weak entity in an organization where employee records are linked to their dependents.
🗂️ ER Diagram:
Weak entity: Double rectangle
Weak relationship: Double diamond →
Belongs toTotal participation: Bold line from
DependenttoBelongs toComposite Key of Dependent:
(Name + Emp_ID)→ underlined
<div class="infographic-weak-rel">
<style>
.infographic-weak-rel {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--error: #c0392b;
--error-soft: #fbe9e7;
--success: #2e7d32;
--success-soft: #e8f5e9;
--mono-font: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
background: var(--paper);
color: var(--ink);
padding: 2rem 1.5rem 2.5rem;
max-width: 760px;
margin: 0 auto;
box-sizing: border-box;
}
.infographic-weak-rel[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--error: #e57373;
--error-soft: #3a2222;
--success: #66bb6a;
--success-soft: #1b3320;
}
.infographic-weak-rel *, .infographic-weak-rel *::before, .infographic-weak-rel *::after {
box-sizing: border-box;
}
.infographic-weak-rel h2 {
font-size: 1.4rem;
margin: 0 0 0.25rem;
letter-spacing: -0.01em;
}
.infographic-weak-rel .subtitle {
color: var(--ink-soft);
font-size: 0.92rem;
margin: 0 0 1.5rem;
max-width: 58ch;
}
.infographic-weak-rel .diagram-wrap {
background: var(--paper-alt);
border-radius: 14px;
padding: 1rem 0.5rem 0.5rem;
margin-bottom: 1rem;
}
.infographic-weak-rel svg {
width: 100%;
height: auto;
display: block;
}
.infographic-weak-rel .shape {
fill: var(--paper);
stroke: var(--ink);
stroke-width: 2;
transition: opacity 0.4s ease, filter 0.4s ease, stroke 0.3s ease;
}
.infographic-weak-rel .shape-inner {
fill: none;
stroke: var(--ink);
stroke-width: 1.6;
transition: opacity 0.4s ease, stroke 0.3s ease;
}
.infographic-weak-rel .conn-line {
stroke: var(--ink-soft);
stroke-width: 1.8;
transition: opacity 0.4s ease, stroke 0.3s ease;
}
.infographic-weak-rel .conn-line.total-part {
stroke-width: 2.2;
}
.infographic-weak-rel .node-label {
font-size: 14px;
font-weight: 700;
fill: var(--ink);
text-anchor: middle;
dominant-baseline: central;
pointer-events: none;
transition: opacity 0.4s ease;
}
.infographic-weak-rel .pk-label {
font-size: 10px;
font-family: var(--mono-font);
fill: var(--ink-soft);
text-anchor: middle;
pointer-events: none;
transition: opacity 0.4s ease;
}
.infographic-weak-rel .ck-label {
font-size: 10px;
font-family: var(--mono-font);
fill: var(--accent);
text-anchor: middle;
text-decoration: underline;
pointer-events: none;
transition: opacity 0.4s ease;
}
.infographic-weak-rel .kicker-text {
font-size: 9.5px;
letter-spacing: 0.04em;
fill: var(--ink-soft);
text-anchor: middle;
text-transform: uppercase;
pointer-events: none;
}
.infographic-weak-rel .grp-deleted .shape,
.infographic-weak-rel .grp-deleted .shape-inner { opacity: 0.3; filter: grayscale(1); }
.infographic-weak-rel .grp-deleted .node-label,
.infographic-weak-rel .grp-deleted .pk-label,
.infographic-weak-rel .grp-deleted .ck-label { opacity: 0.35; }
.infographic-weak-rel .grp-safe .shape { stroke: var(--success); stroke-width: 3; }
.infographic-weak-rel .grp-orphaned .shape,
.infographic-weak-rel .grp-orphaned .shape-inner { stroke: var(--error); }
.infographic-weak-rel .grp-broken .shape,
.infographic-weak-rel .grp-broken .shape-inner { stroke: var(--error); opacity: 0.35; filter: grayscale(1); }
.infographic-weak-rel .grp-broken .node-label { opacity: 0.35; }
.infographic-weak-rel .line-broken { opacity: 0.2; }
.infographic-weak-rel .shake { animation: wrel-shake 0.4s; }
@keyframes wrel-shake {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-4px); }
40% { transform: translateX(4px); }
60% { transform: translateX(-3px); }
80% { transform: translateX(2px); }
}
.infographic-weak-rel .status-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.6rem;
margin-bottom: 1rem;
}
@media (max-width: 520px) {
.infographic-weak-rel .status-grid { grid-template-columns: 1fr; }
}
.infographic-weak-rel .status-card {
border-radius: 10px;
border: 1px solid var(--line);
padding: 0.65rem 0.85rem;
font-size: 0.82rem;
}
.infographic-weak-rel .status-card .s-name { font-weight: 700; margin-bottom: 0.15rem; }
.infographic-weak-rel .status-card.state-ok { color: var(--ink-soft); }
.infographic-weak-rel .status-card.state-safe { border-color: var(--success); color: var(--success); }
.infographic-weak-rel .status-card.state-gone { border-color: var(--error); color: var(--error); }
.infographic-weak-rel .controls {
display: flex;
justify-content: center;
gap: 0.6rem;
margin-bottom: 1.4rem;
flex-wrap: wrap;
}
.infographic-weak-rel .btn {
font: inherit;
font-size: 0.82rem;
font-weight: 600;
padding: 0.55rem 1rem;
border-radius: 999px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
cursor: pointer;
transition: background 0.15s, border-color 0.15s, color 0.15s, opacity 0.2s;
}
.infographic-weak-rel .btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.infographic-weak-rel .btn.primary { background: var(--error); border-color: var(--error); color: #fff; }
.infographic-weak-rel .btn.primary:hover:not(:disabled) { opacity: 0.9; color: #fff; }
.infographic-weak-rel .btn:disabled { opacity: 0.4; cursor: not-allowed; }
.infographic-weak-rel .legend-note {
font-size: 0.76rem;
color: var(--ink-soft);
text-align: center;
margin: 0.4rem 0 1.1rem;
}
.infographic-weak-rel .takeaway {
font-size: 0.88rem;
color: var(--ink-soft);
border-left: 3px solid var(--accent);
padding: 0.5rem 0 0.5rem 0.9rem;
}
.infographic-weak-rel .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-weak-rel *, .infographic-weak-rel *::before, .infographic-weak-rel *::after {
animation-duration: 0.001ms !important;
transition-duration: 0.001ms !important;
}
}
</style>
<h2>🟥 Weak Relationship</h2>
<p class="subtitle">Dependent has no primary key of its own. Delete the owner and watch what a weak relationship actually costs.</p>
<div class="diagram-wrap">
<svg viewBox="0 0 640 210" xmlns="http://www.w3.org/2000/svg">
<line class="conn-line" id="ln-employee-belongs" x1="200" y1="100" x2="260" y2="100"/>
<line class="conn-line total-part" id="ln-belongs-dependent-a" x1="380" y1="97" x2="440" y2="97"/>
<line class="conn-line total-part" id="ln-belongs-dependent-b" x1="380" y1="103" x2="440" y2="103"/>
<g id="grp-employee">
<text class="kicker-text" x="130" y="55">Strong Entity</text>
<rect class="shape" x="60" y="70" width="140" height="60" rx="10"/>
<text class="node-label" x="130" y="93">Employee</text>
<text class="pk-label" x="130" y="112">Emp_ID (PK)</text>
</g>
<g id="grp-belongs">
<text class="kicker-text" x="320" y="45">Weak Relationship</text>
<polygon class="shape" points="320,58 380,100 320,142 260,100"/>
<polygon class="shape-inner" points="320,70 366,100 320,130 274,100"/>
<text class="node-label" x="320" y="100" style="font-size:11px;">Belongs to</text>
</g>
<g id="grp-dependent">
<text class="kicker-text" x="510" y="55">Weak Entity</text>
<rect class="shape" x="440" y="70" width="140" height="60" rx="10"/>
<rect class="shape-inner" x="448" y="78" width="124" height="44" rx="6"/>
<text class="node-label" x="510" y="93">Dependent</text>
<text class="ck-label" x="510" y="112">(Name + Emp_ID)</text>
</g>
</svg>
</div>
<p class="legend-note">Double rectangle = weak entity · Double diamond = weak relationship · Double line = total participation</p>
<div class="status-grid">
<div class="status-card state-ok" id="status-employee">
<div class="s-name">Employee</div>
<div id="status-employee-text">alive · Emp_ID intact</div>
</div>
<div class="status-card state-ok" id="status-dependent">
<div class="s-name">Dependent</div>
<div id="status-dependent-text">alive · linked to Employee via Emp_ID</div>
</div>
</div>
<div class="controls">
<button class="btn primary" id="btn-delete-employee" type="button">🗑️ Delete Employee</button>
<button class="btn primary" id="btn-delete-dependent" type="button">🗑️ Delete Dependent</button>
<button class="btn" id="btn-reset" type="button" disabled>↺ Reset</button>
</div>
<p class="takeaway" id="rel-takeaway"><strong>Total participation means no choice.</strong> Every Dependent must belong to some Employee — remove that Employee, and the Dependent has nothing left to attach to.</p>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-weak-rel')
|| document.querySelector('.infographic-weak-rel');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
var grpEmployee = wrapper.querySelector('#grp-employee');
var grpDependent = wrapper.querySelector('#grp-dependent');
var grpBelongs = wrapper.querySelector('#grp-belongs');
var lnEmployeeBelongs = wrapper.querySelector('#ln-employee-belongs');
var lnA = wrapper.querySelector('#ln-belongs-dependent-a');
var lnB = wrapper.querySelector('#ln-belongs-dependent-b');
var statusEmployee = wrapper.querySelector('#status-employee');
var statusEmployeeText = wrapper.querySelector('#status-employee-text');
var statusDependent = wrapper.querySelector('#status-dependent');
var statusDependentText = wrapper.querySelector('#status-dependent-text');
var takeaway = wrapper.querySelector('#rel-takeaway');
var btnDeleteEmployee = wrapper.querySelector('#btn-delete-employee');
var btnDeleteDependent = wrapper.querySelector('#btn-delete-dependent');
var btnReset = wrapper.querySelector('#btn-reset');
function shake(el) {
el.classList.remove('shake');
void el.getBoundingClientRect();
el.classList.add('shake');
}
function breakRelationship() {
grpBelongs.classList.add('grp-broken');
lnEmployeeBelongs.classList.add('line-broken');
lnA.classList.add('line-broken');
lnB.classList.add('line-broken');
}
function deleteEmployee() {
grpEmployee.classList.add('grp-deleted');
breakRelationship();
statusEmployee.className = 'status-card state-gone';
statusEmployeeText.textContent = '❌ deleted';
setTimeout(function () {
shake(grpDependent);
grpDependent.classList.add('grp-orphaned');
statusDependent.className = 'status-card state-gone';
statusDependentText.textContent = '⚠️ orphaned — no Employee left to belong to';
takeaway.innerHTML = '<strong>Dependent just broke.</strong> With no Employee and no primary key of its own, this record can no longer be identified at all.';
}, 500);
btnDeleteEmployee.disabled = true;
btnDeleteDependent.disabled = true;
btnReset.disabled = false;
}
function deleteDependentOnly() {
shake(grpDependent);
grpDependent.classList.add('grp-deleted');
breakRelationship();
statusDependent.className = 'status-card state-gone';
statusDependentText.textContent = '❌ deleted';
statusEmployee.className = 'status-card state-safe';
statusEmployeeText.textContent = '👍 alive · unaffected, Emp_ID still valid';
takeaway.innerHTML = '<strong>Employee is untouched.</strong> A strong entity never depends on its weak relationship partner — the dependency only runs one way.';
btnDeleteEmployee.disabled = true;
btnDeleteDependent.disabled = true;
btnReset.disabled = false;
}
function reset() {
grpEmployee.classList.remove('grp-deleted', 'grp-safe');
grpDependent.classList.remove('grp-deleted', 'grp-safe', 'grp-orphaned');
grpBelongs.classList.remove('grp-broken');
lnEmployeeBelongs.classList.remove('line-broken');
lnA.classList.remove('line-broken');
lnB.classList.remove('line-broken');
statusEmployee.className = 'status-card state-ok';
statusEmployeeText.textContent = 'alive · Emp_ID intact';
statusDependent.className = 'status-card state-ok';
statusDependentText.textContent = 'alive · linked to Employee via Emp_ID';
takeaway.innerHTML = '<strong>Total participation means no choice.</strong> Every Dependent must belong to some Employee — remove that Employee, and the Dependent has nothing left to attach to.';
btnDeleteEmployee.disabled = false;
btnDeleteDependent.disabled = false;
btnReset.disabled = true;
}
btnDeleteEmployee.addEventListener('click', deleteEmployee);
btnDeleteDependent.addEventListener('click', deleteDependentOnly);
btnReset.addEventListener('click', reset);
})();
</script>
</div>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});🧠 Summary Table:
Feature | 🔵 Strong Relationship | 🔴 Weak Relationship |
|---|---|---|
Entities involved | Strong entities | One weak + one strong entity |
Key dependency | Each entity has its own primary key | Weak entity depends on strong entity |
Representation | Single diamond 🔷 | Double diamond ⧫⧫ |
Entity shape | Rectangle 🟦 | Double rectangle ⬜⬜ |
Participation | Can be partial | Always total participation |