【问题标题】:Creating a mixed number and letter primary key创建混合数字和字母的主键
【发布时间】:2019-06-23 09:03:01
【问题描述】:

我有一个在 mysql 服务器中复制的现有桌面数据库。当前数据库有一个客户表,其中一个字段代表公司服务的区域或区域。区域如下:1A、1B、2、3、4、5、6、7、8、9、10、11、12、13、14、15、16、17。

为了进行设置,为了匹配他们现有的数据集,我设置了一个参考表 (customer_zones),其中的区域以一对多的关系链接到客户表。每个区域可以有许多客户。每个客户只有一个区域。

问题是“1A”和“1B”区域不允许我在 customer_zones 表上设置 int 主键。我必须使用 varchar(2) 作为主键。这是好习惯吗?还是最好的解决方案?

【问题讨论】:

  • 不管怎样,听起来都不是什么“问题”。 FWIW,我会有一个代理,整数 PK。

标签: mysql database database-design mariadb


【解决方案1】:

主键是聚集索引,表中数据的物理表示是因为主键和搜索数字比字符串快。

根据您的情况,以下是方法。

方法 A

如果您为表customer_zones 中的主键字段选择区域ID 作为varchar(2),那么您可以将其引用到customer表中的外键字段,您的问题将得到解决。

方法 B

如果您在表customer_zone 中将主键用作integer,那么要存储1A、1B 等区域,您需要多一个字段,并且在该字段上,您需要一个唯一键也避免数据重复。

如果您遵循方法 A 会更好,因为对于相同的功能,一个约束会更简单。

【讨论】:

  • 使用方法 A:PRIMARY KEY(zone) 作为VARCHAR(2)。数据的清晰度远远超过了使用 int 而不是 varchars 的微不足道的性能差异。
  • 嗨 Rick,我们都建议使用方法 A,但我无法理解您提供的原因。我可以看到您在数据库方面拥有丰富的经验,如果您能帮助我理解这一点,我将不胜感激。
  • 是的,我在 MySQL/MariaDB 方面拥有大约 2 年的经验,其中大部分都专注于性能和扩展。 18 个“区域”组成了一张小桌子,但养成优化设计桌子的习惯是件好事。 (请参阅我的回答以解决您的问题。)
【解决方案2】:

我赞成PRIMARY KEY(zone)VARCHAR(2),而不是替代AUTO_INCREMENT

  • 查询所涉及的行数对性能的影响远大于算术/字符串比较/函数等的详细信息。
  • 即使有数百万行,“数字比字符串快”也不太可能引起注意。
  • 如果更改为代理需要额外的JOIN,那就是额外的开销。
  • 查看“1A”和“16”等更方便(手动查看数据时)。
  • 我发现 3 次中有 2 次我使用“自然”PRIMARY KEY,而不是“代理”(AUTO_INCREMENT)。对于多:多映射表,使用复合 PK 而不是代理项显然更有效。

我会建议在你的情况下这个小优化:

 VARCHAR(2) CHARACTER SET ascii

这避免了 utf8 的小开销。

我对 GUID、UUID、sha1、md5、ip_address、country_code、postal_code、zipcode 电话号码等提出了类似的论点。对于真正固定长度的字段,例如 2 个字母的 country_code,请使用 CHAR(2) 而不是 VARCHAR(2) .

【讨论】:

    猜你喜欢
    • 2011-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多