Mysql学习之constraint/key/primary key/unique/foreign key/constraint的关系

1.constraint就是约束的意思,在MySQL中约束的表现形式有:not null/ primary key/unique隐含有约束功能。

2.如果为一个字段创建了约束,除非这个字段是not null ,否则就是为了这个字段即创建了约束又创建了索引,也就是说primary key为主键创建了约束和索引,unique也是一样。

但是当primary key 与constraint 关键字搭配使用的时候,将会忽视constraint 所创建的约束名与索引,其约束名与索引名皆为primary,比如:create table jc_one (id int ,names varchar(10) ,primary key(id))和create table jc_one (id int ,names varchar(10) ,constraint   my_self_index primary key(id))执行结果是一样的,因此在使用primary key的时候就不需要使用constraint了。

而unique 则不一样,如果unique不与constraint 搭配使用,则约束与索引名都默认为字段名称,而当使用unique与constraint 配合使用时,其约束名称与索引名称结尾constraint定义的一样,create table jc_one (id int ,names varchar(10) ,unique(id))的约束名与索引为id,而create table jc_one (id int ,names varchar(10) ,constraint my_self_key unique (id))索引名与约束名都是my_self_key。

注:如何验证以上结论呢,在mysql下的有个information_schema的数据库,该数据库下有个table_constraints表与 STATISTICS表,这两张表里分别存放着数据库中所有表的约束名与索引名,所以我们可以通过查看这两个表的变化,去查看结果

3.key与index 一样,只创建索引,不创建约束

4.foreign key 是建立外键关系,其与constraint搭配使用也是一样的,当然如果你不使用constraint的话,数据库会自动为你生成一个默认的约束名称与索引名称。

