You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<p>CSV files have no atomicity, no query language, no concurrent access control, and no recovery. Fine for scripts; catastrophic for production data.</p>
149
160
</div>
150
161
<divclass="antipattern">
151
-
<h4>⚠ Ignoring normalization from day one</h4>
162
+
<h4>Ignoring normalization from day one</h4>
152
163
<p>Denormalized schemas feel easy initially but create update anomalies, data redundancy, and painful migrations as the application grows.</p>
153
164
</div>
154
165
<divclass="antipattern">
155
-
<h4>⚠ Treating the DBMS as a dumb storage layer</h4>
166
+
<h4>Treating the DBMS as a dumb storage layer</h4>
156
167
<p>Not using constraints (FK, NOT NULL, CHECK) shifts validation to application code — the worst of both worlds and much harder to enforce consistently.</p>
<p>A relation is a set of tuples (rows), all sharing the same schema (ordered list of attribute names and domains). Order of tuples is undefined — it's a set, not a list.</p>
45
45
</div>
46
46
<divclass="mini-card">
47
-
<divclass="mini-card-icon">🔑</div>
47
+
<divclass="mini-card-icon"></div>
48
48
<h4>Keys</h4>
49
49
<p>Superkey → minimal superkey = Candidate Key → chosen CK = Primary Key. Foreign Keys enforce referential integrity between relations.</p>
50
50
</div>
51
51
<divclass="mini-card">
52
-
<divclass="mini-card-icon">🔗</div>
52
+
<divclass="mini-card-icon"></div>
53
53
<h4>Referential Integrity</h4>
54
54
<p>A FK value must either be NULL or match a PK in the referenced table. ON DELETE CASCADE / SET NULL / RESTRICT control what happens when the parent row is deleted.</p>
55
55
</div>
56
56
<divclass="mini-card">
57
-
<divclass="mini-card-icon">🧮</div>
57
+
<divclass="mini-card-icon"></div>
58
58
<h4>Relational Algebra</h4>
59
59
<p>Six fundamental operations: σ (select rows), π (project columns), ⋈ (join), ∪ (union), − (difference), × (Cartesian product). All SQL compiles down to these.</p>
<li><strong>Relation</strong> = table. <strong>Tuple</strong> = row. <strong>Attribute</strong> = column. All values are atomic (1NF).</li>
116
+
<li><strong>Primary key</strong> uniquely identifies a tuple. <strong>Foreign key</strong> references a primary key in another relation.</li>
117
+
<li><strong>INNER JOIN</strong> returns only matching rows. <strong>LEFT JOIN</strong> keeps all rows from the left, NULLs on no match.</li>
118
+
<li><strong>Relational algebra</strong>: selection (sigma), projection (pi), join, union, difference — the theoretical basis for SQL.</li>
119
+
<li>Candidate keys, superkeys, and functional dependencies underpin normalization theory.</li>
120
+
</ul>
121
+
</div>
122
+
112
123
<!-- Demo -->
113
124
<divclass="section-label">Interactive Demo</div>
114
125
<h2class="section-title">JOIN Visualizer</h2>
115
126
<pclass="section-desc">Select a join type to see which rows match between the employees and departments tables. Matching rows animate into the result.</p>
@@ -135,15 +146,15 @@ <h4>Key Insight: INNER vs OUTER Joins</h4>
135
146
<divclass="section-label">Anti-patterns</div>
136
147
<divclass="antipatterns">
137
148
<divclass="antipattern">
138
-
<h4>⚠ Choosing the wrong join type</h4>
149
+
<h4>Choosing the wrong join type</h4>
139
150
<p>Using INNER JOIN when you need LEFT JOIN silently drops rows. Always verify expected result cardinality. A missing row in the result is often worse than an error.</p>
<p>Storing FK values without declaring FOREIGN KEY lets orphaned rows accumulate — child rows pointing to deleted parents. This causes silent data corruption that's expensive to fix later.</p>
144
155
</div>
145
156
<divclass="antipattern">
146
-
<h4>⚠ Using natural joins in production queries</h4>
157
+
<h4>Using natural joins in production queries</h4>
147
158
<p>NATURAL JOIN matches on ALL common column names. Adding a column to a table can silently change join semantics. Always use explicit ON conditions.</p>
148
159
</div>
149
160
</div>
@@ -212,7 +223,7 @@ <h4>⚠ Using natural joins in production queries</h4>
212
223
<divclass="section-label">Further Reading</div>
213
224
<divclass="reading-links">
214
225
<aclass="reading-link" href="https://www.cs.cmu.edu/~christos/COURSES/826.S03/HANDOUTS/codd72.pdf" target="_blank">📄 Codd's Original 1970 Paper</a>
<p>Logical execution order: FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT. NOT the textual order you write it.</p>
44
44
</div>
45
45
<divclass="mini-card">
46
-
<divclass="mini-card-icon">🪟</div>
46
+
<divclass="mini-card-icon"></div>
47
47
<h4>Window Functions</h4>
48
48
<p>OVER(PARTITION BY … ORDER BY …) — aggregate over a sliding window without collapsing rows. ROW_NUMBER, RANK, LAG, LEAD, SUM OVER.</p>
49
49
</div>
50
50
<divclass="mini-card">
51
-
<divclass="mini-card-icon">📎</div>
51
+
<divclass="mini-card-icon"></div>
52
52
<h4>CTEs (WITH clause)</h4>
53
53
<p>Named subqueries defined before the main query. Improve readability, enable recursion (WITH RECURSIVE for hierarchies/graphs), and can be referenced multiple times.</p>
54
54
</div>
55
55
<divclass="mini-card">
56
-
<divclass="mini-card-icon">📊</div>
56
+
<divclass="mini-card-icon"></div>
57
57
<h4>EXPLAIN / EXPLAIN ANALYZE</h4>
58
58
<p>Shows the execution plan: node types (SeqScan, IndexScan, HashJoin), estimated vs actual rows, cost estimates. Essential for performance debugging.</p>
<p>Fetches all columns including BLOBs and unused fields. Breaks when columns are added/removed. Always list explicit columns — the optimizer can use covering indexes only if it knows which columns you need.</p>
125
136
</div>
126
137
<divclass="antipattern">
127
-
<h4>⚠ The N+1 query problem</h4>
138
+
<h4>The N+1 query problem</h4>
128
139
<p>Fetching a list of N rows then running a query per row in application code. Replace with a single JOIN or a batch IN clause. N+1 is almost always the #1 performance issue in ORMs.</p>
129
140
</div>
130
141
<divclass="antipattern">
131
-
<h4>⚠ Using OFFSET for pagination on large tables</h4>
142
+
<h4>Using OFFSET for pagination on large tables</h4>
132
143
<p>OFFSET N scans and discards N rows every time. For page 1000 with 20 rows/page you discard 20,000 rows. Use keyset pagination: WHERE id > last_seen_id ORDER BY id LIMIT 20.</p>
133
144
</div>
134
145
<divclass="antipattern">
135
-
<h4>⚠ Implicit type conversions in WHERE</h4>
146
+
<h4>Implicit type conversions in WHERE</h4>
136
147
<p>WHERE user_id = '123' when user_id is INT causes a type cast on every row, disabling index usage. Match parameter types to column types exactly.</p>
137
148
</div>
138
149
</div>
@@ -200,9 +211,9 @@ <h4>⚠ Implicit type conversions in WHERE</h4>
0 commit comments