您是否有理由想在TABLE中拥有多个KEY?在一个表中有多个KEY有什么意义?
以下是我发现的一个例子:
CREATE TABLE orders(
id INT UNSIGNED NOT NULL AUTO INCREMENT,
user_id INT UNSIGNED NOT NULL,
transaction_id VARCHAR(19) NOT NULL,
payment_status VARCHAR(15) NOT NULL,
payment_amount DECIMAL(15) NOT NULL,
payment_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(id),
KEY(user_id),
)
另外,您会注意到DBase程序员没有transaction_id
成为KEY
。有这个原因吗?
答案 0 :(得分:4)
有几个可能的原因。
这些是最常见的原因。
答案 1 :(得分:4)
KEY
是“索引”的替代语法
索引在数据库中很常见,但它们尚未涵盖ANSI - 它的纯粹奇迹就像它们一样相似。将一个以上的索引与表关联起来是很常见的 - 因为索引会以更新/删除/插入速度为代价来改进数据检索。
请注意,如果某个表的主键尚不存在,MySQL(5.x?)会自动创建索引。
答案 2 :(得分:3)
在SQL中,每个表可能只有一个PRIMARY KEY
。
KEY(foo)
是标准SQL中的伪造语法。在MySQL KEY foo
中,INDEX foo
是一个命名不佳的同义词,并没有强制使用UNIQUE约束。 (名称很差,因为它实际上与密钥的功能无关。)
可能有多个UNIQUE INDICES
可以扮演“候选键”的角色。 (可以在没有关联的INDEX的情况下指定唯一约束,但“键”的点通常是快速查找。)PRIMARY KEY
的点是唯一标识单个记录,几乎完全由INDEX支持,甚至可能与数据的聚类直接相关。
只应使用确保数据有效性和满足性能要求所需的最少量[唯一] INDICES - 它们也会对查询引擎造成性能损失因为有额外的更新和维护费用。
非唯一 INDEX(INDEX foo
,或者在MySQL的情况下,KEY foo
)纯粹是为了允许数据库优化查询。它们确实映射到“密钥”,可能被称为“覆盖索引”;如果由查询规划器选择,这些索引可以帮助提高性能,即使它们不向逻辑模型本身添加任何内容。 (出于性能原因,数据库引擎可能要求索引覆盖FOREIGN KEYS。)
在这种情况下,在user_id
上创建一个INDEX(不认为“KEY”!)通常会(大大)加速查询,例如:
... WHERE user_id = {somenumber}
如果没有INDEX,上述查询将需要一个完整的表扫描(例如,读取所有记录)。
虽然我不知道为什么transaction_id
没有成为索引,但可能不需要(甚至对给定的访问模式有害) - 考虑每个查询都需要快速:
transaction_id
或; user_id = ...
或其他可以使用INDEX的限制。也就是说,在类似WHERE user_id = ... AND transaction_id = ...
的情况下,查询计划程序可能首先找到匹配用户的记录 ,然后查找匹配的transaction_id
- 它仍然需要进行扫描,但只能在原始表的小得多的数据集上进行。只有普通的WHERE transaction_id = ...
才需要进行全表扫描。如果有疑问,请使用EXPLAIN - 或其他query analyzer - 并查看MySQL 认为应该做什么。作为最后一点,有时估计的查询执行计划可能与实际执行计划不同,过时的统计信息可以使查询计划程序选择一个非理想的计划。
快乐的编码。
答案 3 :(得分:0)
答案 4 :(得分:0)
在数据库理论中,关键是强制唯一性的约束。 relvar(类似于SQL表)可能确实具有多个候选键。一个典型的例子是化学元素的集合,其名称,符号,原子序数和原子量都是键(民间仍然希望为它添加自己的代理键;)
MySQL通过将KEY
的同义词作为INDEX
的同义词,继续滥用单词transaction_id
。显然,MySQL表可能具有在给定情况下对性能所必需的索引数量。
从你的SQL DDL中可以清楚地看出,ID是一个代理键,所以我们必须寻找一个没有太多的自然键。虽然user_id
可能是候选人,但订单可能涉及多个交易并不是不可想象的。实际上,我认为审核员会怀疑同一个用户同时发出的多个订单,因此建议payment_time
和transaction_id
的复合应该是关键。但是,如果transaction_id
不是密钥,那么该表将不会完全规范化。因此,我会给设计师带来疑问,并假设{{1}}也是关键。