<think>我们正在处理MySQL错误1553:无法删除主键索引,因为它被外键约束使用。这意味着我们试图删除的表的主键被其他表的外键引用,因此不能直接删除。 解决方案通常有两种思路: 1. 先删除所有引用该主键的外键约束,然后再删除主键索引,最后重新添加外键约束(如果需要的话)。 2. 修改外键约束引用的列(如果业务允许,可以修改外键引用到另一个唯一索引上,然后再删除主键)。 但是,需要注意的是,在MySQL中,外键约束必须引用被引用表的一个索引(通常是主键或唯一索引)。因此,如果我们想删除主键,必须确保没有外键约束引用它,或者我们为被引用的表提供一个替代的索引(唯一索引)供外键引用。 具体步骤: 方法一:删除外键约束,然后删除主键,再重新创建外键(如果需要) 步骤1:找出所有引用该主键的外键约束。 步骤2:删除这些外键约束。 步骤3:删除主键索引。 步骤4:如果需要,重新创建外键约束(但注意,此时被引用的列必须有一个唯一索引,因为主键被删除了,所以我们需要为这些列创建一个唯一索引,然后再创建外键)。 方法二:如果业务允许,我们可以修改引用表的外键列,使其引用另一个唯一索引(如果有的话),然后再删除主键。但通常,如果没有其他唯一索引,我们就需要先创建一个唯一索引。 然而,在删除主键之前,我们必须确保被引用的列上有一个唯一索引(因为外键要求被引用的列必须是索引且唯一)。所以,如果我们仍然需要外键关系,那么我们必须先创建一个唯一索引,然后修改外键约束引用这个新索引,或者先删除外键,删除主键,再创建唯一索引,最后重新添加外键。 但是,注意:在MySQL中,主键本身就是一个唯一索引。如果我们删除主键,那么该列上的唯一索引就没有了,因此外键约束就会失效。所以,我们必须先创建一个新的唯一索引来替代主键(如果业务允许没有主键,但通常表都需要主键,所以这种方法可能不常用)。 更常见的做法是: 1. 先删除所有引用该表主键的外键约束。 2. 删除该表的主键。 3. 然后为该表添加一个新的主键(或唯一索引)以满足外键引用的要求(如果需要继续使用外键)。 4. 重新添加外键约束。 然而,如果我们的目的是要删除主键并改变表结构(比如更换主键),那么我们需要按照上述步骤操作。 具体操作命令: 步骤1:查询引用该表主键的外键约束。 我们可以通过查询information_schema数据库中的表来获取这些信息。 ```sql SELECT TABLE_NAME, CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = 'your_table' AND REFERENCED_COLUMN_NAME = 'primary_key_column'; ``` 注意:将'your_table'替换为你的表名,'primary_key_column'替换为主键列名。 步骤2:删除外键约束。 对于每一个找到的外键约束,执行: ```sql ALTER TABLE `referencing_table` DROP FOREIGN KEY `constraint_name`; ``` 步骤3:删除主键。 ```sql ALTER TABLE `your_table` DROP PRIMARY KEY; ``` 步骤4:如果我们需要重新添加外键约束,那么我们必须确保被引用的列(原主键列)上有一个唯一索引(因为外键要求被引用的列必须是唯一索引)。如果我们不再需要外键,可以跳过。否则,我们可以先为原主键列添加一个唯一索引: ```sql ALTER TABLE `your_table` ADD UNIQUE INDEX `unique_index_name` (`primary_key_column`); ``` 然后重新添加外键约束: ```sql ALTER TABLE `referencing_table` ADD CONSTRAINT `constraint_name` FOREIGN KEY (`fk_column`) REFERENCES `your_table` (`primary_key_column`); ``` 但是,请注意:如果我们的目的是要删除主键并且不再使用该列作为唯一标识,那么重新添加唯一索引可能不是我们想要的。因此,需要根据业务需求调整。 另外,如果我们在删除主键后想要添加新的主键,那么可以直接添加新主键(新主键列会自动创建唯一索引),然后再将外键约束引用到新的主键上(如果外键需要引用新的主键列)。 重要提示:在操作之前,请确保备份数据,并在测试环境中验证。 根据引用[2]:InnoDB内部索引长度的限制,我们在创建新索引时要注意索引长度不要超过3072字节(组合索引的总长度)。 另外,根据引用[3]:在MySQL 8.0.22及以上版本,对授权表的DML操作(不修改)不会获取读锁,但我们的操作是DDL,所以需要谨慎,因为DDL操作可能会锁表。 因此,对于生产环境,建议在业务低峰期操作,并确保有回滚方案。 现在,我们生成相关问题。</think>### MySQL Error 1553 解决方案:无法删除主键索引(外键约束引用) #### 错误原因分析 当出现错误 `1553 - Cannot drop index 'PRIMARY' needed in foreign key constraint` 时,表示**其他表的外键约束正在引用当前表的主键索引**。在MySQL中,被外键引用的主键索引不能直接删除,因为这会破坏数据完整性约束[^1]。 #### 解决方案(分步操作) 1. **查找依赖的外键约束** ```sql SELECT TABLE_NAME, CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = 'your_table' -- 替换为你的表名 AND REFERENCED_COLUMN_NAME = 'primary_key_column'; -- 替换为主键列名 ``` 2. **临时禁用外键检查**(避免操作中断) ```sql SET FOREIGN_KEY_CHECKS = 0; ``` 3. **删除外键约束** ```sql ALTER TABLE child_table -- 替换为步骤1查到的子表名 DROP FOREIGN KEY fk_name; -- 替换为步骤1查到的约束名 ``` 4. **删除主键索引** ```sql ALTER TABLE your_table -- 你的表名 DROP PRIMARY KEY; ``` 5. **重建外键约束**(如需保留关联) ```sql ALTER TABLE child_table ADD CONSTRAINT new_fk_name -- 新约束名 FOREIGN KEY (fk_column) REFERENCES your_table(pk_column); -- 重新关联列 ``` 6. **恢复外键检查** ```sql SET FOREIGN_KEY_CHECKS = 1; ``` #### 关键注意事项 1. **索引长度限制**:若重建索引,需确保组合索引总长度 ≤ 3072字节(InnoDB限制)[^2] 2. **事务处理**:在MySQL 8.0+版本中,DDL操作可能隐式提交事务,需规划好操作顺序[^3] 3. **数据一致性**:删除主键前,确保子表外键数据不会成为"孤儿记录" 4. **权限要求**:需要 `ALTER` 权限和 `DROP` 权限 #### 替代方案 如果需保留主键但修改结构: 1. 创建新唯一索引 ```sql ALTER TABLE your_table ADD UNIQUE INDEX new_idx (columns); ``` 2. 将外键约束指向新索引 ```sql ALTER TABLE child_table DROP FOREIGN KEY fk_name, ADD FOREIGN KEY (fk_column) REFERENCES your_table(new_idx); ``` > **重要提示**:生产环境操作前务必备份数据,建议在维护窗口执行。 --- ### 相关问题 1. 如何查询MySQL中所有外键约束的依赖关系? 2. 修改主键时如何避免数据库锁表导致服务中断? 3. InnoDB和MyISAM在处理外键约束时有何根本区别? 4. 使用 `SET FOREIGN_KEY_CHECKS=0` 可能存在哪些数据风险? 5. MySQL 8.0版本在外键约束管理上有哪些重要改进? [^1]: 主键索引被外键引用时无法直接删除,需先解除约束 [^2]: InnoDB组合索引最大长度限制为3072字节 [^3]: DDL操作可能触发隐式提交,影响事务完整性
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值