Какой тип данных использовать для номера телефона sql

I need to store phone numbers in a table. Please suggest which datatype should I use?
Wait. Please read on before you hit reply..

This field needs to be indexed heavily as Sales Reps can use this field for searching (including wild character search).

As of now, we are expecting phone numbers to come in a number of formats (from an XML file). Do I have to write a parser to convert to a uniform format? There could be millions of data (with duplicates) and I dont want to tie up the server resources (in activities like preprocessing too much) every time some source data comes through..

Any suggestions are welcome..

Update: I have no control over source data. Just that the structure of xml file is standard. Would like to keep the xml parsing to a minimum.
Once it is in database, retrieval should be quick. One crazy suggestion going on around here is that it should even work with Ajax AutoComplete feature (so Sales Reps can see the matching ones immediately). OMG!!

asked Sep 16, 2008 at 17:57

John's user avatar

JohnJohn

9631 gold badge6 silver badges8 bronze badges

1

Does this include:

  • International numbers?
  • Extensions?
  • Other information besides the actual number (like «ask for bobby»)?

If all of these are no, I would use a 10 char field and strip out all non-numeric data. If the first is a yes and the other two are no, I’d use two varchar(50) fields, one for the original input and one with all non-numeric data striped and used for indexing. If 2 or 3 are yes, I think I’d do two fields and some kind of crazy parser to determine what is extension or other data and deal with it appropriately. Of course you could avoid the 2nd column by doing something with the index where it strips out the extra characters when creating the index, but I’d just make a second column and probably do the stripping of characters with a trigger.

Update: to address the AJAX issue, it may not be as bad as you think. If this is realistically the main way anything is done to the table, store only the digits in a secondary column as I said, and then make the index for that column the clustered one.

answered Sep 16, 2008 at 18:02

Kearns's user avatar

KearnsKearns

1,0797 silver badges10 bronze badges

6

We use varchar(15) and certainly index on that field.

The reason being is that International standards can support up to 15 digits

Wikipedia — Telephone Number Formats

If you do support International numbers, I recommend the separate storage of a World Zone Code or Country Code to better filter queries by so that you do not find yourself parsing and checking the length of your phone number fields to limit the returned calls to USA for example

answered Sep 16, 2008 at 18:03

Brad Osterloo's user avatar

5

Use CHAR(10) if you are storing US Phone numbers only. Remove everything but the digits.

answered Sep 16, 2008 at 18:00

Joseph Bui's user avatar

Joseph BuiJoseph Bui

1,69116 silver badges22 bronze badges

0

I’m probably missing the obvious here, but wouldn’t a varchar just long enough for your longest expected phone number work well?

If I am missing something obvious, I’d love it if someone would point it out…

answered Sep 16, 2008 at 18:00

cori's user avatar

coricori

8,5867 gold badges45 silver badges80 bronze badges

0

I would use a varchar(22). Big enough to hold a north american phone number with extension. You would want to strip out all the nasty ‘(‘, ‘)’, ‘-‘ characters, or just parse them all into one uniform format.

Alex

answered Sep 16, 2008 at 18:00

Alex Fort's user avatar

Alex FortAlex Fort

18.2k5 gold badges42 silver badges51 bronze badges

nvarchar with preprocessing to standardize them as much as possible. You’ll probably want to extract extensions and store them in another field.

answered Sep 16, 2008 at 17:59

John Sheehan's user avatar

John SheehanJohn Sheehan

76.8k30 gold badges159 silver badges194 bronze badges

SQL Server 2005 is pretty well optimized for substring queries for text in indexed varchar fields. For 2005 they introduced new statistics to the string summary for index fields. This helps significantly with full text searching.

answered Sep 16, 2008 at 18:02

Joseph Daigle's user avatar

Joseph DaigleJoseph Daigle

47.2k10 gold badges50 silver badges73 bronze badges

using varchar is pretty inefficient. use the money type and create a user declared type «phonenumber» out of it, and create a rule to only allow positive numbers.

if you declare it as (19,4) you can even store a 4 digit extension and be big enough for international numbers, and only takes 9 bytes of storage. Also, indexes are speedy.

answered May 3, 2011 at 16:12

fjleon's user avatar

fjleonfjleon

3413 silver badges10 bronze badges

2

Normalise the data then store as a varchar. Normalising could be tricky.

That should be a one-time hit. Then as a new record comes in, you’re comparing it to normalised data. Should be very fast.

answered Sep 16, 2008 at 17:59

Iain Holder's user avatar

Iain HolderIain Holder

14.1k10 gold badges65 silver badges86 bronze badges

Since you need to accommodate many different phone number formats (and probably include things like extensions etc.) it may make the most sense to just treat it as you would any other varchar. If you could control the input, you could take a number of approaches to make the data more useful, but it doesn’t sound that way.

Once you decide to simply treat it as any other string, you can focus on overcoming the inevitable issues regarding bad data, mysterious phone number formating and whatever else will pop up. The challenge will be in building a good search strategy for the data and not how you store it in my opinion. It’s always a difficult task having to deal with a large pile of data which you had no control over collecting.

answered Sep 16, 2008 at 18:05

unicorn.ninjaunicorn.ninja

Use SSIS to extract and process the information. That way you will have the processing of the XML files separated from SQL Server. You can also do the SSIS transformations on a separate server if needed. Store the phone numbers in a standard format using VARCHAR. NVARCHAR would be unnecessary since we are talking about numbers and maybe a couple of other chars, like ‘+’, ‘ ‘, ‘(‘, ‘)’ and ‘-‘.

answered Sep 16, 2008 at 18:09

Magnus Johansson's user avatar

Magnus JohanssonMagnus Johansson

27.8k19 gold badges104 silver badges164 bronze badges

Use a varchar field with a length restriction.

agf's user avatar

agf

167k42 gold badges283 silver badges234 bronze badges

answered Sep 16, 2008 at 18:00

user13270's user avatar

It is fairly common to use an «x» or «ext» to indicate extensions, so allow 15 characters (for full international support) plus 3 (for «ext») plus 4 (for the extension itself) giving a total of 22 characters. That should keep you safe.

