【问题标题】:database: best practice countries, country codes, country phone codes数据库:最佳实践国家、国家代码、国家电话代码
【发布时间】:2018-10-16 11:27:53
【问题描述】:

如果您将国家/地区代码存储在数据库中但找不到“这是正确的方法”,我正在寻找“最佳做法”。我想存储 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。

【问题讨论】:

  • 如果一个国家可以有多个代码,那么设计是正确的。现在关于语言:我没有看到需要翻译的东西,我相信国家缩写在语言方面是相同的
  • 翻译的意思是如果我想翻译我的应用程序(不是国家代码 - 它们总是相同的,是的)
  • 请记住,国家可以有多种语言,例如比利时使用荷兰语、法语和德语。
  • @RaymondNijland 这正是我正在寻找的:如何处理我需要的所有信息,而无需在数据库中提供太多信息。
  • 那么翻译应该在一个单独的问题中

标签: php mysql laravel laravel-5 internationalization


【解决方案1】:

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

电话号码的标准化程度要低得多。 ITU 提供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

【讨论】:

    【解决方案2】:

    我的数据库如下所示:

    > 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) 从 DB 中添加德国 (49) 的代码。您会得到 49451112233。如果您愿意,请添加“+”。

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

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

    【讨论】:

      【解决方案3】:

      根据答案,我将执行以下操作:

      数据库表:

      +------------------------------------------------------------+
      | 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 作为首选语言。

      认为这应该涵盖所有需求 - 但如果有人看到其中的问题或有想法/cmets:如果我能改进这个解决方案,我会很高兴:)

      【讨论】:

      • 表 country_languages 和 country_phonecodes 不需要自动增量 ID。您可以将 pk 与两列一起使用
      猜你喜欢
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 2016-06-11
      • 1970-01-01
      相关资源
      最近更新 更多