Skip to content

Beginner: asking questions · Databases and the relational model · topic 2 of 62 · 30 min

Tables, rows, columns and data types

Explanation

A table holds one kind of thing, each row is one item, and each column is one detail with a data type such as INTEGER, DECIMAL, VARCHAR, DATE or BOOLEAN. SQLite is relaxed about types: it stores dates as text like '2025-01-05' and booleans as 1 and 0, and typeof() tells you what was really stored.

Tables, rows and columns

A table holds one kind of thing: students, products, orders. A row (also called a record) is one item: one student, one product. A column (also called a field) is one detail that every row has, like name or price. The place where a row and a column meet is a cell, and it holds one value.

The list of tables, their columns and their types is called the schema. The schema is the plan; the rows are the data that follows the plan. In a spreadsheet anyone can type anything anywhere. In a database the schema decides what each column may hold.

Think of it like this: A table is like a printed attendance register. The column headings (roll no, name, date) are printed once at the top and never change. Each line you fill in is a row. You would not write a phone number in the "date" column, and a good register would not let you.

The common SQL data types

TypeHoldsExample value
INTEGER (INT, BIGINT)Whole numbers42, -7, 1450
DECIMAL(p, s) / NUMERICExact numbers with a fixed number of decimals, used for moneyDECIMAL(10, 2) holds 12345678.90
REAL / FLOAT / DOUBLEApproximate decimal numbers, used for measurements36.6, 0.75
VARCHAR(n) / TEXTText; VARCHAR(n) allows at most n characters'Pune', 'Asha Verma'
DATE / TIMESTAMPA calendar date / a date with a time'2025-01-05', '2025-01-05 14:30:00'
BOOLEANTrue or falseTRUE, FALSE

Why does money need DECIMAL? Because REAL numbers are stored in binary and cannot hold most decimal fractions exactly. Adding 0.1 and 0.2 as REAL numbers gives 0.30000000000000004. For one bill that looks harmless; across lakhs of transactions the errors add up. Banks store money as DECIMAL, or as whole paise in an INTEGER.

sql
SELECT 0.1 + 0.2;
Returns 0.30000000000000004, because 0.1 and 0.2 are approximate REAL values.

How SQLite is different: type affinity

PostgreSQL and MySQL check types strictly: put text into an INTEGER column and you get an error. SQLite, the engine on this site, is relaxed. Each column has a type affinity, which is a preferred type, not a strict rule. There are five affinities: TEXT, NUMERIC, INTEGER, REAL and BLOB (raw bytes). SQLite works out the affinity from the type name you write.

  • VARCHAR(50) gets TEXT affinity, and the 50 is ignored: SQLite happily stores a 200-character name.
  • DECIMAL(10, 2) and NUMERIC get NUMERIC affinity: 4500 is stored as an integer, 1250.75 as a real number.
  • There is no separate date type. Store dates as text in the form 'YYYY-MM-DD' (the ISO 8601 format), which sorts correctly and works with SQLite's date functions.
  • There is no separate boolean type. Store 1 for true and 0 for false. The words TRUE and FALSE are accepted and simply mean 1 and 0.
  • An INTEGER column turns the text '25' into the number 25, but keeps the text 'abc' as text instead of rejecting it.

typeof(): what was really stored

The function typeof() returns the storage class of a value: integer, real, text, blob or null. It is SQLite-only, and very handy for spotting numbers that were saved as text.

sql
CREATE TABLE patients (id INTEGER PRIMARY KEY, name VARCHAR(50) NOT NULL,
  admitted DATE, bill DECIMAL(10, 2), insured BOOLEAN);
INSERT INTO patients VALUES (1, 'Lata Rao', '2025-07-01', 4500, TRUE),
                            (2, 'Mohan Das', '2025-07-03', 1250.75, FALSE);
SELECT name, typeof(admitted), bill, typeof(bill), insured FROM patients;
-- Lata Rao  | text | 4500    | integer | 1
-- Mohan Das | text | 1250.75 | real    | 0
Dates are text, the bill is integer or real depending on the value, and TRUE/FALSE became 1/0.
Tip: Since SQLite 3.37 you can add the word STRICT after a CREATE TABLE. A STRICT table rejects wrong types, for example "cannot store TEXT value in INTEGER column". It allows only the types INT, INTEGER, REAL, TEXT, BLOB and ANY.

