Data Types in SQL

Understanding SQL data types: numbers, strings, dates, booleans, and NULL values.

22 min read
Beginner

Introduction to SQL Data Types

Just like in Python where variables have types (int, str, float), SQL columns have data types that define what kind of data they can store. Choosing the right data type is crucial for:

  • Data integrity: Ensuring only valid data is stored
  • Storage efficiency: Using the appropriate amount of space
  • Query performance: Optimizing how data is indexed and searched

When you create a table, you specify a data type for each column. This tells the database exactly what kind of values that column can hold.

Numeric Data Types

Numeric types store numbers - both whole numbers (integers) and decimal numbers (floating-point).

Numeric Data Types
Type
Description
Range
Storage
Use Case
INTInteger (whole numbers)-2,147,483,648 to 2,147,483,6474 bytesIDs, counts, quantities
BIGINTLarge integers±9 quintillion8 bytesLarge IDs, timestamps
SMALLINTSmall integers-32,768 to 32,7672 bytesSmall counts, ages
DECIMAL(p,s)Exact decimalVaries by precisionVariesMoney, precise calculations
FLOATApproximate decimal~7 decimal digits precision4 bytesScientific measurements
DOUBLELarge approximate decimal~15 decimal digits precision8 bytesComplex calculations

INT vs BIGINT:

