inf*_*oop 7 mysql database-design primary-key surrogate-key
我试图在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
Run Code Online (Sandbox Code Playgroud)
我正面临主键候选列的以下问题:
Id列
优点
缺点
电子邮件列
优点
缺点
用户名栏
优点
缺点
external_customer列
利弊
可以用作客户的外部参考并且不保留任何信息(可能会使用不可编辑的用户名?)
缺点
如果是自动增量(如果可能),可能会泄漏信息
为可伸缩电子商务Web应用程序选择用户表主键时的常见做法是什么?所有反馈意见
Mik*_*ll' 11
我对你的一些分析没什么可说的.如果我削减了你的一些优点或缺点,那只意味着我认为我没有任何有用的东西可以添加.
Id列
优点
- 没有商业意义(稳定的主键)
- 更快的表连接
- 压缩指数
首先,声明为NOT NULL UNIQUE的任何列或列集都具有主键的所有属性.您可以将它们中的任何一个用作外键引用的目标,这就是所有这一切的真正含义.
在您的情况下,您的结构允许4列成为外键引用的目标:id,username,email和external_customer_id.您没有使用相同的一个所有的时间.为90%的FK引用使用id可能是有意义的,并通过电子邮件发送10%的FK引用.
稳定性与列是否具有商业含义无关.稳定性与价值可能发生变化的频率和在何种情况下有关.除非你运行Oracle,否则"稳定"并不意味着"不可变".(Oracle无法执行ON UPDATE CASCADE.)
根据您的表结构和索引,自然键可能会执行得更快.自然键使一些连接不必要.在构建生产数据库之前,我做过测试.我们可能需要几十年时间才能达到连接ID号码的能力将超过更少的连接和自然键.我已经在SO或DBA上写过这些测试.
您还有其他三个唯一索引.(对你有好处.我认为构建数据库的人中至少有90%没有那么正确.)因此,ID号的索引不仅比这三者中的任何一个更紧凑; 它也是一个额外的指数.(在此表中.)
电子邮件列
优点
- 没有
电子邮件地址可以被认为是稳定且独特的.您无法阻止人们共享电子邮件地址,无论它是否是外键引用的目标.
但电子邮件地址可能会"丢失".在美国,大多数大学生在毕业一年左右时会丢失他们的*.edu电子邮件地址.如果您的电子邮件地址来自您正在支付的域名,并且您停止付款,则电子邮件地址会消失.我想像这样的电子邮件地址可能会被提供给新用户.这是否造成难以忍受的负担取决于应用程序.
缺点
- 用户应该能够更改电子邮件地址.不适合主键
可以更改SQL数据库中的所有值.如果您的环境不允许您的dbms及时授予ON UPDATE CASCADE声明,那么它是不合适的.我的环境呢.(但我在体面的非共享硬件上运行PostgreSQL.)YMMV.
用户名栏
优点
- 一个"自然的"主键
- 减少表连接
- 更简单,更"自然"的查询
更少的联接是重要的一点.我一直在咨询演出,在那里我看到盲目使用ID号码让人们用40多个连接编写查询.明智地使用自然键消除了高达75%的自然键.
始终使用代理键作为外键的目标(除非是Oracle)或始终使用自然键作为目标并不重要.思考很重要.
缺点
- 连接表时varchar列较慢
- varchar列上的索引比int列索引更紧凑
你无法真正说明加入varchar()的速度较慢而没有对该声明进行限定.事实是,尽管大多数联接在VARCHAR()是不是加入的ID号慢,他们未必就这么慢,你可以不使用它们.如果查询需要4ms的id号,6ms的varchar(),我认为这不是取消varchar()资格的好理由.此外,使用自然键将消除大量连接,因此整体系统响应可能更快.(在其他条件相同的情况下,40个4ms的连接将表现不到10个6ms连接.)
我记不起我的数据库事业(25年以上)中的任何情况,其中索引的宽度是选择外键目标的决定性因素.
external_customer列
利弊
- 可以用作客户的外部参考并且不保留任何信息(可能会使用不可编辑的用户名?)
实际上很少有系统允许我更改用户名.大多数人会让我改变我的真实姓名(我认为),但不是我的用户名.我认为不可编辑的用户名是完全合理的.
| 归档时间: |
|
| 查看次数: |
2653 次 |
| 最近记录: |