Common mistakes

  • Storing dates as '05/01/2025'. Text in that form sorts wrongly: '05/01/2025' comes before '12/12/2024'. Always use 'YYYY-MM-DD', which sorts in date order.
  • Storing numbers as text. As text, '9' is greater than '100', because text is compared letter by letter. Use INTEGER or DECIMAL for anything you calculate or sort by size.
  • Using REAL for money. Use DECIMAL in PostgreSQL and MySQL, or whole paise in an INTEGER.
  • Trusting VARCHAR(n) to limit length in SQLite. It does not. Add a CHECK rule (next topics) or check in the app.
  • Forgetting that a missing value is NULL, not 0 or an empty string. typeof(NULL) is null.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Tables, rows, columns and data types · 1/7

Tables, rows, columns, types

In this lesson we look inside a table: rows, columns and the type of each column.

Prefer a video by a teacher? Find free videos on “sql data types explained sqlite type affinity” on YouTube ↗

In real life: A hospital admissions table

A hospital records each admission: patient name, admission date, ward, bill amount and whether the patient has insurance. The bill is money, so it is DECIMAL in PostgreSQL; the date is a DATE; insurance is a BOOLEAN. Picking the right types lets the billing team add up bills exactly and the reception sort admissions by date without surprises.

sql
-- PostgreSQL version of the table
CREATE TABLE admissions (
  id        INTEGER PRIMARY KEY,
  patient   VARCHAR(100) NOT NULL,
  admitted  DATE NOT NULL,
  ward      VARCHAR(20),
  bill      DECIMAL(10, 2),
  insured   BOOLEAN DEFAULT FALSE
);
The same statement also runs in SQLite, which maps each type to an affinity.

Practice (0/3 done)

Task 1 · Code · SQL

Instead of every column, choose only two. From students, show the name and the marks of every student (columns: name, marks).

Task 2 · Code · SQL

Find out what SQLite really stored. From students, return three columns: name, marks, and typeof(marks). One student has no marks; see what typeof says for her.

Task 3 · Code · SQL

The database is empty. Write three statements: 1) CREATE TABLE trains with columns number (INTEGER PRIMARY KEY), name (VARCHAR(60) NOT NULL), departs (DATE) and fare (DECIMAL(8, 2)). 2) INSERT two rows: (12951, 'Mumbai Rajdhani', '2025-08-01', 3100.5) and (12627, 'Karnataka Express', '2025-08-02', 1900). 3) SELECT number, name, departs, fare, typeof(fare) FROM trains. The checker looks at your LAST statement.

Quick quiz

Question 1

1.Which type is best for a product price in PostgreSQL?

Question 2

2.How should you store the date 5 January 2025 in SQLite so it sorts correctly?

Question 3

3.In SQLite, what does typeof(NULL) return?

Question 4

4.A SQLite column is declared VARCHAR(3). What happens when you insert 'ABCDEFG'?

Question 5

5.Why does '9' > '100' come out true?

Read more (free)

Before this, learn

This topic builds on these. If something here feels new, open them first.

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Which type is best for a product price in PostgreSQL?

Answer: DECIMAL(10, 2)

DECIMAL stores money exactly; REAL is approximate.

How should you store the date 5 January 2025 in SQLite so it sorts correctly?

Answer: '2025-01-05'

The YYYY-MM-DD form sorts in date order and works with SQLite date functions.

In SQLite, what does typeof(NULL) return?

Answer: null

typeof returns one of integer, real, text, blob or null.

A SQLite column is declared VARCHAR(3). What happens when you insert 'ABCDEFG'?

Answer: All 7 characters are stored

SQLite gives VARCHAR TEXT affinity and ignores the length. PostgreSQL would reject it.

Why does '9' > '100' come out true?

Answer: Because text is compared character by character, and '9' comes after '1'

As text, the first characters are compared first. Store numbers in number columns.

In a students table, what is one row?Related

Answer: One student with all their details

A row is one item. A column is one detail that every row has.

From What is a database?

A column is left out of an INSERT and has no DEFAULT and no NOT NULL. What value does it get?Related

Answer: NULL

With no default, a missing column becomes NULL.

From INSERT

What is the safest way to store ₹1,234.50 in SQLite?Related

Answer: INTEGER 123450 (paise)

Whole paise in an integer are exact; format as rupees only for display.

From Data types, naming and good habits

How is the true/false pinned value stored in SQLite?Related

Answer: As INTEGER 1 or 0

SQLite has no real boolean type, so 1 means true and 0 means false.

From Designing the data model

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Databases and the relational model” before its exam: Keys and relationships, CREATE TABLE and constraints, The SQL language and your tools.
  2. Module 1 exam: Databases and the relational model · 15 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, SELECT: filtering and sorting. 62 topics left in the course before the final exam.

← Previous: What a database is