you need a bit of country-code based metadata to convert back to strings, but the storage format is ultra compact and unambiguous.
you need a bit of country-code based metadata to convert back to strings, but the storage format is ultra compact and unambiguous.
Edited to add:
It does depend on what you are doing with the numbers. Focussing on the storage side is missing the point. It’s about the ambiguity. In general I’ve found that anything other than integers is a mistake.
For example, *555 is not a valid phone number. You can’t put it in a tel: URL and you can’t dial it or send a text to it. It will work only in limited situations. If you want to store an extension it should be a separate field.
Once you realise that phone numbers are functional, almost exactly like IP addresses, you realise that storing them as integers has benefits because that way you literally are unable to store useless data.
Once you get in the habit of using only e164 numbers, the phone number becomes usable in almost any context, and you can make functional assumptions about it.
As an aside, it’s much easier to create fast and small prefix indexes on integers, but that’s a different story…
> In Israel, certain advertising numbers start with a *.
> In New Zealand, non-urgent traffic incidents can be reported by calling *555 from a mobile phone.
"Surely we won't ever need it"
So that leaves you with just the 10 digits. Which can be easily stored in an integer, which can then be formatted reliably for humans according to the international numbering plan.
Like IP addresses, phone numbers are just numbers. You can fuck about all you like by adding funny letters and brackets and complicated parsers (just like you can add dots and colons to an IP address), OR you can just store them as normalised E164 numbers, which will work everywhere and for which there are clear formatting rules. Just like you can store an IP address as an IP address datatype in most databases.
Almost nobody wants to store the NZ time service or 911 or anything else in a large database. Nobody is dialling an extension number over the PSTN network - that's like trying to include the port number in an IP address and calling it ... an IP address. Such numbers should be stored somewhere else.
I discovered that the tel: URL supports local numbers with context. So the bigint scheme can't represent valid tel: URLs.
A generic contact identifier that you’re only going to show to other humans can of course be a string. People can put whatever they want in there. But it won’t be useful for automation or other kinds of processing.
If you’re going to actually use the number in any kind of automation, including tel: urls, it’s better as an integer because then you’re forced to process the incoming number properly before you put it in the database.
In terms of E164, You’re not ever going to store numbers like 911 in a database of phone numbers that you’ll plug into automations.
The whole point of E164 is to normalise the international numbering system. Why would you not use the international telecommunications standard for numbering, to store telephone numbers that are intended to be used to contact people?
It’s the same as storing an IP address as a string. Sure, you can do it, but why? The only possible outcome is that you will eventually store useless strings that aren’t actually valid.
Of course the tel: url scheme can support E164 numbers. I mean unless your app is limited to only a single geography, why would you even want it to be local only?
They're not integers, they're strings. Strings of digits it's true, but still strings.
For most phone numbers, you just need to round trip them. They will be presented in the same context. It is better to store ambiguous numbers as entered, along with context, and let human figure it out than mess up.
> For most phone numbers, you just need to round trip them
That would be a great entry in a book, "myths developers believe about phone numbers".