why there are multiple numeric types in Postgres SQL
PostgreSQL, and relational databases in general, use multiple numeric types instead of a single general "number" type like in JavaScript for reasons related to precision, storage efficiency, and performance.
| Type of Number | PostgreSQL Examples | Key Feature | Primary Use Case |
|---|---|---|---|
| Fixed-Size Integers | SMALLINT (2 bytes), INTEGER (4 bytes), BIGINT (8 bytes) | Store whole numbers (no fractional part). Offer a balance of range, speed, and minimal storage space. | Counters, primary keys, ID numbers, or any data that is strictly a whole number. |
| Fixed-Precision Decimals | NUMERIC / DECIMAL | Store numbers with an exact, user-defined precision and scale (e.g., 10 total digits, 2 after the decimal). Calculations are exact. | Monetary/financial data, or any calculation where exactness is critical and rounding must be avoided. |
| Floating-Point | REAL (4 bytes), DOUBLE PRECISION (8 bytes) | Store numbers with fractional parts using approximate storage. They offer a very wide range but can suffer from minor rounding errors during calculation. | Scientific data, less critical measurements, where speed is more important than absolute precision. |
Why Not Use Just One Number Type?
The difference comes down to the fundamental design goals of a robust database management system compared to a general-purpose scripting language like JavaScript.
1. Ensuring Data Integrity and Precision
The single Number type in JavaScript is an IEEE 754 double-precision 64-bit binary floating-point number. While great for general use, it has limitations:
- It cannot represent all decimal numbers exactly (e.g., $0.1 + 0.2 \ne 0.3$). This is unacceptable for financial or legal data where exactness is required.
- PostgreSQL's
NUMERIC/DECIMALtype is designed to solve this by storing numbers in a way that provides arbitrary precision and exact decimal calculation, which a standard floating-point type cannot guarantee.
2. Optimizing Storage and Performance
Databases are designed to manage vast amounts of data efficiently. Choosing the right data type helps minimize storage space and speed up processing:
- Smallest Size for the Range: If you know a number will never exceed 32,767 (like a small count), using a 2-byte
SMALLINTis far more efficient than allocating the 8 bytes required for aBIGINTor a floating-point number. Over millions of rows, this saves a significant amount of disk space and memory, leading to faster data retrieval and operations. - Fastest Calculation: Integer operations are generally the fastest for the computer's CPU, followed by floating-point (if hardware-accelerated). Operations on the arbitrary-precision
NUMERICtype are the slowest because they require more complex, custom software logic to handle the exact decimal math.
By offering multiple types, PostgreSQL allows you to choose the type that perfectly balances:
- Correctness (Precision): Using
NUMERICfor financial data. - Efficiency (Size): Using
SMALLINTorINTEGERfor small, whole-number IDs. - Speed (Performance): Using
INTEGERorDOUBLE PRECISIONwhere exactness is not the top priority.