sql
CREATE TABLE products (
    product_id INT,              -- Regular ID (up to 2 billion)
    barcode BIGINT,              -- Large numbers (like UPC codes)
    stock_quantity SMALLINT      -- Small numbers (won't exceed 32k)
);

DECIMAL vs FLOAT:

DECIMAL(p, s) stores exact values - perfect for money!

  • p = precision (total digits)
  • s = scale (digits after decimal)
sql
CREATE TABLE financial (
    price DECIMAL(10,2),    -- $99,999,999.99 max, EXACT
    measurement FLOAT       -- Approximate, for science
);

INSERT INTO financial VALUES (19.99, 19.99);
SELECT * FROM financial;

Important: Never use FLOAT or DOUBLE for money! They're approximate and can cause rounding errors. Always use DECIMAL for financial data.

String Data Types

String types store text data - from single characters to large blocks of text.

String Data Types
Type
Description
Max Length
Storage
Use Case
CHAR(n)Fixed-length stringn charactersn bytesCountry codes, zip codes
VARCHAR(n)Variable-length stringn charactersLength + 1-2 bytesNames, emails, titles
TEXTLarge text~65,535 charactersLength + 2 bytesArticles, descriptions
MEDIUMTEXTVery large text~16 million charsLength + 3 bytesBooks, large documents
LONGTEXTHuge text~4 GBLength + 4 bytesExtremely large content

CHAR vs VARCHAR:

  • CHAR(n): Always uses n characters of space (padded with spaces)
  • VARCHAR(n): Uses only the space needed (up to n characters)
sql
CREATE TABLE users (
    country_code CHAR(2),          -- Always 2 chars: 'US', 'UK'
    username VARCHAR(50),           -- Up to 50 chars
    bio TEXT                        -- Large description
);

INSERT INTO users VALUES ('US', 'alice', 'Software engineer who loves databases');
SELECT * FROM users;

Best Practice: Use VARCHAR for most text fields. Only use CHAR when the length is always the same (like country codes or zip codes).

Date and Time Data Types

Date and time types store temporal data - crucial for tracking when things happened.

Date/Time Data Types
Type
Description
Format
Range
Use Case
DATEDate onlyYYYY-MM-DD1000-01-01 to 9999-12-31Birthdays, deadlines
TIMETime onlyHH:MM:SS-838:59:59 to 838:59:59Business hours, duration
DATETIMEDate and timeYYYY-MM-DD HH:MM:SS1000-01-01 to 9999-12-31Event timestamps
TIMESTAMPAuto-updating timestampYYYY-MM-DD HH:MM:SS1970-01-01 to 2038-01-19Created/updated times
YEARYear onlyYYYY1901 to 2155Birth year, fiscal year
sql
CREATE TABLE events (
    event_id INT PRIMARY KEY,
    event_name VARCHAR(100),
    event_date DATE,                    -- Just the date
    event_time TIME,                    -- Just the time
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  -- Auto-timestamp
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

INSERT INTO events (event_id, event_name, event_date, event_time)
VALUES (1, 'Team Meeting', '2024-06-15', '14:30:00');

SELECT * FROM events;

DATETIME vs TIMESTAMP:

  • DATETIME: Stores the exact date/time you specify
  • TIMESTAMP: Can auto-update to current time, but limited to year 2038

Tip: Use TIMESTAMP with DEFAULT CURRENT_TIMESTAMP for "created_at" columns. It automatically records when the row was inserted!

Boolean Data Type

Boolean types store TRUE or FALSE values.

Stores logical true/false values. In MySQL, BOOLEAN is actually stored as TINYINT(1) where 0 = FALSE and 1 = TRUE.

sql
CREATE TABLE products (
    product_id INT PRIMARY KEY,
    product_name VARCHAR(100),
    in_stock BOOLEAN,           -- TRUE or FALSE
    is_featured BOOL,           -- Same as BOOLEAN
    is_on_sale TINYINT(1)       -- 0 or 1
);

INSERT INTO products VALUES
    (1, 'Laptop', TRUE, FALSE, 1),
    (2, 'Mouse', 1, 0, FALSE);  -- You can use TRUE/FALSE or 1/0

SELECT * FROM products;

You can query boolean columns naturally:

sql
SELECT product_name, in_stock
FROM products
WHERE in_stock = TRUE;

NULL Values

NULL is a special value that represents "no value" or "unknown". It's different from zero or an empty string!

NULL means the absence of a value. It's not zero, not an empty string, and not false - it's "unknown" or "not applicable."

sql
CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,     -- Cannot be NULL
    email VARCHAR(100),              -- Can be NULL
    salary DECIMAL(10,2) NOT NULL,   -- Cannot be NULL
    manager_id INT                   -- Can be NULL (CEO has no manager)
);

INSERT INTO employees (id, name, email, salary, manager_id)
VALUES
    (1, 'Alice', 'alice@company.com', 75000, NULL),  -- No manager (CEO)
    (2, 'Bob', NULL, 65000, 1);                      -- No email provided

SELECT * FROM employees;

Important: NULL is not equal to anything, not even NULL! Use IS NULL or IS NOT NULL to check for NULL values, not = NULL.

Choosing the Right Data Type

Here's a practical guide for choosing data types:

Data Type Selection Guide
If you're storing...
Use this type
Example
User IDs, Order IDsINT or BIGINT`user_id INT PRIMARY KEY`
Names, TitlesVARCHAR(n)`name VARCHAR(100)`
Email addressesVARCHAR(255)`email VARCHAR(255)`
Prices, MoneyDECIMAL(10,2)`price DECIMAL(10,2)`
Product descriptionsTEXT`description TEXT`
Birth datesDATE`birth_date DATE`
Login timestampsTIMESTAMP`last_login TIMESTAMP`
Account statusBOOLEAN`is_active BOOLEAN`
Phone numbersVARCHAR(20)`phone VARCHAR(20)`
Zip/Postal codesVARCHAR(10)`zip_code VARCHAR(10)`
Country codesCHAR(2)`country CHAR(2)`

Complete Example

Let's create a realistic table with various data types:

sql
CREATE TABLE customers (
    -- Primary key
    customer_id INT PRIMARY KEY AUTO_INCREMENT,

    -- String types
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    phone VARCHAR(20),

    -- Numeric types
    age SMALLINT,
    account_balance DECIMAL(12,2) DEFAULT 0.00,

    -- Boolean types
    is_active BOOLEAN DEFAULT TRUE,
    email_verified BOOLEAN DEFAULT FALSE,

    -- Date/Time types
    birth_date DATE,
    registered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_login TIMESTAMP NULL,

    -- Text types
    address TEXT,
    notes TEXT
);
sql
INSERT INTO customers
    (first_name, last_name, email, phone, age, birth_date)
VALUES
    ('Alice', 'Johnson', 'alice@email.com', '555-1234', 30, '1994-03-15'),
    ('Bob', 'Smith', 'bob@email.com', NULL, 28, '1996-07-22');

SELECT customer_id, first_name, last_name, email, age, is_active
FROM customers;

Common Mistakes to Avoid

Don't make these mistakes:

  1. Using VARCHAR without a length: Always specify VARCHAR(100), not just VARCHAR
  2. Using FLOAT for money: Use DECIMAL(10,2) instead
  3. Storing phone numbers as INT: Use VARCHAR(20) to preserve formatting and leading zeros
  4. Forgetting NOT NULL: Add NOT NULL to required fields
  5. Using huge VARCHAR sizes: VARCHAR(1000) when you only need 50 wastes resources