满腔热血空悲切 發表於 2025-5-14 14:35:01

SQL 外键Foreign Key全解析

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1. 什么是外键?​​ ​​</a></li><li><a href="#_label1">​​2. 外键的语法​​</a></li><li><a href="#_label2">​​3. 外键的约束行为​​</a></li><li><a href="#_label3">​​4. 多列外键​​</a></li><li><a href="#_label4">​​5. 外键的限制与注意事项​​ ​​</a></li><li><a href="#_label5">​​6. 实际应用示例​​</a></li><li><a href="#_label6">​​7. 常见问题​​</a></li><li><a href="#_label7">​​8. 总结​​ ​​</a></li></ul></div><p class="maodian"><a name="_label0"></a></p><h2>1. 什么是外键?​​ ​<strong>​</strong></h2>
<ul><li>定义​​:外键是数据库表中的一列(或一组列),用于​​建立两个表之间的关联关系​​。外键的值必须匹配另一个表的主键(Primary Key)或唯一约束(Unique Constraint)的值。</li><li>​​作用​​:<ul><li>确保数据的​​引用完整性​​(Referential Integrity),防止无效数据插入。</li><li>维护表之间的逻辑关系(如&ldquo;一对多&rdquo;或&ldquo;多对多&rdquo;)。</li></ul></li></ul>
<p class="maodian"><a name="_label1"></a></p><h2>​​2. 外键的语法​​</h2>
<p>在创建表时定义外键:</p>
<div class="jb51code"><pre class="brush:sql;">CREATE TABLE 子表 (
    列1 数据类型,
    列2 数据类型,
    ...
    FOREIGN KEY (外键列) REFERENCES 父表(主键列)
   
);</pre></div>
<p>在已有表中添加外键:</p>
<div class="jb51code"><pre class="brush:sql;">ALTER TABLE 子表
ADD CONSTRAINT 约束名称
FOREIGN KEY (外键列) REFERENCES 父表(主键列)
;</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>​​3. 外键的约束行为​​</h2>
<p>当父表的记录被删除或更新时,子表的外键如何处理?通过&nbsp;<code>ON DELETE</code>&nbsp;和&nbsp;<code>ON UPDATE</code>&nbsp;指定:</p>
<table><thead><tr><th>约束行为</th><th>说明</th></tr></thead><tbody><tr><td>​<strong>​CASCADE​</strong>​</td><td>级联操作。父表删除/更新记录时,子表关联记录也被删除/更新。</td></tr><tr><td>​<strong>​SET NULL​</strong>​</td><td>父表删除/更新记录时,子表的外键列设为 NULL(要求外键列允许 NULL)。</td></tr><tr><td>​<strong>​NO ACTION​</strong>​</td><td>默认行为。阻止父表的删除/更新操作,如果子表存在关联记录。</td></tr><tr><td>​<strong>​RESTRICT​</strong>​</td><td>类似 <code>NO ACTION</code>,立即检查约束。</td></tr><tr><td>​<strong>​SET DEFAULT​</strong>​</td><td>父表删除/更新记录时,子表的外键设为默认值(需定义默认值)。</td></tr></tbody></table>
<p class="maodian"><a name="_label3"></a></p><h2>​​4. 多列外键​​</h2>
<p>外键可以由多个列组成,需满足:</p>
<ul><li>子表和父表的列数、顺序、数据类型一致。</li><li>父表的列必须有唯一约束(如主键或唯一索引)。</li></ul>
<p>​<strong>​示例​</strong>​:</p>
<div class="jb51code"><pre class="brush:sql;">CREATE TABLE 订单详情 (
    订单ID INT,
    产品ID INT,
    数量 INT,
    PRIMARY KEY (订单ID, 产品ID),
    FOREIGN KEY (订单ID) REFERENCES 订单(订单ID),
    FOREIGN KEY (产品ID) REFERENCES 产品(产品ID)
);</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>​​5. 外键的限制与注意事项​​ ​<strong>​</strong></h2>
<ul><li><strong>父表必须有主键或唯一约束​</strong>​。</li><li>​<strong>​外键列的数据类型必须与父表主键一致​</strong>​。</li><li>​<strong>​引擎支持​</strong>​:如 MySQL 的 InnoDB 支持外键,而 MyISAM 不支持。</li><li>​<strong>​性能影响​</strong>​:外键会增加数据操作的检查开销,但能提升数据一致性。</li><li>​<strong>​循环依赖​</strong>​:避免两个表互相引用。</li></ul>
<p class="maodian"><a name="_label5"></a></p><h2>​​6. 实际应用示例​​</h2>
<p>​<strong>​场景​</strong>​:学生表(<code>students</code>)和课程表(<code>courses</code>),通过选课表(<code>enrollments</code>)关联。</p>
<div class="jb51code"><pre class="brush:sql;">-- 父表:学生表
CREATE TABLE students (
    student_id INT PRIMARY KEY,
    name VARCHAR(50)
);
-- 父表:课程表
CREATE TABLE courses (
    course_id INT PRIMARY KEY,
    course_name VARCHAR(50)
);
-- 子表:选课表(含外键)
CREATE TABLE enrollments (
    student_id INT,
    course_id INT,
    enrollment_date DATE,
    FOREIGN KEY (student_id) REFERENCES students(student_id) ON DELETE CASCADE,
    FOREIGN KEY (course_id) REFERENCES courses(course_id) ON DELETE RESTRICT
);</pre></div>
<p>​<strong>​插入数据​</strong>​:</p>
<div class="jb51code"><pre class="brush:sql;">-- 插入学生和课程
INSERT INTO students VALUES (1, 'Alice');
INSERT INTO courses VALUES (101, 'Math');
-- 合法插入:学生和课程存在
INSERT INTO enrollments VALUES (1, 101, '2023-10-01');
-- 非法插入:学生不存在,触发外键错误
INSERT INTO enrollments VALUES (999, 101, '2023-10-01'); -- 报错!</pre></div>
<p class="maodian"><a name="_label6"></a></p><h2>​​7. 常见问题​​</h2>
<p>​<strong>​外键必须指向主键吗?​</strong>​<br />不,可以指向父表的唯一约束(Unique Constraint)。</p>
<p>​<strong>​能否跨数据库引用?​</strong>​<br />通常不支持,外键需在同一数据库内。</p>
<p>​<strong>​外键是否允许 NULL?​</strong>​<br />如果外键列允许 NULL,则插入 NULL 是合法的(表示无关联)。</p>
<p>​<strong>​如何查看外键约束?​</strong>​<br />使用数据库工具或查询元数据(如 MySQL 的&nbsp;<code>SHOW CREATE TABLE</code>)。</p>
<p class="maodian"><a name="_label7"></a></p><h2>​​8. 总结​​ ​<strong>​</strong></h2>
<ul><li><strong>外键的核心作用​</strong>​:维护数据的一致性和关联性。​<strong>​</strong></li><li><strong>适用场景​</strong>​:需要强数据完整性的系统(如电商、金融)。​<strong>​</strong></li><li><strong>慎用场景​</strong>​:高并发写入且对性能要求极高的系统(需权衡一致性与性能)。</li></ul>
頁: [1]
查看完整版本: SQL 外键Foreign Key全解析