top of page

Data Saving Strategy for Numbers

  • Mar 29
  • 4 min read
Technologist working on laptop

Hey kids! Let's chat about data storage!


When we save data to a database, we need to think carefully about what type of field we're saving it into. The data type you choose determines how the database stores, reads, and handles that value .... picking the wrong one can corrupt your data in ways that are really hard to debug later.


One of the most common beginner mistakes? Storing zip codes as numbers.


view of person's hands and laptop with image of data presentation

Saving an address - the wrong way


Let's say you're building a table to store customer mailing addresses. You might set it up like this:


-- ❌ WRONG: Do NOT do this
CREATE TABLE addresses (
    id        INT PRIMARY KEY,
    street    VARCHAR(100),
    city      VARCHAR(50),
    state     CHAR(2),
    zip       INT        -- This is the problem!
)

This seems reasonable at first - zip codes look like numbers, after all. But storing zip as a number is a trap.



Here's what happens when you insert data:


-- ❌ WRONG: Inserting with an INT zip column
INSERT INTO addresses (id, street, city, state, zip)
VALUES (1, '10 Main St', 'Blandford', 'MA', 01234);

-- What actually gets stored:
-- zip = 1234   <-- leading zero is GONE. Silent data loss!

You get ghosted. The database just drops that zero and doesn't tell you. You won't notice until someone's package ends up in the wrong state, or your front end address validation fails or stops a user from entering their data. Unless you set the number length to be 5 by using DECIMAL(5, 0), but let's face it - that is rarely done irl.


microphones in front of unknown person


The fix: save zip codes as VARCHAR

-- ✅ CORRECT: Do this instead
CREATE TABLE addresses (
    id        INT PRIMARY KEY,
    street    VARCHAR(100),
    city      VARCHAR(50),
    state     CHAR(2),
    zip       VARCHAR(10)   -- Handles 5-digit AND ZIP+4 formats
)

Using VARCHAR(10) covers both the standard 5-digit format (01234) and the extended ZIP+4 format (01234-5678)


Now when you insert that same zip code:

-- ✅ CORRECT: Inserting with a VARCHAR zip column
INSERT INTO addresses (id, street, city, state, zip)
VALUES (1, '10 Main St', 'Blandford', 'MA', '01234');
--                                            ^^^^^^
--                                   Quoted as a string!

-- What actually gets stored:
-- zip = '01234'   <-- Leading zero preserved, exactly as entered ✅


Notice the zip code is now wrapped in quotes because it's a string, not a number.


Comparison of Int vs Varchar results:

-- ❌ INT column         | ✅ VARCHAR column
-- --------------------- | ---------------------
-- INSERT: 01234         | INSERT: '01234'
-- STORED: 1234          | STORED: '01234'
-- RETRIEVED: 1234       | RETRIEVED: '01234'
--  (boo!)               |  (yay!)


woman posing with rotary phone handset


Phone numbers are also interesting, based on what you're willing to allow to be stored. Do you want the numbers only, just the base 10 or the country code too? What if someone pastes the + sign with it? Let's chat about that .....


Phone numbers in particular are another field that look like numbers, but really should not be stored as one, for your own sanity down the line. Let's look at why.

-- ❌ WRONG: Phone number as a numeric type
CREATE TABLE contacts (
    id           INT PRIMARY KEY,
    name         VARCHAR(100),
    phone        BIGINT    -- Please no
);

Even setting aside the leading zero problem, BIGINT can't store a phone number the way a real user would enter it. Here's everything that breaks:

-- ❌ All of these get mangled or fail entirely with a numeric column:

-- Leading zero stripped (common in UK numbers):
-- INSERT: 07911123456  →  STORED: 7911123456  

-- Plus sign for international format can't be stored as a number:
-- INSERT: +14155552671  →  ERROR or data loss

-- Country code with formatting:
-- INSERT: +1-415-555-2671  →  ERROR due to dashes 

-- Common US formatted style:
-- INSERT: (415) 555-2671  →  ERROR due to parentheses

The fix is the same as with zip codes — use a string:

-- ✅ CORRECT: Phone number as VARCHAR
CREATE TABLE contacts (
    id           INT PRIMARY KEY,
    name         VARCHAR(100),
    phone        VARCHAR(20)   -- Handles international formats, symbols, spaces
);

VARCHAR(20) gives you plenty of room for international numbers in any format your users might enter:

-- ✅ All of these store perfectly as VARCHAR:
INSERT INTO contacts (id, name, phone) VALUES (1, 'Alex',  '07918675309')
INSERT INTO contacts (id, name, phone) VALUES (2, 'Sam',   '+14155552671')
INSERT INTO contacts (id, name, phone) VALUES (3, 'Jules', '+1-415-555-2671')
INSERT INTO contacts (id, name, phone) VALUES (4, 'Morgan','(415) 867-5309')


One extra tip here .... if your app needs to support international users, you may want to look into always storing phone numbers in E.164 format (the +14155552671 style). It's a universal standard that strips all formatting down to country code + number, which makes it much easier to validate, search, and pass to services like SMS providers. There are a bunch of 'copyable' functions in places like StackOverflow in every language that you can reuse, so just do a search with the language you need the code in, search for 'international phone number regex', or use the library https://github.com/google/libphonenumber.


The Golden Rule 🏆


A good rule of thumb: if you're never going to do math on a value, it probably shouldn't be a number type. 


You wouldn't add two zip codes together, or calculate the average of a set of phone numbers. These are identifiers, not quantities. Identifiers belong in string fields.


The same logic applies to other fields that look numeric, but aren't:

-- ❌ All of these should probably not be INT/numeric types:
phone_number   INT      -- 0800123456 becomes 800123456
ssn            INT      -- 012-34-5678 becomes unusable
order_id       INT      -- 00892 becomes 892
product_sku    INT      -- 007ABC can't be stored

-- ✅ These should all be strings:
phone_number   VARCHAR(15)
ssn            VARCHAR(11)   -- also: please hash this, its PII
order_id       VARCHAR(20)
product_sku    VARCHAR(50)

When in doubt, ask yourself: does the leading zero matter? Does the format matter? If yes - make it a string.


Stay safe out there, happy coding, and keep your data in good shape!! Until next time ....


gif



Comments


bottom of page