数据库:最佳做法国家/地区代码,国家/地区电话代码

时间:2018-05-06 14:45:07

标签: php mysql laravel laravel-5 internationalization

如果您将国家/地区代码存储在数据库中但无法找到“这是正确的方法”,那么我正在寻找“最佳实践”。我想存储2个国家代码和国家电话代码(例如德国将是“DE”和“+49”)。

实际上我的计划如下:创建一个表countries和一个表country_codes。像这样:

TABLE: countries
id INT(11)
code CHAR(2)

TABLE: country_codes
id INT(11)
country_id INT(11) FORGEIGN KEY (countries -> id)
phone_code VARHAR(6)

我认为我需要拆分它们,因为有些国家/地区有多个电话代码。这样一个国家/地区可以有多个电话代码。

但是我的问题是:那是“最佳做法”吗?如果我想在“所有”国家推出我的应用程序,或者如果我想用多种语言翻译应用程序(在这种情况下我想使用{{1表也​​适用于不同的语言。

如果您希望能够使用任何语言翻译您的应用而无需重新编码内容,并且您还需要应用中所有国家/地区的列表,那么您有什么方法可以做taht?

如果重要的话:我正计划用这个应用程序的laravel。

3 个答案:

答案 0 :(得分:1)

国家/地区代码标准化为two letters by ISO 3166-1-alpha-2,因此以这种方式存储它们将起作用。在表格中包含国家/地区名称通常很有帮助,因此用户可以选择正确的国家/地区,而无需知道所有代码。

电话号码的标准化程度要低得多。国际电联提供recommendation E.164来表示实际电话号码(在电话行话中称为“电话号码”)。国家/地区代码定义为一到三位数。北美(包括美国,加拿大和许多加勒比国家)都是North American Numbering Plan的一部分,并分享国家代码1

目录号码通常以+开头,并以点为点。因此,例如,已发布的纽约市目录服务号码(或者当他们还有这样的服务时)+1.212.555.1212。如果您从欧洲的某个地方拨打该号码,您会看到+并替换您当地的国际前缀。在NANP中,多个国家/地区具有相同的国家/地区代码。

但是,英国很奇怪。来自国外的电话,+44.exchange.number。但是要从国内拨打长途电话(0) exchange.number

我的观点:如果您尝试使用软件中的国家/地区代码编写目录号码,则很难做到正确。你可能最好要求用户提供带有国际前缀的电话号码。

您绝对不应将E.164国家/地区代码与ISO 3166双字母国家/地区代码绑定,方法是将它们作为不同的列放在表格的同一行上。您需要两个单独的表来进行未来验证。标准化组织是不同的,并且做自己的事情,因此您的数据模型应该反映出来。

请阅读:Falsehoods Programmers Believe About Telephone Numbers

答案 1 :(得分:0)

我的数据库看起来像这样:

> id    int(11) Auto Increment (Just an ID (primary key))
> iso   char(2)  (2-letters ISO code)
> name  varchar(80)  (normalized name (all uppercase))
> nicename  varchar(80)  (Nicely formatted name)
> iso3  char(3) NULL     (3-letters ISO code)
> numcode   smallint(6) NULL     (numeric ISO code)
> phonecode int(5) (phone code like '1' for USA, without '+')

它应该足够了。您可以获得用户的电话号码,在开头删除零,删除任何非数字字符,从DB添加国家/地区代码,您就可以开始使用了!

示例:

1)用户输入(045)111-22-33,德国

2)您将其转换为451112233

3)从DB添加德国代码(49)。你得到49451112233.如果你愿意,可以加'+'。

4)现在,您可以使用Twilio或任何其他服务拨打电话或发送短信。

如果您想“轻松”将网站翻译成其他语言,请将所有文字存储在数据库中,并根据用户的语言偏好选择合适的版本。

答案 2 :(得分:0)

根据答案,我会做以下事情:

数据库表:

