5

In MySQL, I built a table using the following code:

BUILD TABLE user
(
    userName char(25) NOT NULL PRIMARY KEY,
    firstName char(25) NOT NULL,
    lastName char(25) NOT NULL,
    userEmail char(25) NOT NULL,
    userPhone int(10) NOT NULL,
);

And suppose I make the following command:

INSERT INTO `user`(`userName`, `firstName`, `lastName`, `userEmail`, `userPhone`) 
VALUES ("JDoe","John","Doe","jdoe@nothing.net", 9725550145)

MySQL runs the command without an issue, and puts the information in the table. However, when I retrieve the information for said John Doe, his phone number comes up as 2147483647.

In a number of the entries, I sort of noticed that if the first number of their area code is greater than 2, then they get that same number. What did I do wrong, and how can I fix this so that everyone has their respective phone number and not this seemingly random value that MySQL assigns them?

Thank you kindly.

JCMcRae
  • 245
  • 1
  • 5
  • 11
  • 7
    Don't. Phone numbers are not integers. For instance, my phone number is 0612345678. The 0 is quite significant, but storing it in an integer field would cause the loss of that information. – GolezTrol Nov 27 '15 at 19:22
  • 3
    Store the phone number as a string not an integer. A phone number may look like a number, but you don't want to do numeric transformations on it. – Gordon Linoff Nov 27 '15 at 19:22
  • @GordonLinoff Thanks, but it's not *really* my phone number, although mine starts with 06.. – GolezTrol Nov 27 '15 at 19:23
  • 2
    Personally, I would (and do), store the phone number as it was provides, and store it formatted to my own liking in a separate column. That way, I have the best of both. – GolezTrol Nov 27 '15 at 19:32
  • 1
    This might be a duplicate of https://stackoverflow.com/questions/23637057/why-is-it-best-to-store-a-telephone-number-as-a-string-vs-integer – Nico Haase Apr 25 '23 at 12:39
  • 1
    Or this one https://stackoverflow.com/questions/3483156/whats-the-right-way-to-represent-phone-numbers – Nico Haase Apr 25 '23 at 12:39

3 Answers3

12

Don't do that, phone numbers are not integers for very good reasons :

  • leading zeroes : 0199857514
  • country codes : +34199857514
  • special commands : #992,514
  • sip phones : sip:01199857514@stackoverflow.net

If you're going to store your phone numbers as integers, you are going to have major limitations and problems later.

To answer your question: You can't store a phone number as an integer, you must use a string.

Guillaume F.
  • 5,905
  • 2
  • 31
  • 59
  • While that is true, it was already addressed in comments, where it belongs, since it doesn't answer the question. – GolezTrol Nov 27 '15 at 19:31
  • It's impossible to store a phone number as an integer. The question is irrelevant. – Guillaume F. Nov 27 '15 at 19:33
  • 2
    I agree with @GuillaumeF. we are here to solve problems not only to answer question. So his answer is way better than my one. – Jorge Campos Nov 30 '15 at 11:33
  • He asks, "how" which suggests of a method, and then he specifically said ```how can I fix this so that everyone has their respective phone number and not this seemingly random value that MySQL assigns them?```, @guillaume F. then just explains what he did wrong, but never answers the "how", so how? – Eduardo Mar 23 '21 at 17:52
  • @Eduardo: There is now "how", it is not possible without destroying information, which would be unacceptable. – Guillaume F. Mar 23 '21 at 21:07
  • @GuillaumeF. In regards to answering, that just covers half of the issue by the OP because you can still use a string, I mean I stored it as a string, hopefully I don't need to do anything else with that column/value. – Eduardo Mar 23 '21 at 22:00
  • 1
    @Eduardo : Right, if you want, I though that was obvious, but I added "you must use a string." to the answer. – Guillaume F. Mar 23 '21 at 22:31
  • Phone numbers *should* be in numbers. Leading zeroes are part of your local call prefix, not the number; they aren't present from all call points, and can be predicted. Country codes do not have a plus; that's just how Europeans write them. There is no plus in phone numbers. Special commands are not part of a phone number. Sip addresses are not phone numbers. Why whould these be numbers? Because you want data normalcy. You shouldn't be able to write the same number multiple ways. Uniqueness and FKs matter. String comparisons are problematic for speed and correctness. Collations. Etc. – John Haugeland Apr 25 '23 at 12:05
  • @JohnHaugeland : Look at E.164 - The international public telecommunication numbering plan ; then RFC 3966 for how to declare phone number URIs. – Guillaume F. Apr 25 '23 at 15:07
6

Change your column userPhone int(10) NOT NULL to userPhone BIGINT NOT NULL

If you need to change the column type, here is the command:

