Appearance
Mental model
A table is basically a typed array of objects. A row is one object. A column is a field. That's the whole plot twist.
Tables ≈ collections
In JS you might hold contacts like this:
ts
const contacts = [
{ id: 1, name: 'Ada Lovelace', email: 'ada@example.com', companyId: 10 },
{ id: 2, name: 'Grace Hopper', email: 'grace@example.com', companyId: 10 },
]In SQL that collection is a table. Each object is a row. Each property is a column.
sql
-- conceptual shape
-- contacts(id, name, email, company_id)As you can see, it's not magic. Same data, stricter shape, lives on disk (or in a server DB).
Schema vs "just objects"
In TypeScript you might write:
ts
type Contact = {
id: number
name: string
email: string
companyId: number | null
}SQL's version is the table definition:
sql
CREATE TABLE contacts (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL,
company_id INTEGER
);Comments for the code above:
PRIMARY KEY- unique row identity (like your Reactkey, but enforced)NOT NULL- required fieldcompany_idcan be null here - contact without a company is allowed
The schema is the contract. The database will refuse rows that break it (depending on constraints - we'll add more later).
Rows are not nested by default
Here's the FE trap.
In JSON APIs we love nesting:
json
{
"id": 1,
"name": "Ada Lovelace",
"company": { "id": 10, "name": "Analytical Engines Inc" }
}In the database, that's usually two tables linked by an id:
text
companies: id=10, name=Analytical Engines Inc
contacts: id=1, name=Ada, company_id=10The nest happens at query time with a JOIN (or in the API/ORM layer). Flat storage, nested presentation.
Query = ask a question
| FE vibe | SQL vibe |
|---|---|
contacts.filter(c => c.companyId === 10) | WHERE company_id = 10 |
contacts.slice(0, 20) | LIMIT 20 |
contacts.sort((a,b) => a.name.localeCompare(b.name)) | ORDER BY name |
contacts.map(c => c.email) | SELECT email FROM contacts |
nested company include | JOIN companies … |
We'll go through each of those for real in the next chapters.
One more thing: set-based thinking
JS often loops row by row. SQL thinks in sets - "give me all rows matching X, then sort them, then take 20".
That's why SQL can feel weird at first if you're used to for loops. Lean into it. The database is really good at set operations.
Next: SELECT basics.