Alternatively, normalise on input so any «ext» gets translated to «x», giving a maximum of 20.

answered Jul 22, 2013 at 9:34

Rob G's user avatar

Rob GRob G

744 bronze badges

It is always better to have separate tables for multi valued attributes like phone number.

As you have no control on source data so, you can parse the data from XML file and convert it into the proper format so that there will not be any issue with formats of a particular country and store it in a separate table so that indexing and retrieval both will be efficient.

Thank you.

answered Aug 12, 2017 at 14:36

Jayghosh Wankar's user avatar

1

I realize this thread is old, but it’s worth mentioning an advantage of storing as a numeric type for formatting purposes, specifically in .NET framework.

IE

.DefaultCellStyle.Format = "(###)###-####" // Will not work on a string

ΩmegaMan's user avatar

ΩmegaMan

28.4k10 gold badges98 silver badges117 bronze badges

answered Mar 23, 2017 at 1:14

Mr. Tripodi's user avatar

Mr. TripodiMr. Tripodi

8091 gold badge6 silver badges7 bronze badges

1

Use data type long instead.. dont use int because it only allows whole numbers between -32,768 and 32,767 but if you use long data type you can insert numbers between -2,147,483,648 and 2,147,483,647.

answered Apr 2, 2020 at 20:31

Ej Manalo Carbona's user avatar

1

For most cases, it will be done with bigint

Just save unformatted phone numbers like: 19876543210, 02125551212, etc.

Check the topic about bigint vs varchar

answered Dec 19, 2022 at 15:11

job.js.org's user avatar

job.js.orgjob.js.org

2,4172 gold badges18 silver badges29 bronze badges

I need to store phone numbers in a table. Please suggest which datatype should I use?
Wait. Please read on before you hit reply..

This field needs to be indexed heavily as Sales Reps can use this field for searching (including wild character search).

As of now, we are expecting phone numbers to come in a number of formats (from an XML file). Do I have to write a parser to convert to a uniform format? There could be millions of data (with duplicates) and I dont want to tie up the server resources (in activities like preprocessing too much) every time some source data comes through..

Any suggestions are welcome..

Update: I have no control over source data. Just that the structure of xml file is standard. Would like to keep the xml parsing to a minimum.
Once it is in database, retrieval should be quick. One crazy suggestion going on around here is that it should even work with Ajax AutoComplete feature (so Sales Reps can see the matching ones immediately). OMG!!

asked Sep 16, 2008 at 17:57

John's user avatar

JohnJohn

9631 gold badge6 silver badges8 bronze badges

1

Does this include:

  • International numbers?
  • Extensions?
  • Other information besides the actual number (like «ask for bobby»)?

If all of these are no, I would use a 10 char field and strip out all non-numeric data. If the first is a yes and the other two are no, I’d use two varchar(50) fields, one for the original input and one with all non-numeric data striped and used for indexing. If 2 or 3 are yes, I think I’d do two fields and some kind of crazy parser to determine what is extension or other data and deal with it appropriately. Of course you could avoid the 2nd column by doing something with the index where it strips out the extra characters when creating the index, but I’d just make a second column and probably do the stripping of characters with a trigger.

Update: to address the AJAX issue, it may not be as bad as you think. If this is realistically the main way anything is done to the table, store only the digits in a secondary column as I said, and then make the index for that column the clustered one.

answered Sep 16, 2008 at 18:02

Kearns's user avatar

KearnsKearns

1,0797 silver badges10 bronze badges

6

We use varchar(15) and certainly index on that field.

The reason being is that International standards can support up to 15 digits

Wikipedia — Telephone Number Formats

If you do support International numbers, I recommend the separate storage of a World Zone Code or Country Code to better filter queries by so that you do not find yourself parsing and checking the length of your phone number fields to limit the returned calls to USA for example

answered Sep 16, 2008 at 18:03

Brad Osterloo's user avatar

5

Use CHAR(10) if you are storing US Phone numbers only. Remove everything but the digits.

answered Sep 16, 2008 at 18:00

Joseph Bui's user avatar

Joseph BuiJoseph Bui

1,69116 silver badges22 bronze badges

0

I’m probably missing the obvious here, but wouldn’t a varchar just long enough for your longest expected phone number work well?

If I am missing something obvious, I’d love it if someone would point it out…

answered Sep 16, 2008 at 18:00

cori's user avatar

coricori

8,5867 gold badges45 silver badges80 bronze badges

0

I would use a varchar(22). Big enough to hold a north american phone number with extension. You would want to strip out all the nasty ‘(‘, ‘)’, ‘-‘ characters, or just parse them all into one uniform format.

Alex

answered Sep 16, 2008 at 18:00

Alex Fort's user avatar

Alex FortAlex Fort

18.2k5 gold badges42 silver badges51 bronze badges

nvarchar with preprocessing to standardize them as much as possible. You’ll probably want to extract extensions and store them in another field.

answered Sep 16, 2008 at 17:59

John Sheehan's user avatar

John SheehanJohn Sheehan

76.8k30 gold badges159 silver badges194 bronze badges

SQL Server 2005 is pretty well optimized for substring queries for text in indexed varchar fields. For 2005 they introduced new statistics to the string summary for index fields. This helps significantly with full text searching.

answered Sep 16, 2008 at 18:02

Joseph Daigle's user avatar

Joseph DaigleJoseph Daigle

47.2k10 gold badges50 silver badges73 bronze badges

using varchar is pretty inefficient. use the money type and create a user declared type «phonenumber» out of it, and create a rule to only allow positive numbers.

if you declare it as (19,4) you can even store a 4 digit extension and be big enough for international numbers, and only takes 9 bytes of storage. Also, indexes are speedy.

answered May 3, 2011 at 16:12

fjleon's user avatar

fjleonfjleon

3413 silver badges10 bronze badges

2

Normalise the data then store as a varchar. Normalising could be tricky.

That should be a one-time hit. Then as a new record comes in, you’re comparing it to normalised data. Should be very fast.

answered Sep 16, 2008 at 17:59

Iain Holder's user avatar

Iain HolderIain Holder

14.1k10 gold badges65 silver badges86 bronze badges

