【问题标题】:Declaring MySQL PK as only Unique Key将 MySQL PK 声明为唯一的唯一键
【发布时间】:2014-09-05 03:26:20
【问题描述】:

如下表所示,在 Id 上创建 UNIQUE 索引是否足以使 id 成为主键?更具体地说,你能说下表有一个主键吗?

test` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`role` varchar(32) NOT NULL,
`resources_name` varchar(32) NOT NULL,
`access_name` varchar(32) NOT NULL,
`allowed` int(3) NOT NULL,
UNIQUE KEY `id` (`id`),
UNIQUE KEY `roles_name` (`role`,`resources_name`,`access_name`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8

你可以用什么查询来证明这有或没有PK?

【问题讨论】:

  • 主键被定义为主键。 UNIQUE KEYS 是候选项,但根据定义不是 PRIMARY KEY。

标签: mysql sql indexing primary-key


【解决方案1】:

从逻辑上讲,如果关系表中至少有一个候选键(最小唯一且不可为空),那么事实上它有一个“主”键。没有绝对需要使用特殊的“主”标签来挑出任何一个键,因为原则上所有键都是相等的(历史上,“主键”一词用于任何和所有候选键,而不仅仅是每个表的一个键)。

SQL 中有一个称为 PRIMARY KEY 约束的约束。从逻辑上讲,SQL PRIMARY KEY 只不过是语法糖,因为 NOT NULL UNIQUE 语法基本上实现了相同的目的。从技术上讲,PRIMARY KEY 约束不必与“主键”的关系概念指代相同的东西,但很明显,如果您要将任何一个键指定为主键,并且您认为需要一种语法方式来表示它选择,那么 PRIMARY KEY 约束是公认的方法。

所以也许最好的答案是“视情况而定”。这在很大程度上取决于您首先定义主键的动机。如果您打算为数据库的开发人员和用户挑出一个键,那么 NOT NULL UNIQUE 语法可能无法为您实现这一目标。如果您不需要使用 SQL 语法来执行此操作,那么 NOT NULL UNIQUE 可能与 PRIMARY KEY 约束一样是定义键的好方法。

【讨论】:

    【解决方案2】:

    这对于评论来说太长或太短:否。

    主键和唯一键——虽然相似——但并不相同。所以,你的表没有主键。最大的功能区别是主键不能是NULL,而唯一键可以是。

    主键通常也是集群的(如果底层存储引擎支持集群索引)。这意味着数据实际上是按照主键的顺序物理存储在页面上的。唯一键只是另一个索引,具有没有重复值的特点。

    编辑:

    有趣。 SHOW COLUMNSdocuments这种行为:

    如果 UNIQUE 索引不能包含 NULL,它可能会显示为 PRI 值,并且表中没有 PRIMARY KEY。

    我不知道这一点。

    【讨论】:

    • 但是当我运行 SQL 命令“SHOW COLUMNS FROM test”时,它实际上将 Id 显示为 PRI?
    • @TheGeorgia 。 . .也许 MySQL 将不可为空的唯一键视为主键。我不知道确实如此,但您的经验表明这是可能的。 (我总是直接将该列声明为主键。)
    • 但是因为它是auto_increment,这意味着它无论如何都不能包含空值。它保证总是有一个值。
    • 还有,声明AUTO_INCREMENT=32是什么意思,如上表所示是什么意思?
    • @TheGeorgia 。 . .这设置了列的初始值。
    猜你喜欢
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 2018-06-04
    • 2014-01-12
    相关资源
    最近更新 更多