我正在尝试在 MySQL 中设计一个电子商务 Web 应用程序,但在为用户表选择正确的主键时遇到问题。给出的示例只是用于说明的示例。
用户表有以下定义
CREATE TABLE IF NOT EXISTS `mydb`.`user` (
`id` INT NOT NULL ,
`username` VARCHAR(25) NOT NULL ,
`email` VARCHAR(25) NOT NULL ,
`external_customer_id` INT NOT NULL ,
`subscription_end_date` DATETIME NULL ,
`column_1` VARCHAR(45) NULL ,
`column_2` VARCHAR(45) NULL ,
`colum_3` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `username_UNIQUE` (`username` ASC) ,
UNIQUE INDEX `email_UNIQUE` (`email` ASC) ,
UNIQUE INDEX `customer_id_UNIQUE` (`external_customer_id` ASC) )
ENGINE = InnoDB
我在主键候选列方面面临以下问题:
标识列
优点
- 无业务意义(稳定主键)
- 更快的表连接
- 紧缩指数
缺点
- 不是“自然”键
- 所有属性表必须与“主”用户表连接,因此无法进行非连接直接查询
- 导致较少“自然”的 SQL 查询
- 泄漏信息:如果起始值为 0,则用户可以计算出注册用户的数量(更改起始值对此进行排序)ii)用户在 time_X 将配置文件注册为 user_A,稍后在 time_Y 注册为 user_B 将很容易计算一段时间内的注册用户数((用户 B 的 ID)-(用户 A 的 ID)/(时间_Y-时间_X))
电子邮件栏
优点
- 没有任何
缺点
- 用户应该能够更改电子邮件地址。不适合主键
用户名列
优点
- “自然”主键
- 更少的表连接
- 更简单、更“自然”的查询
缺点
- 连接表时 varchar 列速度较慢
- varchar 列上的索引不如 int 列索引紧凑
- 很难更改用户名,因为外键取决于值。解决方案:“同步”应用程序上的所有外键或不允许用户更改用户名,例如,用户应删除配置文件并注册新的
external_customer 列
优点
可以用作客户的外部参考并且不包含任何信息(也许可以使用不可编辑的用户名?)
缺点
如果它是自动增量的(如果可能),可能会泄漏信息
- 如果自动增量代理 id 已在使用中,则生成 unqiue 值是有问题的,因为 MySQL innodb 引擎在同一个表中没有多个 auto_increment 列
为可扩展的电子商务 Web 应用程序选择用户表主键时的常见做法是什么?所有反馈表示赞赏