Since you need to accommodate many different phone number formats (and probably include things like extensions etc.) it may make the most sense to just treat it as you would any other varchar. If you could control the input, you could take a number of approaches to make the data more useful, but it doesn’t sound that way.

Once you decide to simply treat it as any other string, you can focus on overcoming the inevitable issues regarding bad data, mysterious phone number formating and whatever else will pop up. The challenge will be in building a good search strategy for the data and not how you store it in my opinion. It’s always a difficult task having to deal with a large pile of data which you had no control over collecting.

answered Sep 16, 2008 at 18:05

unicorn.ninjaunicorn.ninja

Use SSIS to extract and process the information. That way you will have the processing of the XML files separated from SQL Server. You can also do the SSIS transformations on a separate server if needed. Store the phone numbers in a standard format using VARCHAR. NVARCHAR would be unnecessary since we are talking about numbers and maybe a couple of other chars, like ‘+’, ‘ ‘, ‘(‘, ‘)’ and ‘-‘.

answered Sep 16, 2008 at 18:09

Magnus Johansson's user avatar

Magnus JohanssonMagnus Johansson

27.8k19 gold badges104 silver badges164 bronze badges

Use a varchar field with a length restriction.

agf's user avatar

agf

167k42 gold badges283 silver badges234 bronze badges

answered Sep 16, 2008 at 18:00

user13270's user avatar

It is fairly common to use an «x» or «ext» to indicate extensions, so allow 15 characters (for full international support) plus 3 (for «ext») plus 4 (for the extension itself) giving a total of 22 characters. That should keep you safe.

Alternatively, normalise on input so any «ext» gets translated to «x», giving a maximum of 20.

answered Jul 22, 2013 at 9:34

Rob G's user avatar

Rob GRob G

744 bronze badges

It is always better to have separate tables for multi valued attributes like phone number.

As you have no control on source data so, you can parse the data from XML file and convert it into the proper format so that there will not be any issue with formats of a particular country and store it in a separate table so that indexing and retrieval both will be efficient.

Thank you.

answered Aug 12, 2017 at 14:36

Jayghosh Wankar's user avatar

1

I realize this thread is old, but it’s worth mentioning an advantage of storing as a numeric type for formatting purposes, specifically in .NET framework.

IE

.DefaultCellStyle.Format = "(###)###-####" // Will not work on a string

ΩmegaMan's user avatar

ΩmegaMan

28.4k10 gold badges98 silver badges117 bronze badges

answered Mar 23, 2017 at 1:14

Mr. Tripodi's user avatar

Mr. TripodiMr. Tripodi

8091 gold badge6 silver badges7 bronze badges

1

Use data type long instead.. dont use int because it only allows whole numbers between -32,768 and 32,767 but if you use long data type you can insert numbers between -2,147,483,648 and 2,147,483,647.

answered Apr 2, 2020 at 20:31

Ej Manalo Carbona's user avatar

1

For most cases, it will be done with bigint

Just save unformatted phone numbers like: 19876543210, 02125551212, etc.

Check the topic about bigint vs varchar

answered Dec 19, 2022 at 15:11

job.js.org's user avatar

job.js.orgjob.js.org

2,4172 gold badges18 silver badges29 bronze badges

If storing less then 1 mil records, and high performance is not an issue go for varchar(20)/char(20) otherwise I’ve found that for storing even 100 milion global business phones or personal phones, int is best. Reason : smaller key -> higher read/write speed, also formatting can allow for duplicates.

1 phone in char(20) = 20 bytes vs 8 bytes bigint (or 10 vs 4 bytes int for local phones, up to 9 digits) , less entries can enter the index block => more blocks => more searches, see this for more info (writen for Mysql but it should be true for other Relational Databases).

Here is an example of phone tables:

CREATE TABLE `phoneNrs` (   
    `internationalTelNr` bigint(20) unsigned NOT NULL COMMENT 'full number, no leading 00 or +, up to 19 digits, E164 format',
    `format` varchar(40) NOT NULL COMMENT 'ex: (+NN) NNN NNN NNN, optional',
    PRIMARY KEY (`internationalTelNr`)
    )
DEFAULT CHARSET=ascii
DEFAULT COLLATE=ascii_bin

or with processing/splitting before insert (2+2+4+1 = 9 bytes)

CREATE TABLE `phoneNrs` (   
    `countryPrefix` SMALLINT unsigned NOT NULL COMMENT 'countryCode with no leading 00 or +, up to 4 digits',
    `countyPrefix` SMALLINT unsigned NOT NULL COMMENT 'countyCode with no leading 0, could be missing for short number format, up to 4 digits',
    `localTelNr` int unsigned NOT NULL COMMENT 'local number, up to 9 digits',
    `localLeadingZeros` tinyint unsigned NOT NULL COMMENT 'used to reconstruct leading 0, IF(localLeadingZeros>0;LPAD(localTelNr,localLeadingZeros+LENGTH(localTelNr),'0');localTelNr)',
    PRIMARY KEY (`countryPrefix`,`countyPrefix`,`localLeadingZeros`,`localTelNr`)  -- ordered for fast inserts
) 
DEFAULT CHARSET=ascii
DEFAULT COLLATE=ascii_bin
;

Also «the phone number is not a number», in my opinion is relative to the type of phone numbers. If we’re talking of an internal mobile phoneBook, then strings are fine, as the user may wish to store GSM Hash Codes. If storing E164 phones, bigint is the best option.

So this will be the dummy question of the year but I need to ask since is not the first time I pass through this. Take a look to the following table definition:

enter image description here

Take a look at the column from_number which is a VARCHAR(45) right now but it will hold a phone number. Since I don’t know how many numbers a phone could have all over the world then I am trying to cover almost all of them. I want to keep database integrity as much as possible so I think VARCHAR is not a proper type for hold this kind of information — maybe I am wrong, you tell me — so I am thinking in change to INT or even BIGINT.

When I am defining a column in Workbench I should specify the number between parentheses () not in all the cases but in those I mention previous I had to. So if I do this: BIGINT() I got this error:

enter image description here

Which guide me to read a bit about this MySQL type here. Basically the info is this:

A large integer. … The unsigned range is 0 to 18446744073709551615.

