Learn SQL and Relational Database Design with MySQL
Model facts and relationships
A relational database stores information in tables whose rows represent records and whose columns represent attributes. Primary keys uniquely identify records. Foreign keys express relationships and help prevent references to records that do not exist. Before writing queries, identify the entities in the problem and the relationships between them.
Normalization is a way to reduce unnecessary duplication and update anomalies. For example, store customer details once and connect their orders through a key rather than repeating their address in every order row. The right design depends on how the application reads and changes data, but integrity rules should be explicit.
Query with SQL
SELECT statements retrieve data. WHERE filters rows, ORDER BY controls output order and GROUP BY supports aggregation. Joins combine related tables; an inner join returns matching records, while a left join can preserve rows from the first table when no related row exists. Use aliases and clear formatting to make queries easier to review.
Parameterized queries should be used for user-supplied values. Building SQL by concatenating untrusted input can create injection vulnerabilities. Framework data-access libraries help manage parameters, but developers still need to understand query behavior and validate their data boundaries.
Transactions and correctness
A transaction groups related database operations so they succeed or fail together. This is important when a workflow changes more than one record—for example, creating an order and updating inventory. Constraints provide another line of defense by rejecting invalid states even if an application-level check is missed.
Indexes can speed up frequent lookups, but they add storage and write costs. Start from a correct schema and inspect query plans when performance becomes a measured concern. Avoid adding indexes without understanding which queries they support.
Prepare for Java persistence
Spring Data JPA can map Java entities to relational tables and generate common repository operations. It does not remove the need to understand SQL, relationships or transaction boundaries. Use a real database in integration checks and verify that application behavior matches the intended schema and constraints.