MySQL术语“;“限制”;vs";外键“;区别?

MySQL术语“;“限制”;vs";外键“;区别?,mysql,foreign-keys,constraints,ddl,Mysql,Foreign Keys,Constraints,Ddl,我正在查看MySQL文档,并试图理清外键和约束之间的区别。我认为FK是一个约束,但文档似乎把它们当作独立的东西来谈论 创建FK的语法是(部分) 所以“CONSTRAINT”子句是可选的。为什么要包括它或不包括它?如果不使用它,MySQL会创建外键而不是约束吗?或者更像是“约束”只不过是您FK的一个名称,所以如果您不指定它,您会得到一个匿名FK 如有任何澄清,将不胜感激 谢谢 Ethan无法回答MySQL的问题,但FK是约束条件。任何迫使数据进入特定条件的行为都是一种约束。有几种约束,唯一、主键、

我正在查看MySQL文档,并试图理清外键和约束之间的区别。我认为FK是一个约束,但文档似乎把它们当作独立的东西来谈论

创建FK的语法是(部分)

所以“CONSTRAINT”子句是可选的。为什么要包括它或不包括它?如果不使用它,MySQL会创建外键而不是约束吗?或者更像是“约束”只不过是您FK的一个名称,所以如果您不指定它,您会得到一个匿名FK

如有任何澄清,将不胜感激

谢谢


Ethan无法回答MySQL的问题,但FK是约束条件。任何迫使数据进入特定条件的行为都是一种约束。有几种约束,唯一、主键、检查和外键都是约束。也许MySQL还有其他的


有时命令中允许使用单词,但为了可读性,如DELETE语句中的FROM,不需要使用这些单词。

是的,外键是一种约束类型。MySQL对约束的支持不均衡:

  • 主键
    :是作为表约束和列约束
  • 外键
    :是作为表约束,但仅适用于InnoDB和BDB存储引擎;否则将被解析但忽略
  • 检查
    :已在所有存储引擎中解析但被忽略
  • 唯一性
    :是作为表约束和列约束
  • 非空
    :列约束为“是”
  • 可延迟
    和其他约束属性:不支持
CONSTRAINT
子句允许您显式命名约束,以使元数据更可读,或者在您想要删除约束时使用该名称。SQL标准要求
约束
子句是可选的。如果不使用它,RDBMS会自动创建一个名称,名称取决于实现。

通常(不需要MySQL),外键是约束,但约束并不总是外键。考虑主键约束、唯一约束等


回到具体问题,您是正确的,省略约束[symbol]部分将创建一个具有自动生成名称的FK。

这可能是MySQL中最令人困惑的topìc

许多人说,例如,“主键”、“外键”和“唯一”键实际上是索引!(此处包含MySQL官方文档)

另一方面,许多其他人说它们是约束(这是有道理的,因为当您使用它们时,实际上是在对受影响的列施加限制)

如果它们真的是索引,那么使用约束子句为其命名有什么意义,因为您应该能够在创建索引时使用该索引的名称

例如:

。。。外键索引名称(列名称1,列名称2,…)

如果外键是索引,那么我们应该能够使用索引名称来处理它。但是,我们不能

但如果它们不是索引,而是实际的约束,使用索引工作,那么这是有意义的


无论如何,我们都不知道。实际上,似乎没有人知道。

如果我没有错的话,约束需要索引,因此当您创建一个外键约束时,MySQL也会自动创建一个索引。

到目前为止,我们的创建表DDL是这种格式的-请注意我们使用的唯一键和外键定义语法

CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY,
    account_nbr INT NOT NULL,
    account_name VARCHAR(50) NOT NULL,
    active_flg CHAR(1) NOT NULL DEFAULT 'Y',
    vendor_nbr INT NOT NULL,
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp,
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp,
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    UNIQUE KEY uk1_my_table(account_nbr, account_name),
    FOREIGN KEY fk1_my_table(vendor_nbr) REFERENCES vendor(vendor_nbr)
    );
在这种格式中,MySQL自动创建名为uk1_my_table和fk1_my_table的索引es;但是FK对象的名称是不同的-my_table_ibfk_1(即tablename_ibfk_N–系统定义)。因此,
ALTER TABLE my_TABLE DROP外键fk1\u my_TABLE
将无法工作(因此会令人沮丧并引发警报),因为没有该名称的FK db对象

这里有一个针对constraints(参考:)的替代DDL格式:-

在这种格式中,MySQL仍在自动创建名为uk1_my_table和fk1_my_table的索引es,但FK对象名并没有什么不同——它是DDL中提到的fk1_my_table。因此,
ALTER TABLE my_TABLE DROP外键fk1\u my_TABLE
起作用,但留下了同名索引

另外,请注意,
ALTER TABLE my_TABLE DROP INDEX fk1\u my_TABLE
最初不会工作(当FK尚未删除时),并会显示一条错误消息,说明它正在FK中使用!如果DROP FK命令已成功执行,则只有DROP索引才能工作


希望这能解释并帮助解决这一困惑。

我将在这里发言,尽管我不知道我的答案是否准确,所以如果你知道数据库工程的内在本质,请纠正我。但如果我是对的,我认为这会有所帮助

外键及其关联的外键约束不是一回事,就像汽车发动机和曲轴不是一回事一样。发动机将汽油爆炸转化为直线运动(活塞),曲轴将直线运动转化为转向运动,然后转向车轮。发动机和曲轴一起驱动汽车前进

同样,外键和外键约束不是一回事,但它们共同创造了“外键关系”的概念

定义:

“外键”是外键索引的缩写

“Constraint”是外键约束的缩写

索引和约束一起构成“外键关系”

外键关系要求子表中的值存在于其父表中,从而确保数据库中的数据完整性

因为
CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY,
    account_nbr INT NOT NULL,
    account_name VARCHAR(50) NOT NULL,
    active_flg CHAR(1) NOT NULL DEFAULT 'Y',
    vendor_nbr INT NOT NULL,
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp,
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp,
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    UNIQUE KEY uk1_my_table(account_nbr, account_name),
    FOREIGN KEY fk1_my_table(vendor_nbr) REFERENCES vendor(vendor_nbr)
    );
CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY,
    account_nbr INT NOT NULL,
    account_name VARCHAR(50) NOT NULL,
    active_flg CHAR(1) NOT NULL DEFAULT 'Y',
    vendor_nbr INT NOT NULL,
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp,
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp,
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    CONSTRAINT uk1_my_table UNIQUE KEY (account_nbr, account_name),
    CONSTRAINT fk1_my_table FOREIGN KEY (vendor_nbr) REFERENCES vendor(vendor_nbr)
    );