+------------------------------------------------------------+
| Table: countries                                           |
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id           | int(11)      | NO   |     | NULL    |       |
| iso_code2    | char(2)      | NO   |     | NULL    |       |
| iso_code3    | char(3)      | NO   |     | NULL    |       |
| num_code     | int(3)       | NO   |     | NULL    |       |
| name         | varchar(48)  | NO   |     | NULL    |       |
| nicename     | varchar(48)  | NO   |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+
// will store all countries available


+------------------------------------------------------------+
| Table: country_phonecodes                                  |
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id           | int(11)      | NO   |     | NULL    |       |
| country_id   | int(11)      | NO   |     | NULL    |       |
| phonce_code  | int(6)       | NO   |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+
// based on this page: https://countrycode.org/ there are 
// countries with more than one code 
// and also codes can be 6 chars long


+------------------------------------------------------------+
| Table: languages                                           |
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id           | int(11)      | NO   |     | NULL    |       |
| code         | char(2)      | NO   |     | NULL    |       |
| locale       | char(5)      | NO   |     | NULL    |       |
| name         | varchar(50)  | NO   |     | NULL    |       |
| native_name  | varchar(50)  | NO   |     | NULL    |       |
| flag         | varchar(10)  | NO   |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+
// table for available translations of the app


+------------------------------------------------------------+
| Table: country_languages                                   |
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id           | int(11)      | NO   |     | NULL    |       |
| country_id   | int(11)      | NO   |     | NULL    |       |
| language_id  | int(11)      | NO   |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+
// table for language suggestions for a given country

一些示例插入:

+---------------------------------------------------------------------------------------+
| Inserts: countries                                                                    |
+-----+------------+------------+-----------+---------------------+---------------------+
| id  | iso_code2  | iso_code3  | num_code  | name                | nicename            |
+-----+------------+------------+-----------+---------------------+---------------------+
| 1   | de         | deu        | 276       | GERMANY             | Germany             |
| 2   | do         | dom        | 214       | DOMINICAN REPUBLIC  | Dominican Republic  |
| 3   | be         | bel        | 056       | BELGIUM             | Belgium             |
+-----+------------+------------+-----------+---------------------+---------------------+

+----------------------------------+
| Inserts: country_phonecodes      |
+-----+-------------+--------------+
| id  | country_id  | phonce_code  |
+-----+-------------+--------------+
| 1   | 1           | 49           |
| 2   | 2           | 1809         |
| 3   | 2           | 1829         |
| 4   | 2           | 1849         |
| 5   | 3           | 32           |
+-----+-------------+--------------+

+----------------------------------------------------------+
| Inserts: languages                                       |
+-----+-------+---------+---------+--------------+---------+
| id  | code  | locale  | name    | native_name  | flag    |
+-----+-------+---------+---------+--------------+---------+
| 1   | de    | de_DE   | German  | Deutsch      | de.svg  |
| 2   | do    | es_DO   | Spanish | Español      | es.png  |
| 3   | be    | fr_BE   | French  | Français     | fr.jpg  |
| 4   | be    | nl_BE   | Dutch   | Nederlands   | nl.png  |
| 5   | be    | de_BE   | German  | Deutsch      | de.svg  |
+-----+-------+---------+---------+--------------+---------+

+----------------------------------+
| Inserts: country_languages       |
+-----+-------------+--------------+
| id  | country_id  | language_id  |
+-----+-------------+--------------+
| 1   | 1           | 1            |
| 2   | 2           | 2            |
| 3   | 3           | 3            |
| 4   | 3           | 4            |
| 5   | 3           | 5            |
+-----+-------------+--------------+

我认为这应该适用于需要国家/地区列表和/或i18n的任何项目。

如果用户来自比利时,他可以从可用语言/翻译列表中进行选择。他会得到FR,NL和DE的建议,但仍然可以选择es_DO作为首选语言。

认为这应该涵盖所有需求 - 但如果有人发现问题或有想法/意见:如果我能改进这个解决方案,我会很高兴:)