Course topics

By WebNest Studio Engineering Team

Database and SQL Tutorial

Tables, Rows, and Columns

A table is the basic structural unit of a relational database: it defines a fixed set of named, typed columns, and stores data as rows that each provide one value (or NULL) per column. Designing a table well — choosing the right columns and the right data type for each one — is one of the most consequential decisions in building a database-backed application.

Why it matters

A table definition is a promise about the data: which columns exist and what kind of value each may hold. Choosing the right type prevents invalid data, such as text in a price column, and affects storage and speed. A poor choice made at the start, such as storing dates as text, is painful to correct once the table is full.

Defining a Table's Structure

A table is created with CREATE TABLE, listing each column's name and data type. Once created, every row inserted into that table must conform to this structure: it must provide a value for every NOT NULL column, and every value must match (or be convertible to) its column's declared type.

Common SQL Data Types

Choosing an appropriate type for each column keeps data both valid and efficient to store and query.

  • INTEGER / BIGINT — whole numbers, commonly used for IDs and counts.
  • VARCHAR(n) / TEXT — variable-length text, with VARCHAR(n) capping the length.
  • DECIMAL(p, s) / NUMERIC(p, s) — exact fixed-precision numbers, essential for money.
  • DATE / TIMESTAMP — calendar dates, and dates combined with a time component.
  • BOOLEAN — true/false values (some databases emulate this with a small integer).

Rows as Records

Each row represents one complete record — one employee, one order, one product. A well-designed table keeps every row describing exactly one kind of "thing"; mixing unrelated kinds of records in a single table (for example, storing both customers and products in one generic table) breaks the relational model and makes queries and constraints far harder to write correctly.

Example

Defining a products table with appropriate data types, then inserting rows

SQL
CREATE TABLE products (
    id INTEGER PRIMARY KEY,
    name VARCHAR(120) NOT NULL,
    price DECIMAL(10, 2) NOT NULL,
    in_stock BOOLEAN DEFAULT TRUE,
    created_at DATE DEFAULT CURRENT_DATE
);

INSERT INTO products (id, name, price) VALUES
    (1, 'Wireless Mouse', 19.99),
    (2, 'Mechanical Keyboard', 79.50);

SELECT id, name, price FROM products;
Output
Returns 2 rows: (1, 'Wireless Mouse', 19.99), (2, 'Mechanical Keyboard', 79.50)

Common Mistakes

  • Using VARCHAR/TEXT for prices instead of DECIMAL/NUMERIC, which leads to rounding errors in floating-point arithmetic.
  • Choosing an unnecessarily large type (e.g., BIGINT for a small lookup table) or an unnecessarily restrictive one (e.g., VARCHAR(10) for names), causing wasted space or truncated data.
  • Cramming multiple unrelated entities (like customers and orders) into a single wide table instead of splitting them into separate, properly related tables.

Exercise

Create a products table with these columns: an integer primary key id; a name of up to 100 characters that is required; an integer price; a boolean in_stock; and a date added_on. Insert the two rows given in the comments, then select the name and price of the products that are in stock.

Expected output: name | price then Pen | 12

SQL · starter code
-- TODO: create the products table

-- TODO: insert (1, 'Pen', 12, TRUE, '2026-01-15') and (2, 'Bag', 450, FALSE, '2026-02-01')

-- TODO: name and price of the products that are in stock
Show hints
  • The types are INTEGER, VARCHAR(100), BOOLEAN and DATE.
  • Filter with WHERE in_stock = TRUE.
Show solution
SQL · solution
CREATE TABLE products (
  id INTEGER PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  price INTEGER,
  in_stock BOOLEAN,
  added_on DATE
);

INSERT INTO products (id, name, price, in_stock, added_on) VALUES
  (1, 'Pen', 12, TRUE, '2026-01-15'),
  (2, 'Bag', 450, FALSE, '2026-02-01');

SELECT name, price FROM products WHERE in_stock = TRUE;

Quick quiz

1. Which type should store an amount of money exactly?

  • A. DECIMAL (also called NUMERIC)
  • B. FLOAT
  • C. TEXT
  • D. BOOLEAN
Show answer

A. Floating-point types store approximations and produce rounding errors in money calculations.

2. What does VARCHAR(50) mean?

  • A. Exactly 50 characters, padded with spaces
  • B. A number up to 50
  • C. Text of up to 50 characters
  • D. 50 separate columns
Show answer

C. CHAR(50) is the fixed-length type that pads shorter values.

3. What does one row of a table represent?

  • A. A data type
  • B. A category of information
  • C. A rule on the data
  • D. One record: a single entity such as one customer
Show answer

D. Columns describe the attributes, and each row holds the values for one item.

Interview questions

What is the difference between CHAR and VARCHAR?

Show answer

CHAR(n) is fixed length: every value occupies n characters, and shorter values are padded with spaces. VARCHAR(n) is variable length: it stores only the characters given, up to a maximum of n. CHAR suits values that always have the same length, such as a two-letter country code; VARCHAR suits names, emails and most other text.

Why should dates not be stored as text?

Show answer

Text does not validate, so '2026-13-45' or 'tomorrow' would be accepted. Text sorts and compares as characters, which gives wrong results unless every value has exactly the same format. Date functions, such as adding a month or finding the difference between two dates, do not work on it, and indexes are less useful. A DATE or TIMESTAMP column avoids all of this.

Key Points to Remember

  • A table defines named, typed columns; every row must conform to that structure.
  • Picking the right data type (DECIMAL for money, DATE/TIMESTAMP for dates) prevents subtle bugs and wasted storage.
  • Each row should represent exactly one instance of one clearly defined entity.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs your SQL on SQLite in your browser. Standard SQL works; a few features that exist only in PostgreSQL or MySQL do not. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

These examples need a project environment on your computer, so they can be copied but not run here. Codelab runs Python, FastAPI backends with SQLite, plain Java 17 and HTML/CSS/JavaScript.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering