【问题标题】:How to remove unique constraint in MySQL?如何删除 MySQL 中的唯一约束?
【发布时间】:2021-08-03 13:48:42
【问题描述】:

我在网上搜索了关于如何在网上删除MySQL中唯一约束的方法,我找到了很多解决方案。

  1. DROP INDEX index_name ON table_name;
    
  2. ALTER TABLE table_name
    DROP INDEX index_name;
    
  3. ALTER TABLE table_name
    DROP CONSTRAINT constraint_name; 
    

所有这些查询之间有什么区别?这些查询中的哪一个符合标准 SQL?

另外,唯一约束、唯一索引和唯一键有什么区别?

【问题讨论】:

  • @Dorvalla 您提供的链接是关于 SQL Server 的。我说的是 MySQL。

标签: mysql indexing constraints unique-constraint alter-table


【解决方案1】:

许多 SQL 用户没有意识到索引不在 SQL 标准中。

继续,尝试在 ANSI/ISO SQL 规范中查找 CREATE INDEX、DROP INDEX 或任何其他相关的索引语法。

约束在规范中。以下是“SQL-99,完整,真正”一书的在线版本中 UNIQUE CONSTRAINT 的报道链接

UNIQUE 约束描述了对给定表执行的 INSERT/UPDATE/DELETE 操作行为的逻辑限制。也就是说,在约束中命名的唯一列中,任何两行都不能具有相同的非 NULL 值。

但索引是一个实现细节,SQL 标准将实现细节留给供应商。

碰巧添加索引数据结构是使约束的实现有希望高效的最常见方法。所以几乎所有的 SQL 供应商都有类似的功能,他们用必要的语句和子句扩展 SQL 语法以支持索引。

坦率地说,供应商之间的索引语法如此相似是一个奇迹。这给用户一种印象,即供应商正在遵守 SQL 标准的某些部分。他们不是;他们只是在模仿早期的实现。


你的评论:

这两个查询完成了同样的事情。语义上没有区别,只有语法。

DROP INDEX index_name ON table_name;

ALTER TABLE table_name
DROP INDEX index_name;

例如,使用 ALTER TABLE,您可以将删除索引与同一张表上的其他更改操作结合起来,例如删除多个索引、创建新索引或任何其他更改。

但是 DROP INDEX 只允许你在一张表上删除一个索引。

然后第三个查询删除一个约束。约束不是索引。

ALTER TABLE table_name
DROP CONSTRAINT constraint_name; 

这可能会产生删除索引的效果,但不一定。这取决于您要删除的约束类型。例如,删除 UNIQUE 约束会隐式删除与该约束关联的索引。而删除 FOREIGN KEY 或 CHECK 约束不会删除同一列上的索引。

【讨论】:

  • 感谢您对 SQL 标准部分的解释。能否请您解释一下这三个查询的区别以及唯一约束、唯一索引和唯一键的区别?
  • 感谢您的信息。请参阅此fiddle。为了删除唯一约束,ALTER TABLE .. DROP CONSTRAINTALTER TABLE .. DROP INDEX 在 MySQL 8.0 中删除了唯一约束。如果约束不是索引,那么为什么 ALTER TABLE .. DROP INDEX 会删除唯一约束?顺便说一句,ALTER TABLE .. DROP CONSTRAINT 在 5.0 中不起作用。为什么会这样?
  • UNIQUE KEY 在 MySQL 中作为索引实现。请理解,每个品牌的 SQL 数据库都有自己的实现,这必然与 SQL 标准中的理论定义有所不同。在像 5.0 这样的早期版本中(我们写这篇文章的 15 年前),他们根本还没有编写代码来支持 DROP CONSTRAINT 语法。
【解决方案2】:
DROP INDEX index_name ON table_name;

ALTER TABLE table_name
DROP INDEX index_name;

完全一样。此外,第一个查询实际上映射到第二个查询。


ALTER TABLE table_name
DROP CONSTRAINT constraint_name; 

执行另一个功能。

索引是表中的一个结构。 DROP INDEX 删除索引(对不起..)。

约束是表内的一个规则,这个规则可以伴随着相应的索引创建来维护约束。 DROP CONSTRAINT 放弃约束。但是,如果创建了用于维护的索引,则不会删除该索引。见fiddle

【讨论】:

  • 感谢您阐明索引和约束之间的区别。请解释一下 UNIQUE 约束的情况。
  • @RandomPerson 请解释一下 UNIQUE 约束的情况。 UNIQUE CONSTRAINT 不存在。这是指定唯一索引名称的另一种形式。请参阅fiddle - 声明了唯一约束,但在表结构中没有创建约束,它映射到创建唯一索引。但如果同时指定了约束名称和索引名称,则首选后者。
  • 看到这个fiddle
  • @RandomPerson 我没有看到 约束。我看到唯一索引。他们的混合是错误的想法。见fiddle。注意 - 允许名称干扰,因此索引名称和约束符号是两个不同的名称区域。 IE。服务器区分索引和约束。
  • 请参考my answer。我引用了 MySQL 文档中的一些文本,这将使事情更清楚。
【解决方案3】:

从 MySQL 8.0.19 开始,ALTER TABLE 允许使用更通用(和 SQL 标准)语法来删除和更改任何类型的现有约束,其中约束类型由约束名称确定:

  • 删除一个名为符号的现有约束:
    ALTER TABLE tbl_name
        DROP CONSTRAINT symbol;
    

Source

SQL 标准规定所有类型的约束(主键、唯一索引、外键、检查)属于同一个命名空间。在 MySQL 中,每个约束类型的每个模式都有自己的命名空间。因此,每个模式的每种约束类型的名称必须是唯一的,但不同类型的约束可以具有相同的名称。当多个约束同名时,DROP CONSTRAINTADD CONSTRAINT 不明确,会出现错误。在这种情况下,必须使用特定于约束的语法来修改约束。例如,使用 DROP PRIMARY KEY 或 DROP FOREIGN KEY 删除主键或外键。
Source

所以,从技术上讲,在 MySQL 8.0.19 或更高版本上,我们可以使用 ALTER TABLE tbl_name DROP CONSTRAINT constraint_name 来删除 UNIQUE 约束。但是,如果某些其他约束与 UNIQUE 约束具有相同的名称,则此方法将不起作用。在这种情况下,我们必须使用ALTER TABLE tbl_name DROP INDEX index_nameDROP INDEX index_name ON tbl_name 来移除UNIQUE 约束。

ALTER TABLE tbl_name DROP INDEX index_nameDROP INDEX index_name ON tbl_name 之间的区别已在this answer 中进行了说明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-13
    • 2023-03-22
    • 2015-05-07
    • 2012-05-11
    • 2012-09-02
    • 1970-01-01
    • 2014-09-12
    • 2020-12-09
    相关资源
    最近更新 更多