MySQL主键和外键使用及说明

本文详细介绍了MySQL中如何使用外键约束确保数据的完整性和一致性,包括外键的使用条件、定义语法及实际操作示例。

一、外键约束

      MySQL通过外键约束来保证表与表之间的数据的完整性和准确性。

 外键的使用条件:
    1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持);
   2.外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显示建立; 
   3.外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以;

          外键的好处:可以使得两张表关联,保证数据的一致性和实现一些级联操作;

外键的定义语法:

 语法详解

简单演示一下使用,做dage和xiaodi两个表,大哥表是主键,小弟表是外键

建表:

复制代码

 1CREATE TABLE `dage` (
 2  `id` int(11) NOT NULL auto_increment,
 3  `name` varchar(32) default '',
 4  PRIMARY KEY  (`id`))
 5  ENGINE=InnoDB DEFAULT CHARSET=latin1;
 6
 7CREATE TABLE `xiaodi` (
 8  `id` int(11) NOT NULL auto_increment,
 9  `dage_id` int(11) default NULL,
10  `name` varchar(32) default '',
11  PRIMARY KEY  (`id`),
12  KEY `dage_id` (`dage_id`),
13  CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)
14) ENGINE=InnoDB DEFAULT CHARSET=latin1;

复制代码

插入个大哥:

复制代码

1mysql> insert into dage(name) values('铜锣湾');
2Query OK, 1 row affected (0.01 sec)
3mysql> select * from dage;
4+----+--------+
5| id | name   |
6+----+--------+
7|  1 | 铜锣湾 |
8+----+--------+
91 row in set (0.00 sec)

复制代码

插入个小弟:

复制代码

1mysql> insert into xiaodi(dage_id,name) values(1,'铜锣湾_小弟A');
2Query OK, 1 row affected (0.02 sec)
3
4mysql> select * from xiaodi;
5+----+---------+--------------+
6| id | dage_id | name         |
7+----+---------+--------------+
8|  1 |       1 | 铜锣湾_小弟A |
9+----+---------+--------------+

复制代码

把大哥删除:

1mysql> delete from dage where id=1;
2ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`bstar/xiaodi`, CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`))

提示:不行呀,有约束的,大哥下面还有小弟,可不能扔下我们不管呀!

插入一个新的小弟:

1mysql> insert into xiaodi(dage_id,name) values(2,'旺角_小弟A');              
2ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`bstar/xiaodi`, CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`))
3

提示:小子,想造反呀!你还没大哥呢!

把外键约束增加事件触发限制:

复制代码

1mysql> show create table xiaodi;
 2
 3  CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)
 4
 5mysql> alter table xiaodi drop foreign key xiaodi_ibfk_1; 
 6Query OK, 1 row affected (0.04 sec)
 7Records: 1  Duplicates: 0  Warnings: 
 8mysql> alter table xiaodi add foreign key(dage_id) references dage(id) on delete cascade on update cascade;
 9Query OK, 1 row affected (0.04 sec)
10Records: 1  Duplicates: 0  Warnings: 0

复制代码

再次试着把大哥删了:

复制代码

1mysql> delete from dage where id=1;
2Query OK, 1 row affected (0.01 sec)
3
4mysql> select * from dage;
5Empty set (0.01 sec)
6
7mysql> select * from xiaodi;
8Empty set (0.00 sec)

复制代码

哎呦,这回对应的小弟也没了,没办法,谁让你跟我on delete cascade(级联限制)了呢!

<think>嗯,用户想了解如何在MySQL中创建主键的SQL语句。好的,我需要先回忆一下相关的知识,然后根据提供的引用内容来整理答案。 首先,主键是用于唯一标识表中每一行的列或列组合,而则用于建立两个表之间的关联。根据引用[1],创建主键可以在创建表时定义,或者在已有表上添加。比如在CREATE TABLE的时候使用PRIMARY KEY关字,或者在现有表上通过ALTER TABLE添加。比如引用[3]中提到,使用ALTER TABLE users ADD PRIMARY KEY (user_id)来添加主键。 然后是,引用[4]中提到,可以在创建表时定义FOREIGN KEY,并指定REFERENCES父表的列。或者在已有表上使用ALTER TABLE添加约束。例如,在创建子表时,FOREIGN KEY (parent_id) REFERENCES parent_table(id)。还有引用[5]提到,如果原有主键需要删除,可以使用ALTER TABLE DROP PRIMARY KEY,然后再添加新的主键。 用户可能需要具体的示例,所以应该给出创建表时修改表时的SQL语句。比如在创建表时如何设置主键,包括单字段主键复合主键部分也需要说明在创建表时之后如何添加,并且注意约束的选项,如ON DELETEON UPDATE。 还需要注意自增属性,主键通常自增一起使用,比如使用AUTO_INCREMENT,这在引用[1][4]中都有提到。例如,id INT AUTO_INCREMENT PRIMARY KEY。 用户可能遇到的问题包括如何删除原有主键,这在引用[5]中提到,需要用ALTER TABLE DROP PRIMARY KEY。但需要注意,如果原有主键是自增的,可能需要先修改列属性,再删除主键,不过这可能超出当前问题的范围,但可以简要提及。 另需要确保父表的列存在索引,并且存储引擎是InnoDB,否则可能不支持约束。这点可能在引用中没有提到,但根据MySQL的知识,需要补充说明,以避免用户在使用时出现错误。 总结一下,回答的结构应该分为创建主键创建两部分,每部分再分为创建表时修改已有表两种情况,并给出示例。同时,注意事项也需要提到,比如存储引擎、索引、约束条件等。 现在需要检查是否有遗漏的引用内容,比如引用[2][3]可能提供其他信息,但根据内容,引用[3]提到添加主键的方法,引用[4][5]涉及的创建修改。需要确保所有相关的操作都有覆盖,比如删除主键的步骤,但用户的问题主要是创建,所以可能不需要详细展开删除部分,除非必要。 最后,生成相关问题,可能需要包括主键的区别、如何删除、性能影响、修改约束等,这些可以帮助用户进一步学习。</think>### MySQL主键创建方法 #### 一、主键创建方法 主键用于唯一标识表中的每一条记录,**创建方式分为建表时定义后期添加**: 1. **建表时定义主键** - 单字段主键: ```sql CREATE TABLE users ( user_id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL ); ``` - 复合主键(多字段组合): ```sql CREATE TABLE orders ( order_id INT, product_id INT, PRIMARY KEY (order_id, product_id) ); ``` 2. **已有表添加主键** ```sql ALTER TABLE employees ADD PRIMARY KEY (emp_id); ``` **注意**:若表已有主键需先删除原主键[^5]: ```sql ALTER TABLE jingyan DROP PRIMARY KEY; ``` #### 二、创建方法 用于关联两个表的数据,**需确保父表存在对应主键使用InnoDB引擎**: 1. **建表时定义** ```sql CREATE TABLE orders ( order_id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE ); ``` 2. **已有表添加** ```sql ALTER TABLE orders ADD FOREIGN KEY (user_id) REFERENCES users(user_id); ``` #### 三、核心注意事项 1. **自增属性**:主键常配合`AUTO_INCREMENT`实现自动编号[^1] 2. **约束条件**: - `ON DELETE CASCADE`:父表记录删除时自动删除子表关联记录 - `ON UPDATE CASCADE`:父表主键更新时同步更新子表 3. **引擎限制**:仅InnoDB引擎支持约束[^4] 4. **索引要求**:字段会自动创建索引以提高查询效率 $$ \text{关系公式:} \boxed{\text{子表.字段} \subseteq \text{父表.主键字段}} $$
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值