如果您将国家/地区代码存储在数据库中但找不到"这是正确的方法",我正在寻找"最佳实践"。我想存储 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)
我想我需要拆分它们,因为有些国家/地区有多个电话代码。这样,一个国家/地区可以有多个电话代码。
但对于我的问题:这是这样做的"最佳实践"吗?如果我想在"所有"国家/地区推出我的应用程序,或者如果我想将应用程序翻译成多种语言(在这种情况下,我想将countries
表也用于不同的语言,不仅从这一点"这将起作用",而且从该观点来看
。如果您希望能够在不需要重新编码的情况下将应用程序翻译成任何语言,并且您还需要应用程序中所有国家/地区的列表,那么您有什么方法可以做到这一点?
如果它应该重要:我计划与 laravel 一起开发这个应用程序。
国家/地区代码由 ISO 3166-1-alpha-2 标准化为两个字母,因此以这种方式存储它们将起作用。在表格中包含国家/地区名称通常很有帮助,因此用户可以选择正确的国家/地区,而无需知道所有代码。
电话号码的标准化程度要低得多。国际电联提供了代表实际电话号码(电话术语中称为"目录号码")的建议E.164。 国家/地区代码定义为一到三位数字。北美(包括美国,加拿大和许多加勒比国家)都是北美编号计划的一部分,并共享国家代码1
。
目录号码通常以 + 开头,并以点标点。因此,例如,已发布的纽约市目录协助号码是(或当他们仍然有这样的服务时)+1.212.555.1212
。如果您从欧洲的某个地方拨打该号码,您将看到+
并替换您当地的国际前缀。在 NANP 中,多个国籍具有相同的国家/地区代码。
但是,英国很奇怪。 从国外打来的电话,+44.exchange.number
.但是从国内长途打电话是(0) exchange.number
.
我的观点:如果您尝试在软件中使用国家/地区代码编写目录号码,则很难正确处理。您最好要求用户提供带有国际前缀的电话号码。
您绝对不应该将 E.164 国家/地区代码与 ISO 3166 双字母国家/地区代码绑定,方法是将它们作为不同的列放在表格的同一行上。您需要两个单独的表才能适应未来。标准化组织是不同的,它们做自己的事情,因此您的数据模型应该反映这一点。
阅读以下内容:程序员相信电话号码的谎言。
我的数据库看起来像这样:
> 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 '+')
应该足够了。您获得用户的电话号码,删除开头的零,删除任何非数字字符,从数据库添加国家/地区代码,您就可以开始了!
例:
1) 用户输入 (045) 111-22-33, 德国
2)将其转换为451112233
3) 从数据库添加德国代码 (49)。你得到49451112233。如果您愿意,请添加"+"。
4)现在,您可以使用Twilio或任何其他服务拨打电话或发送短信。
如果您想"轻松"将网站翻译成其他语言,请将所有文本存储在数据库中,并根据用户的语言偏好提取正确的版本。
根据答案,我会做以下事情:
数据库表:
+------------------------------------------------------------+
| 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
作为首选语言。
认为这应该涵盖所有需求 - 但如果有人发现其中存在问题或有想法/意见:如果我能改进这个解决方案,我会很高兴:)