ALTER TABLE user MODIFY userPhone BIGINT NOT NULL;

Also take a time to read about the number types on MySql docs

http://dev.mysql.com/doc/refman/5.7/en/numeric-types.html

As pointed out in the comments you shouldn't use a numeric type to store a phone number since there are phone numbers with a leading 0 and if it is stored as a number you would be losing this information. Pointed out by @GolezTrol and @GordonLinoff

Jorge Campos
  • 22,647
  • 7
  • 56
  • 87
  • there are no numbers with a leading zero anywhere on earth. that's just how you make an international call from a handful of european countries. you don't dial zero when you call the same numbers from the rest of the planet. – John Haugeland Apr 25 '23 at 12:42
  • @JohnHaugeland the second word "numbers" refers to phone number that I mention right before it. I will edit it to make it clear. – Jorge Campos Apr 25 '23 at 16:03
  • There are no phone numbers with a leading zero anywhere on Earth, Jorge. – John Haugeland Apr 26 '23 at 00:21
  • 1
    @JohnHaugeland You overemphasize international numbers, overlooking each country's unique dialing rules. The prefix you dismiss is crucial, directing calls to the correct PBX or operator. Leading zeroes and symbols address special cases and enhance readability. Also, my phone number begins with a zero; using the international format would incur extra fees since that would use a different operator than mine. Maybe they "should" be number, but in reality they aren't. – Guillaume F. Apr 26 '23 at 15:44
-3

Despite Guillame's completely incorrect answer that has been accepted for nine years, phone numbers can and should be stored as numbers.

None of the counter-examples he gives are correct.

First, to respond to his claims that a phone number cannot be stored in a number:

  1. Phone commands are not part of a phone number. You might as well try to care for a discord handle in their mailing address. Databases don't carry substitute datasets.

  2. There is no plus in an international country code. Yes, that's how Europeans write it, but get your phone out, and try to dial the plus. Let me know when you figure out how, and send me some instructions please. There's also no dashes or parentheses in a phone number. There are only digits.

  3. Of course you shouldn't be storing SIP email addresses in your phone number column. That is not a phone number.

  4. Phone numbers do not have leading zeroes. Guillame may not know this, but that is a country-bound call command. If you go to a different country, you won't have to dial it anymore, even though the phone number hasn't changed. Therefore, it is not actually part of the phone number. So, by example, if I call my Canadian friend from Germany, I have to start by dialling a zero. But if I call them from Canada, or the United States, or Mexico, or France, I don't have to. Why? Because phone numbers by definition never start with a zero. The only exception is the American/Canadian call prefix to operator. This was part of the international phone system agreements that built this system more than a hundred years ago.

So.

Why do this right?

Well.

  1. Data that can be normalized should be normalized.
    • If you're able to write the same phone number three different ways, that's a problem.
    • The example given was 0199857514.
    • If you dial that from Europe, you get Uzbekistan. Europe is the only place on Earth where that dialing pattern will work, so I assume Guillame is European, and doesn't travel enough to know how phones work other places.
    • If you dial that from the United States or Canada, you get an operator after the first digit, because dialing 0 gets operator.
    • From a cruise ship, you get the police after the second digit.
    • In Japan, you get hung up on, because 09 is the beginning of the system prefix (what an American would think of as an X11 number like 411 or 611,) and whereas there is a 091 and through a 095, there is no 099.
    • In China, you get a fast busy, because starting a call with 01 is never correct in China under any circumstances
    • The fundamental problem here is that dialing 01 before a phone number in Europe is a phone system command, and not actually part of the phone number; the correctly parsed number there is (01 is a command,) (998 is a country code), (57514) is the actual local phone number.
    • The correct complete phone number is 99857514. It does not include the external dial prefix 01, which is a command to Guillame's local phone system.
    • That number starts with just a 1 from the US, with 010 from Japan, 001 from China, et cetera. In the United States, the way to call that number varies between networks; cell phones, legacy landlines, and ESS6+ landlines all call that number differently. Think I'm kidding? Ask someone from Atlanta, who has to know what phone carrier they're on to know how to make an international call, because one requires the 1 prefix and the other forbids it.
  2. Why does normalization matter?
    • It's a database community. This should be obvious.
    • Guillame writes it 0199857514. I write it 1199857514. My Chinese friend writes it 0010199857514. My Japanese friend writes it 010199857514.
    • The customer was taken by the Japanese sales team, so it's in the database as 010199857514. I'm on the American sales team, and I try to look the customer up. They're in Europe, so they say their number is 0199857514. I look, and can't find that. As an American, I next try 1199857514, and 110199857514, but they're not in there. I don't know about the Japanese notation. The system incorrectly tells me that this phone number is not in use, so I create a new customer record and attach to that.
    • The customer is now in the database twice under two different phone numbers. Records are being lost. Double billing is beginning. Things that are recorded aren't being honored because we're looking at the wrong copy of the user.
    • Foreign keys are just as easy to violate as unique constraints.
    • "But the application shouldn't have to format with local phone rules!" Of course it should. Just like you don't track dates as strings, and format them on the way in, and on the way out. Just like Europeans write AA/BB/CCCC where Americans write BB/AA/CCCC, and Japanese write CCCC/BB/AA. This is a local formatting issue, and you cannot fold local formatting into your data.
  3. Performance
    • If you didn't stop reading at "this makes your data incorrect," you're going too far
    • But also, holy crap, you really want to make string comparisons instead of integer comparisons on your index?