Which make me ask: what value I should set for parentheses when I am defining a BIGINT() type. (I am using BIGINT because I don’t know if INT can hold as many numbers as a phone could have — perhaps I am wrong too). Which is the right way to create|design a column in MariaDB/MySQL databases?

Anyway I would like to know your opinion, experience and of course I would like to get an answer

Note: I am using MySQL Workbench latest edition for create the ER diagram. I am using also MariaDB 10.0.x

asked Dec 24, 2015 at 18:58

ReynierPM's user avatar

ReynierPMReynierPM

1,69010 gold badges29 silver badges45 bronze badges

1

How would you handle a phone number with an extension, such as «+1-000-000-0000 ext 1234» ?

Note, the «+» indicates international dialing rules should be applied; so from North America, the system automatically knows «011» in front of international calls, etc.

Also, what about phone numbers such as «1-800-DBA-HELP»?

I would typically store phone numbers as text. Having said that, it really depends how critical your phone number column is. If you are running automated dialers from that column, then you’d really want to ensure that only numbers are included, and the data represents well-formed phone numbers.

You could have separate columns for extensions, and phone numbers that have text, such as the «1-800-DBA-HELP» example I provided.

answered Dec 24, 2015 at 19:19

Hannah Vernon's user avatar

Hannah VernonHannah Vernon

68.4k22 gold badges164 silver badges303 bronze badges

7

Previously it was written:

«With MariaDB you could use a computed field to extract just the digits for an auto-dialer. Also works for MySQL 5.7.»

In response to the OP’s question about this («can you explain a bit what are you telling me?»), here is an explanation.

Many database systems have now introduced this feature. These are fields which are known variously as «computed«, «virtual» or «generated» which are derived from values in other fields. The power of this feature will vary depending on your RDBMS. I know that Oracle, Firebird, MariaDB and now MySQL 5.7 have them. Others probably also do.

An easy example would be to have a surname column and have a computed column which «stores» (remember, they can be virtual — i.e. calculated on the fly, or they can be physically stored on disk) the surname as all capitals, thereby making searching easier. That way you only have to search on CAPs (using, say, LIKE), knowing that the data being searched in the [computed | virtual | generated] field is in capitalised text.

The concept for MySQL 5.7 is explained here and here. It has been in MariaDB for a bit longer and the concept is also explained here. Some possible uses are suggested here, but you are really only limited by your imagination. They can be seen as a convenient (and less error-prone) substitute for triggers.

For your particular use case, you could derive a dialable number from a text field «+» —> «00» (or whatever your international dialling code is). Just a thought.

answered Dec 26, 2015 at 21:00

Vérace's user avatar

VéraceVérace

28.5k8 gold badges64 silver badges80 bronze badges

1

