Every column has a type, and the type you pick shapes what the database will store, how much space it takes, and which bugs it quietly prevents. This lesson tours the type families you'll use most. The seed has one products table that puts each of them to work.
Take a look at what the seed defined:
SELECT column_name, data_type, numeric_precision, numeric_scale
FROM information_schema.columns
WHERE table_name = 'products'
ORDER BY ordinal_position;
Integers: smallint, integer, bigint
Three sizes of whole number. Use integer (a.k.a. int, 4 bytes, up to ~2.1 billion) as your default. Reach for bigint (8 bytes) when you might exceed that — row IDs on a big table, byte counts, anything that grows without bound. smallint (2 bytes) is a niche space optimization.
SELECT
1 AS an_int,
pg_typeof(1) AS its_type,
2147483647 AS int_max,
9223372036854775807 AS bigint_max;
pg_typeof(...) reports the type Postgres inferred — a handy way to check what you're actually getting.
Exact vs approximate numbers
This is the distinction that bites people. numeric (a.k.a. decimal) stores numbers exactly, to a precision you specify — numeric(10,2) is up to 10 digits with 2 after the decimal point. real and double precision are floating point: fast, compact, and approximate.
SELECT
0.1::numeric + 0.2::numeric AS exact,
0.1::real + 0.2::real AS approximate;
The float result isn't quite 0.3. That rounding error is fine for a weight or a sensor reading, and a disaster for money. Rule: money and anything that must add up uses numeric; measurements where a tiny error is acceptable can use real/. That's why the seed's is and is .