In order to do the job correctly, you must remove the country control code, because it's not part of the phone number, and works differently in different countries

You should not be storing things that are not part of the phone number, such as PBX commands and SIP email addresses, in a phone number column

Phone numbers should be stored as numbers

John Haugeland
  • 9,230
  • 3
  • 37
  • 40
  • 1
    "can and should be stored as numbers" - no, that's wrong. Every out-of-town-call in Germany uses a 0 in the beginning to distinguish it from a in-town-call – Nico Haase Apr 25 '23 at 12:34
  • yes, nico, i pointed that out already, and relied on it as an example of why that cannot be in the database, because it's not correct from other countries. this really isn't that complicated. if the number changes when you go somewhere else, then what changed wasn't actually part of the number. read the second bullet under point 2. google, microsoft, and apple all store phone numbers internally as actual numbers. do you think they all fail to understand the phones? maybe when you finally travel outside your country, you'll start to understand – John Haugeland Apr 25 '23 at 12:35
  • let's try this a different way. if you make an out of town call in germany, then go to canada, and the way you call it is different, nico, did the phone number change? now if you go home and call it again, has the phone number changed a second time? do you think that the phone number in the database should be stored in a way that can only be called from a couple of countries, or in the way that is correct internationally, nico? – John Haugeland Apr 25 '23 at 12:40
  • 1
    "google, microsoft, and apple all store phone numbers internally as actual numbers" - do you have any credible source for that? https://github.com/google/libphonenumber/blob/master/FALSEHOODS.md (which looks like a repository from the Google guys), point 25, starts with "Never try to store phone numbers as an int or any other kind of numeric data type" – Nico Haase Apr 25 '23 at 12:42
  • I was a former staff member at all three, Nico. I'm not interested in "credible source" redditor nonsense; it's easy to look up. I'm also not interested in a readme you found. Please answer the question I asked. When you go to Canada, and you don't use the German outbound call prefix anymore, did the phone number change, and should the database be updated? – John Haugeland Apr 25 '23 at 12:43
  • Also, for fun, point 21 directly contradicts you, so if you care about this source, it's saying you're wrong. It's saying the reason that you shouldn't put phone numbers in numbers is that israeli numbers can start with an asterisk, but that hasn't been true for 15 years, and that some advertising uses letters for numbers (who cares). e164 says you're wrong, and it's the binding international standard here. Let me know if you think the phone number changed when you go somewhere else and have to call it differently, because that German rule doesn't even exist in most of Europe. – John Haugeland Apr 25 '23 at 12:46
  • 1
    I don't get the point of "go to Canada". Obviously I have to use a different way to call someone from my hometown Cologne. I would never use the international number to call my local pizza delivery guy – Nico Haase Apr 25 '23 at 12:47
  • Please try to add all clarification neccessary to your answer by editing it – Nico Haase Apr 25 '23 at 12:48
  • Let's make it even simpler for you, Nico. If the example number is written "01199857514", then you can only call it from nine countries on earth. If you want to call that from most of Europe, you don't follow the German pattern; you follow the French one, which is different. You lose normalcy, unique indices, and foreign keys. On the other hand, if you follow the e164 international standard, and write it "99857514", you can call it from anywhere on Earth, and it's correctly uniqued anywhere on Earth. Which strategy would you choose, and why? – John Haugeland Apr 25 '23 at 12:52
  • 1
    Well, a universal true way of storing phone numbers should be able to store all numbers possible, don't you think? Still, I don't get what you mean by that Canada thing. The phone number itself does not change, but the way I use it on my phone does. And if you store a german phone number in the locally used format without a leading 0 in any database and try to use it like that when making a call, you won't reach the person you want to call – Nico Haase Apr 25 '23 at 12:52
  • 1
    "Which strategy would you choose, and why? " - as far as I see, that's not the point of this question. Unless you assume that **everybody** inputs the data in a normalized way into the database, you should use a column type that does not modify the data (like dropping a leading 0) – Nico Haase Apr 25 '23 at 12:54