Hmm. Phone numbers are made of numbers. Using varchar allows user to store any type of formatting, with ( or not, with — or . and it quickly creates a mess with your data. A phone # format is «country» dependent, the mask should be tied to the country. Extension is an extension and is optional, so it should be stored in a «extension field». (int also).
For 1-800-DBA-HELP, i would convert that on the fly and store actual number. If you really need these human readable phone #, store it in separate varchar field.

answered May 1, 2017 at 20:24

greenlitmysql's user avatar

I usually stores the Phone Numbers in simple text. Formatting and display leave it to the client code.

Here, more than, how you store? what you are going to do with that phone number is really important.

If your business wants to perform outbound calls from your system, application will extract only numbers. If your business wants to make international calls, store country code and area code in separate columns.

If your business wants for reporting, the application will format and display with extension and numbers separately.

From my understanding, designing universal data model for phone number is not a good idea. Each country has different numbers, extensions and area code apart from country code. Also, I came to know, some countries does not have area code.

This may not answer your question but it will help to widen our understanding. Thank you.

answered May 3, 2017 at 11:05

Rathish Kumar B's user avatar

Rathish Kumar BRathish Kumar B

2,1345 gold badges20 silver badges34 bronze badges

  1. Learning About MySQL Data Types
  2. Use CHAR to Store Phone Numbers in MySQL
  3. Use TINYTEXT to Store Phone Numbers in MySQL
  4. Use VARCHAR to Store Phone Numbers in MySQL

Format and Store Phone Numbers in MySQL

MySQL offers various convenient data types for storing expected input to its databases. Knowledge of the correct datatype for storing peculiar data is key to ensuring an optimized and efficient database.

This tutorial illustrates the formatting and storage of phone numbers in a MySQL database.

Learning About MySQL Data Types

MySQL generally has three data types:

  1. Numeric (INT, BIT, FLOAT, etc.)
  2. String (CHAR, VARCHAR, TEXT, etc.)
  3. Date and Time (DATE, DATETIME, TIMESTAMP, etc.)

These generalized datatypes further have sub-types for specific cases of data handling in the database.

Check out this reference from w3schools on various RDBMS (Relational Database Management System) datatypes for further reading.

In handling phone numbers, one may be quick to consider using a numeric data type. However, problems could arise as phone numbers come in various formats (country codes, delimiters, etc.) and have special characters.

Since phone numbers are at a maximum of fifteen (15) digits in length, according to the International Telecommunications Union, a string type of CHAR, VARCHAR, or TINYTEXT are the best considerations.

CHAR and TINYTEXT have an upper limit of two-hundred-and-fifty-five (255) characters, while VARCHAR uses dynamic memory allocation for storing data up to a defined limit between 0 and 65535.

Let us take a few examples of phone number storage with each data type to decide the most appropriate choice.

Use CHAR to Store Phone Numbers in MySQL

The CHAR datatype (short for character) can store strings of fixed length between 0 and 255 characters. A column implementing CHAR can specify an upper limit constraint between 0 and 255, and MySQL expects every string in that column to be of the same size.

MySQL pads the remainder of the space with blanks when inputting a lower-length string than the specified constraint.

For example, if a table column specifies a CHAR data type with a size constraint of thirty characters (30), passing a value of 10 characters still takes up the space of 30 characters (10 data characters and 20 blanks).

A further discussion on this is available via this MySQL official documentation.

To illustrate, let us create a sample registration system database.

-- Initializing
CREATE DATABASE new_registration_db;
USE new_registration_db;

-- CREATING TABLES
CREATE TABLE registered_users (
	id INT AUTO_INCREMENT,
    username VARCHAR (255) NOT NULL,
    email VARCHAR(255),
    phone CHAR (15) NOT NULL,
    PRIMARY KEY(id)
);

-- POPULATING THE TABLE WITH SAMPLE REGISTRATION DATA
INSERT INTO registered_users(username, email, phone) Values
	('Mark Laurent', 'MarkRLaurent@teleworm.us','+1 908-204-0495'),
    ('Patricia Todd', 'PatriciaJTodd@teleworm.us','+1 801-752-2367'),
    ('Victoria McDonald', 'VictoriaAMcDonald@dayrep.com', '+1 608-299-8640'),
	('Vin Petrol', 'vin_not_diesel@crudemail.com','+1 870-381-6967');

Output:

1 row(s) affected
0 row(s) affected
0 row(s) affected
4 row(s) affected Records: 4  Duplicates: 0  Warnings: 0

Now, let us preview the resulting table.

SELECT * FROM registered_users;    -- Checking the table

Output:

id	username			email							phone
1	Mark Laurent		MarkRLaurent@teleworm.us		+1 908-204-0495
2	Patricia Todd		PatriciaJTodd@teleworm.us		+1 801-752-2367
3	Victoria McDonald	VictoriaAMcDonald@dayrep.com	+1 608-299-8640
4	Vin Petrol			vin_not_diesel@crudemail.com	+1 870-381-6967
-----------------------------------------------------------------------------------------
4 row(s) returned

Here, since the phone number is of a fixed length of 15 characters, the CHAR datatype will offer efficient storage. Also, it is indexable for filtering purposes.

However, the CHAR datatype may not efficiently manage memory for applications that take phone numbers of variable size (a global application) due to the padding of blanks, as earlier discussed.

Use TINYTEXT to Store Phone Numbers in MySQL

The TINYTEXT datatype is the smallest of the TEXT-type datatypes. It has the same memory constraints as a CHAR datatype between 0 and 255 characters.

However, unlike CHAR, it can dynamically allocate space to a passed value according to its character length. Hence, it offers better memory efficiency than the CHAR for this example of storing phone numbers.

It does have the downside of not having a default value making it non-indexable for sorting or aggregation.

Now, let us redo the previous example using TINYTEXT.

-- CREATING TABLES
CREATE TABLE registered_users2 (
	id INT AUTO_INCREMENT,
    username VARCHAR (255) NOT NULL,
    email VARCHAR(255),
    phone TINYTEXT NOT NULL,
    PRIMARY KEY(id)
);

-- POPULATING THE TABLE WITH SAMPLE REGISTRATION DATA
INSERT INTO registered_users2(username, email, phone) Values
	('Mark Laurent', 'MarkRLaurent@teleworm.us','+1 908-204-0495'),
    ('Patricia Todd', 'PatriciaJTodd@teleworm.us','+1 801-752-2367'),
    ('Victoria McDonald', 'VictoriaAMcDonald@dayrep.com', '+1 608-299-8640'),
	('Vin Petrol', 'vin_not_diesel@crudemail.com','+1 870-381-6967');

SELECT * FROM registered_users2;    -- Checking the table

Output:

id	username			email							phone
1	Mark Laurent		MarkRLaurent@teleworm.us		+1 908-204-0495
2	Patricia Todd		PatriciaJTodd@teleworm.us		+1 801-752-2367
3	Victoria McDonald	VictoriaAMcDonald@dayrep.com	+1 608-299-8640
4	Vin Petrol			vin_not_diesel@crudemail.com	+1 870-381-6967
-----------------------------------------------------------------------------------------
0 row(s) affected
4 row(s) affected Records: 4  Duplicates: 0  Warnings: 0
4 row(s) returned

We get an expected result. Check this reference for extra information on the MySQL TINYTEXT and other TEXT datatypes.

Use VARCHAR to Store Phone Numbers in MySQL

The final suggested method for handling phone numbers in MySQL is by using the VARCHAR data type. VARCHAR offers the flexibility of dynamic memory allocation when the phone number length will vary across database users.

It typically allocates two (2) extra bytes for storing length information. Hence, if a character of length six (6) is stored, a total memory allocation of 8 bytes is required for VARCHAR.

Columns specifying VARCHAR datatypes are also indexable for implementing sorting, aggregation, and primary/foreign key constraints.

Let us create a third table implementing VARCHAR for phone number allocation.

-- CREATING TABLES
CREATE TABLE registered_users3 (
	id INT AUTO_INCREMENT,
    username VARCHAR (255) NOT NULL,
    email VARCHAR(255),
    phone VARCHAR (15) NOT NULL,
    PRIMARY KEY(id)
);

-- POPULATING THE TABLE WITH SAMPLE REGISTRATION DATA
INSERT INTO registered_users3(username, email, phone) Values
	('Mark Laurent', 'MarkRLaurent@teleworm.us','+1 908-204-0495'),
    ('Patricia Todd', 'PatriciaJTodd@teleworm.us','+1 801-752-2367'),
    ('Victoria McDonald', 'VictoriaAMcDonald@dayrep.com', '+1 608-299-8640'),
	('Vin Petrol', 'vin_not_diesel@crudemail.com','+1 870-381-6967');

SELECT * FROM registered_users3;    -- Checking the table

Output:

id	username			email							phone
1	Mark Laurent		MarkRLaurent@teleworm.us		+1 908-204-0495
2	Patricia Todd		PatriciaJTodd@teleworm.us		+1 801-752-2367
3	Victoria McDonald	VictoriaAMcDonald@dayrep.com	+1 608-299-8640
4	Vin Petrol			vin_not_diesel@crudemail.com	+1 870-381-6967
-----------------------------------------------------------------------------------------
0 row(s) affected
4 row(s) affected Records: 4  Duplicates: 0  Warnings: 0
4 row(s) returned

Implementing either of the three described datatypes is sufficient for handling phone numbers in a MySQL database.

However, the choice of the most appropriate data type, based on memory efficiency and speed, is dependent on the intended database application.

O

На сайте с 29.05.2008

Offline

195

12 сентября 2013, 19:12

13282

Здравствуйте.

В каком типе поля SQL лучше хранить мобильный телефон — char или int?

SQL Мобильный телефон — char или int?

Всего проголосовало: 15

C

На сайте с 04.02.2005

Offline

274

12 сентября 2013, 19:17

#1

char

в начале было слово «+»

O

На сайте с 29.05.2008

Offline

195

12 сентября 2013, 19:18

#2

Chukcha, а зачем хранить +? Например, я захочу получить номера определенного оператора, LIKE для CHAR будет настолько же производителен, как и диапазон для INT?

C

На сайте с 04.02.2005

Offline

274

12 сентября 2013, 19:30

#3

Ок. Храните в двух полях — форматированное по вашему желанию

и чистое от формата :)

Если хотите использовать для поиска — char без формата номера, для быстрого доступа — отформатировнный

А еще… отдельным полем код оператора

siv1987

На сайте с 02.04.2009

Offline

427

12 сентября 2013, 19:34

#4

лучше всего в varchar

dkameleon

На сайте с 09.12.2005

Offline

386

13 сентября 2013, 00:07

#5

ortegas:
Chukcha, а зачем хранить +? Например, я захочу получить номера определенного оператора, LIKE для CHAR будет настолько же производителен, как и диапазон для INT?

мне кажется

num like ‘38095_______’

будет смотреться гармоничнее, нежели

num >= 380950000000 and num <= 380959999999

да и пользоваться тоже удобнее

DV

На сайте с 01.05.2010

Offline

644

13 сентября 2013, 04:03

#6

int.

Храните номера в соответствии со стандартом E.164. Символы, отличные от цифр, не нужны.

1

dromenko

На сайте с 17.08.2010

Offline

31

13 сентября 2013, 08:06

#7

Хранить в varchar. Сами так храним.

Попробуйте для теста записать 9999999999 в поле int

DV

На сайте с 01.05.2010

Offline

644

13 сентября 2013, 08:15

#8

unsigned int имеется в виду.

1

TF-Studio

На сайте с 17.08.2010

Offline

334

13 сентября 2013, 08:34

#9

Я бы масштабируемость сразу бы заложил….

3 поля: регион, код сети, номер телефона.

Допустим расширяемость, отчеты, да многое можно будет оптимизировать потом.

И выводить проще, если в отдельных полях будет )

O

На сайте с 29.05.2008

Offline

195

13 сентября 2013, 16:55

#10

Друзья, объясните, когда можно использовать один KEY для двух значений? Вот у меня есть номер телефона, который разбит на FOREIGN KEY `country` и непосредственно сам номер телефона. Я не вижу смысл создавать отдельные ключи для страны и номера, могу ли я сделать один ключ? Или для выборки это не катит? Нужно будет выбирать конкретный номер телефона, то-есть, выборка за `phone`, но использовать форматирование вывода в зависимости от `country`.

Если я хочу, чтобы целый номер country + phone был уникальным, по аналогии, нужно создавать один ключ UNIQUE?

Главная / Web / MySQL / Хранение номеров телефонов в Б…

Хранение номеров телефонов в БД

Хранение номеров телефонов в базе данных MySQL не такая уж тривиальная задача, как может показаться на первый взгляд. Один из первых вопросов при проектировании БД: какой тип ячейки БД использовать? Цифровое поле, например INT в MySQL не подходит для этих целей, так как номера некоторых телефонов (например мобильные номера в Украине) могут начинаться с нуля, а следовательно, если попытаться сохранить такой номер как число — ведущий ноль (нули) будут потеряны. Для хранения номеров телефонов лучше всего использовать текстовый тип столбца: CHAR.

Чтобы ускорить поиск по текстовым данным имеющим различную длину, в отдельном индексируемом цифровом столбце (TINYINT) можно хранить длину номера телефона и использовать её в условиях поиска — отсекать лишние номера при поиске. Но такая реализация базы данных нужна только при очень больших объемах телефонных номеров и в большинстве случаев её можно не использовать.

Если планируется хранение номеров телефонов в месте с кодом города и страны — лучше всего разделить эти данные на 4 отдельных столбца: код1, код2, номер телефона, полный номер телефона (код1, код2, номер).

Код1 — это, в основном, код страны (+20 — Египет, +380 — Украина и т.д.), но некоторые первичные коды телефонов могут и не иметь привязки к стране, например: 388 — European Telephony Numbering Space (Europe-wide services); 870 — Inmarsat «SNAC» service и т.д. Поэтому называть такую колонку country_code или подобным образом логически не правильно. Помимо всего прочего один первичный код может принадлежать нескольким странам: +1 — Америка, Канада и другие; 7 — Россия, Казахстан и т.д. Подробнее о таких кодах можно прочитать тут: Географические коды телефонных номеров. Хранить данные о первичном коде телефонного номера можно и в цифровом формате, так как все такие коды не могут начинаться с нуля, но исходя из соображения, что стандарт в будущем может поменяться — безопаснее сразу хранить такую информацию в текстовом виде. Максимальное количество символов Код1 — пять.

Код2 может быть кодом города, мобильного оператора или чего-нибудь еще, соответственно mob_code, city_code не являются логичными названиями для таких данных. Следует отметить, что в некоторых странах такие коды, возможно, могут начинаться и с нуля, поэтому выбор типа данных такого столбца — очевиден. Максимальное количество символов в таком столбце, скорее всего, не будет более пяти.

Номер телефона — об этом столбце написано в начале статьи. Кол-во символов в таком номере, обычно не превышает 7 штук.

Полный номер телефона содержит в себе информацию столбцов БД MySQL Код1, Код2 и Номер телефона. Этот столбец существенно упростит проверку на дублирующиеся номера. Тип и размер данных в нем высчитывается на основании колонок Код1, Код2 и Номер телефона.

Если планируется привязка нескольких номеров телефонов к одной организации, в таблице базы данных следует предусмотреть колонку с идентификатором фирмы (firm_id) и колонку порядковый номер телефона (number). Это решение очень поможет в составлении легковесных SQL запросов, когда нужно выводить список многих организаций с одним (например: основным) номером телефона.

Вывести только 1 номер телефона для всех фирм из БД

SELECT f.firm, p.phone
FROM table_firm AS f
LEFT JOIN table_phone AS p ON (f.id = p.firm_id AND p.number = 1)

Колонка порядковый номер должна содержать последовательные номера, начинающиеся с единицы, без разрывов: 1,2,3.

Хранение номеров телефонов, зачастую, подразумевает и сопутствующую их привязку к персональной информации — ФИО, название организации и т.д., а для этого, в свою очередь во многих странах требуются специальные разрешения, регистрации баз данных и т.п.

Хранение номеров телефонов в виде хеша

Если номер телефона нужен только для подтверждения регистрации пользователя — как средство защиты от ботов и мультиаккаунтов можно использовать следующую схему. Номер хранится в открытом виде только до подтверждения регистрации. После подтверждения создается и записывается в БД взломоустойчивый хеш номера телефона, а сам номер удаляется:

Пример относительно взломоустойчивого хеша на PHP

$hash = md5(md5($phone_number).‘saltBLF@#$%^’);

При необходимости восстановления пароля пользователя через мобильный телефон, отослав на него код активации, нужно запросить через форму у пользователя его номер телефона, вычислить хеш, сравнить с тем что в БД и выслать на него инструкции по активации.

Опубликовано: 2013/03/20

HTML-код ссылки на эту страницу:

<a href=»https://petrenco.com/mysql.php?txt=168″ target=»_blank»>Хранение номеров телефонов в БД</a>

27514

When dealing with SQL databases, users will have to interact with different data types and schemas depending on the project’s requirements. Since databases are used in many different applications and support multiple platforms, devices, and users, there may be differences in how data is entered, even in a simple field like a phone number.

For example, one set of users will enter the phone number with the country code, while the others may simply ignore the country code. Therefore, it is essential for database users to know how to clean data in a SQL database. In this post, we will see how to utilize SQL string operations on phone number fields to properly clean, format, and extract data.

Why Do We Care About Data Cleaning?

Data comes in all forms and sizes. Most of the time, it will be raw data, without proper formatting. Data cleaning allows users to filter, sort, and format this raw data to extract meaningful information from it. Data cleaning also makes data analysis a much more efficient process as an additional benefit.

Let’s assume we have a text field that captures user information and asks users to enter valuable information like phone numbers. We need to clean this text field to make the phone numbers usable. How would we go about doing that? To begin with, we need to understand SQL string operations.

What are SQL String Operations?

String operations are functions that can be used to manipulate strings. These string operators (also called string functions) take a string as input, process it according to the specified function, and return a string as the output. The availability of these functions will differ depending on the database. For example, the following is a list of commonly used string functions in MySQL:

Common Types of String Operations

Function Usage
LEFT/RIGHT Extract a specified number of characters from a string (starting from left or right)
TRIM Remove leading or trailing spaces
POSITION / STRPOS Analogous to the Location function, where a numerical value of the position of the specified substring is provided
SUBSTR Extract the specified substring from a specific location to match the specified length
CONCAT Combine two or more strings to make a single string
SUBSTR Extract the specified substring from a specific location to match the specified length
COALESCE Replace null values with a specified value
FORMAT Formats the value to the specified format
REGEXP Matches string to a regular expression
REGEXP_SUBSTR Extracts value for the matching regular expression
STR Convert numerical value to string
REVERSE Reverses the specified string
REPLACE Replaces the specified string with the given value

The full list of available string functions and operators is available in the official documentation.

How to use String Operations with Phone Numbers

Now we have a basic understanding of string operations and related functions in SQL! So, let’s look at how exactly we can utilize some of these functions on phone numbers to extract and format data. For all the examples provided here, we will be using the Arctype SQL client with a MySQL database in a Windows environment with the following dataset.

If you don’t have Arctype installed, you can use the link below to download it and follow along:

The fast and easy-to-use
SQL client for developers and teams

Properly Formatting a Phone Number

We can utilize the SUBSTR command to format phone numbers. It will extract parts of the number and use the CONCAT to join the specific parts together. In the following example, we have broken down the phone number into three distinct sections and combined them together with the formatting as a new field called num_formatted:

SELECT
    phone_num,
    CONCAT(
        '(',
        SUBSTR(phone_num, 1, 3),
        ') ',
        SUBSTR(phone_num, 4, 3),
        '-',
        SUBSTR(phone_num, 7)
    ) AS num_formatted
FROM
    EmpDetails
Formatting a phone number in SQL.

The result of the operation is show below:

Cleaning phone numbers - output of example.

Cleaning phone numbers in Arctype.

You can create a new column to save the formatted number using the ALTER TABLE command. It will create a new column and update it with the formatted numbers.

ALTER TABLE EmpDetails
ADD formatted_number VARCHAR(255);
    
UPDATE
    EmpDetails
SET
    formatted_number = (
        SELECT
            CONCAT(
                '(',
                SUBSTR(phone_num, 1, 3),
                ') ',
                SUBSTR(phone_num, 4, 3),
                '-',
                SUBSTR(phone_num, 7)
            ) AS num_formatted
    )
Creating a new column to save the formatted data.

The result of the above operation is shown below:

Screeshot of a query in Arctype.

Updating the query to save the formatted data in a new column using Arctype.
Screenshot of data from a query to convert phone numbers to formatted data.
Resulting data from the above query.

We can modify our SQL command to include the REPLACE function if there are additional characters in the phone number field, such as dashes and brackets. This function can be used to remove unnecessary characters and whitespaces in a string. Now let’s further format the formmated_number field to include the country code.

SELECT
    formatted_number,
    CONCAT(
        '+1 '
        '(',
        SUBSTR(num_cleansed, 1, 3),
        ') ',
        SUBSTR(num_cleansed, 5, 3),
        '-',
        SUBSTR(num_cleansed, 7)
    ) AS num_formatted
FROM
    (
        SELECT
            formatted_number,
            REPLACE(REPLACE(REPLACE(REPLACE(formatted_number, '(', ''), ')', ''), '-', ''), ' ','') as num_cleansed
        FROM
            EmpDetails
    ) FormattedPhoneNumbers
Adding the country code, using REPLACE.

In the above statement, the REPLACE function is used to remove the brackets, dashes, and whitespaces from the formatted_number field before undergoing the formatting process.

Screenshot of query results.

Results of the query.

We can use the LEFT and RIGHT functions to specify and extract different parts of the phone number. In the following example, we will extract the area code of the phone number using the LEFT function and the last four digits using the RIGHT function based on the num_formatted field.

SELECT
    REPLACE(LEFT(formatted_number, 4), '(', '') As 'Area Code',
    RIGHT(formatted_number, 4) AS 'Last Four Digits'
FROM
    EmpDetails
Using the LEFT and RIGHT functions to specify different parts of a phone number.

Here, the REPLACE function is used to remove the bracket from the selected number block. The result of the query is shown below.

Query result in Arctype.

Query result in Arctype.

One of the most common tasks in the world of data cleaning is extracting phone numbers from a text block. The complexity and feasibility of this task will mostly depend on the composition of the text.

The easiest way to extract phone numbers is to utilize regular expressions to target the specific phone number formats. Extracting data has become far simpler with the introduction of functions like REGEXP_SUBSTR in MySQL 8.0. We will be populating the details column with some phone numbers in different formats, as shown below.

Arctype showing query results.

Results of the query in Arctype

Identifying Rows with Matching Phone Numbers

First, we need to figure out which rows consist of data matching our requirements. In this case, the following regular expressions will be used on the details field.

  • Any consecutive 10 digits
  • Formatted number (XXX-XXX-XXXX)
SELECT
    *
FROM
    EmpDetails
WHERE
    # Any 10 Digits
    details REGEXP '[[:digit:]]{10}'
    # Formatted Number (XXX-XXX-XXXX)
    OR details REGEXP '[0-9]{3}-[0-9]{3}-[0-9]{4}';

Using regular expressions to clean the data.

Results of the query can be seen below:

Regexp query results screenshot.

Arctype showing the query and results of a Regexp approach.

Since we have identified the rows, the next step is to extract the phone numbers. It can be done using the REGEXP_SUBSTR function to extract the substring which matches the given regular expression. As we need to query two different regular expressions, we will be using the CONCAT_WS function to combine the results of both expressions into a single column.

SELECT
    emp_id,
    name,
    email,
    CONCAT_WS(
        '',
        REGEXP_SUBSTR(details, '^[0-9]+$', 1, 1, 'm'),
        REGEXP_SUBSTR(details, '[0-9]{3}-[0-9]{3}-[0-9]{4}', 1, 1, 'm')
    ) AS extracted_phone_numbers
FROM
    (
        SELECT
            *
        FROM
            EmpDetails
        WHERE
            details REGEXP '[[:digit:]]{10}'
            OR details REGEXP '[0-9]{3}-[0-9]{3}-[0-9]{4}'
) ExtractedDetails
Extracting the phone numbers.

The result of this operation can be seen below:

Screenshot of phone number extraction.

Extracting the phone numbers in Arctype, with the results shown below the query.

Handling Multiple Phone Numbers in a Single Field

To query results from a single field with multiple numbers, we need to create a stored procedure that loops through the desired field to capture all matching regex patterns. For instance, let’s see how to extract multiple phone numbers from the details field of emp_id 1702 (Dan).

DELIMITER $$
CREATE PROCEDURE get_number_of_matches_full()
BEGIN
  DECLARE regex_match INT DEFAULT 1;
  DECLARE current_number INT DEFAULT 1;
  WHILE regex_match >= 1 DO
    CREATE TABLE IF NOT EXISTS extracted_numbers_table (
        `emp_id` int NOT NULL,
        `name` varchar(255) DEFAULT NULL,
        `email` varchar(255) DEFAULT NULL,
        `extracted_phone_num` varchar(255) DEFAULT NULL
    );
    INSERT INTO extracted_numbers_table (emp_id, name, email, extracted_phone_num)
    SELECT emp_id, name, email, REGEXP_SUBSTR(details, '[0-9]{3}-[0-9]{3}-[0-9]{4}', 1, current_number, 'm') FROM EmpDetails WHERE emp_id = 1702;
    SET current_number = current_number + 1;
    IF ((SELECT REGEXP_SUBSTR(details, '[0-9]{3}-[0-9]{3}-[0-9]{4}', 1, current_number, 'm') FROM EmpDetails WHERE emp_id = 1702) IS NULL) THEN
        SET regex_match = 0;
    END IF;
  END WHILE;
END $$
    
DELIMITER;
Using a stored procedure to loop through thee desired field and find all matching Regex patterns. 

The result of this operation is shown below.

Query result in Arctype.

Query result in Arctype.

In the above code block, we have created a stored procedure called get_number_of_matches_full, which loops through the details field until all the regex matches are found on the specified row of the EmpDetails table. We are using the REGEXP_SUBSTR function with the position argument to extract different matches. It updates by one at each loop run and saves the results on a newly created extracted_numbers_table. Finally, the loop exits when a NULL result is found.

We can call this procedure and view the results by querying the extracted_numbers_table as shown below.

CALL get_number_of_matches_full;

SELECT * FROM extracted_numbers_table;
Finding the extracted numbers.

And, shown again in Arctype:

Query results in Arctype.

Query results as seen in Arctype.

Conclusion

String operations in SQL are vital functions to clean and format data within a database. Moreover, string operations are the core component when dealing with valuable information such as phone numbers as they allow users to extract or manipulate phone numbers according to their requirements. However, it’s important to remember that the exact functions available will change depending on the database type and version. Therefore, always remember to refer to the documentation to find out the available string operations and implement them to your heart’s content.

Ready to get started with string operations in SQL? If so, be sure to download Arctype and give it a try. You can use the link below to install Arctype for free and follow along with the examples seen here. Happy querying!

JOIN the Arctype Newsletter

Programming stories, tutorials, and database tips every 2 weeks

Это тоже интересно:

  • Какой тип данных использовать для номера телефона mysql
  • Какой твой номер телефона на немецком
  • Какой твой номер телефона на английском
  • Какой тариф на этом телефоне на этом номере
  • Какой стране принадлежит номер телефона 234

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии