InnoDB外键使用小结

USE `wfc_database`;
#  主表(也可以称作:被参照表、referenced table、outTable)
ALTER TABLE `app` ENGINE=INNODB;
#  从表(也可以称作:参照表、外表、referencing table )
ALTER TABLE `app_version` ENGINE=INNODB;
# 一个 【应用 】可以有多个【应用版本】
# 因此 app 和 app_version 是 1:n 的关系 (一个 app_id 对应有多个 av_app_id)
# app_id是 app表 的主键, av_app_id是 app_version表 的索引

# app_version数据订正(在 app_version表中删除 app已经没有的 app_id)
DELETE FROM `app_version` WHERE av_app_id NOT IN ( SELECT app_id FROM app);
# 此步骤极为重要,否则无法添加外键(从表中存在主表中没有的外键id是不允许的)

# app_version添加外键
ALTER TABLE `app_version`
ADD CONSTRAINT fk_av_app_id
FOREIGN KEY (av_app_id)
REFERENCES `app` (app_id)
ON DELETE CASCADE ON UPDATE CASCADE;

# 建立外键的前提:
  被约束字段与外键的数据类型必须相同
  被约束字段需要设置为索引,外键需要设置为 PRIMARY
  外键作用: 使两张表形成关联,外键只能引用从表中的列的值!
  指定从表关键字: foreign key (列名)
  引用外键关键字: references <外键表名> (外键列名)
# 事件触发(级联操作)限制 : on delete 和 on update
  可设参数 cascade (跟随外键改动) ,强烈推荐,能够保存数据一致性
  restrict (限制主表中的外键改动)
  [默认] no action 

# 如果以上语句在创建过程中有报如下错误
  Can not create table ‘d91.#sql-197e_18b4‘ (errno: 150)
# 请把 av_app_id 和 app_id 的字段类型设置为完全相同
  也就是约束字段的 类型、长度、有无符号、是否为空、默认值 要设置跟外键相同
  对于这次的场景,我把 app_id 和 av_app_id 都设置为 INT(10) , UNSIGNED,NOT NULL
  确保外键的名字没有和已经存在的 键值/索引名 重名

# 补充,如果要删除外键约束可以这么做
  alter table 表名 drop foreign key 外键约束名称;
# 比如,要删掉刚刚创建的外键,你可以
  ALTER TABLE `app_version` DROP FOREIGN KEY fk_av_app_id ;

# --------------------- InnoDB外键知识 ------------------------- #

方法一:  
定义数据表
  假如某个电脑生产商,它的数据库中保存着整机和配件的产品信息。用来保存整机产品信息的表叫做 Pc;用来保存配件供货信息的表叫做Parts。
  在Pc表中有一个字段,用来描述这款电脑所使用的CPU型号;
  在Parts 表中相应有一个字段,描述的正是CPU的型号,我们可以把它想成是全部CPU的型号列表。
  很显然,这个厂家生产的电脑,其使用的CPU一定是供货信息表(parts)中存在的型号。这时,两个表中就存在一种约束关系(constraint)——Pc表中的CPU型号受到Parts 表中型号的约束。

  首先我们来创建 parts 表:
CREATE TABLE parts (
... 字段定义 ...,
model VARCHAR(20) NOT NULL,
... 字段定义 ...
);
接下来是Pc表:                   
CREATE TABLE pc (
... 字段定义 ...,
cpumodel VARCHAR(20) NOT NULL,
... 字段定义 ...
};
  设置索引
  若要设置MySQL外键,在 参照表 [外表] (referencing table,即Pc表) 和被参照表 [主表] (referenced table,即parts表) 中,相对应的两个字段必须都设置索引(index)。

  对Parts表:
  ALTER TABLE parts ADD INDEX idx_model (model);
  这句话的意思是,为 parts 表增加一个索引,索引建立在 model 字段上,给这个索引起个名字叫idx_model。

  对Pc表也类似:
  ALTER TABLE pc ADD INDEX idx_cpumodel (cpumodel);
  事实上这两个索引可以在创建表的时候就设置。这里只是为了突出其必要性。

  定义外键
  下面为两张表之间建立前面所述的那种“约束”。因为pc的CPU型号必须参照parts表中的相应型号,所以我们将Pc表的cpumodel字段设置为“外键”(FOREIGN KEY),即这个键的参照值来自于其他表。

ALTER TABLE pc ADD CONSTRAINT fk_cpu_model
FOREIGN KEY (cpumodel)
REFERENCES parts(model); 

  第一行是说要为Pc表设置MySQL外键,给这个外键起一个名字叫做fk_cpu_model;第二行是说将本表的cpumodel字段设置为外键;第三行是说这个外键受到的约束来自于Parts表的model字段。

  这样,我们的外键就可以了。如果我们试着CREATE一台Pc,它所使用的CPU的型号是Parts表中不存在的,那么MySQL会禁止这台PC被CREATE出来。

  级联操作
  考虑以下这种情况:
  技术人员发现,一个月之前输入到 parts 表中的某个系列的 cpu (可能有很多款)的型号全都输错了一个字母,现在需要改正。我们希望的是,当 parts 表中那些 Referenced Column 有所变化时,相应表中的 Referencing Column 也能自动更正。
  可以在定义MySQL外键的时候,在最后加入这样的关键字:
  ON UPDATE CASCADE; 即在主表更新时,子表(们)产生连锁更新动作,似乎有些人喜欢把这个叫“级联”操作。:)
  如果把这语句完整的写出来,就是:
# 例子一
ALTER TABLE pc ADD CONSTRAINT fk_cpu_model
FOREIGN KEY (cpumodel)
REFERENCES parts(model)
ON UPDATE CASCADE; 

  除了 CASCADE 外,还有 RESTRICT(禁止主表变更)、SET NULL(子表相应字段设置为空)等操作。
  延伸阅读

  外键(Foreign Key)
  如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。外键又称作外关键字。

  外键的作用:
  保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值!

方法二:
建立外键的前提: 本表的列必须与外键类型相同(外键必须是外表主键)。
外键作用: 使两张表形成关联,外键只能引用外表中的列的值!
指定主键关键字: foreign key(列名)
引用外键关键字: references <外键表名>(外键列名)
事件触发限制: on delete和on update , 可设参数cascade(跟随外键改动), restrict(限制外表中的外键改动),set Null(设空值),set Default(设默认值),[默认]no action 

例如:
outTable表 主键 id 类型 int
创建含有外键的表: 

create table temp(
id int,
name char(20),
foreign key(id) references outTable(id)
on delete cascade on update cascade); 

创建后修改表:
alter table temp add constraint  foreign key(id) references outTable(id) on delete cascade on update cascade; 

说明:把id列设为外键,参照外表outTable的id列,当外键的值删除本表中对应的列删除;当外键的值改变本表中对应的列值改变。在使用alter中constraint是针对使用外键的情况。
这种主外键的级联操作在mysql中只支持InnoDB类型。要设置为该类型要在mysql中的配置文件中改动默认不支持InnoDB为支持,可输入命令查看是否支持:

mysql > show variables like "have%";
如果不支持停止mysql,打开my.ini配置文件找到skip-innodb,前面加#,重启mysql,然后修改主外键两表类型:

mysql > alter table xxx ENGINE = InnoDB;
最后在命令中输入上述创建外键的方法。 不过,如果你的业务不需要使用到事务,那么使用myisam是最佳考虑, 因为myisam不支持事务,有比较好的性能。 但是如果你的业务必须要使用到事务,也就是说对数据一致性要求很高的话,需要使用到INODB,由于INODB要使用到锁,因此它的并发能力就差一些,因此性能方面也会差一些。

如果要删除外键约束可使用如下命令:
mysql > alter table ss_accesscode drop foreign key 外键约束名称;

注:添加外键约束时若没有指定外键约束的名称,则系统会自动添加外键约束名:表名_ibfk_n(表示第n个外键约束)。比如我们创建外键时就省略了外键线束名称。
时间: 2024-08-23 23:36:42

InnoDB外键使用小结的相关文章

外键约束小结

外键约束(foreign key constraints) 确保存储在外键表中的数据一致性.完整性. 外键前提:本表列须于外键列类型相同(外键须是外表主键). 外键选择原则 1.为关联字段创建外键. 2.所有的键都必须唯一. 3.避免使用复合键. 4.外键总是关联唯一的键字段.

只有innoDB才允许使用外键

1.只有InnoDB引擎才允许使用外键,所以,我们的数据表必须使用InnoDB引擎. 2.注意: 1.必须使用InnoDB引擎: 2.外键必须建立索引(INDEX): 3.外键绑定关系这里使用了“ ON DELETE CASCADE”,意思是如果外键对应数据被删除,将关联数据完全删除, 3.更新的操作也类似,因为我们在前面建表的时候已经定义外键删除.更新操作都是CASCADE,所以在这里可以直接测试数据. 4.用外键对多个相关联的表做同时删除.更新的操作,从而保证了数据的一致性. . casca

Hibernate一对一双向关联(外键关联)用法小结

这几天在改一个项目源码,遇到一个问题坑了很久.场景如下(注:此处是借鉴网络上的例子,并不是自己的实验环境): 一夫一妻制--比如夫妻关系的两张数据表,一个是wif表,一个是husban表,其数据表信息如下: CREATE TABLE `wife` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFA

mysq添加外键报错:check the manual that corresponds to your MySQL server version for the right syntax to use near &#39;TYPE=InnoDB&#39; at line 1

今天用navcat往一个表添加外键的时候报错: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TYPE=InnoDB' at line 1 排查之后发现是因为两个表的类型不一样所致: SQL:SHOW TABLE STATUS 查询出数据表的状态,Engine那一列就是 使用

MySQL的外键约束:Cascade/Restrict/No action/SET NULL

转自:http://blog.csdn.net/cnjsnt_s/article/details/5548280 具体使用时需要参考:http://blog.csdn.net/codeforme/article/details/5539454 (注:没看很明白,囧.) MySQL有两种常用的引擎类型:MyISAM和InnoDB.目前只有InnoDB引擎类型支持外键约束.InnoDB中外键约束定义的语法如下: [CONSTRAINT [symbol]] FOREIGN KEY [index_nam

mysql外键(FOREIGNKEY)介绍及使用注意事项

一.基本概念 1.MySQL中"键"和"索引"的定义相同,所以外键和主键一样也是索引的一种.不同的是MySQL会自动为所有表的主键进行索引,但是外键字段必须由用户进行明确的索引.用于外键关系的字段必须在所有的参照表中进行明确地索引,InnoDB不能自动地创建索引. 2.外键可以是一对一的,一个表的记录只能与另一个表的一条记录连接,或者是一对多的,一个表的记录与另一个表的多条记录连接. 3.如果需要更好的性能,并且不需要完整性检查,可以选择使用MyISAM表类型,如果

mysql的外键约束

创建表格: #首先登录mysql mysql -uroot 打开一个数据库 mysql>use db1; 创建一个父表,我们命名为province, mysql> create table province ( -> id smallint auto_increment key, -> name varchar(10) NOT NULL -> ); 创建一个子表,命名为student,其中其pid引用来自province的id, mysql> create table

navicat设置外键

最近使用navicat设置外键发现保存以后会消失,然后各种百度发现问题了,表的引擎是MyISAM,InnoDB引擎才支持设置外键 如图打开表设计,在选项一栏选择InnoDB,然后保存,被关联的表同样需要设置InnoDB引擎 两个都引擎都设置好了以后,添加外键 保存的时候,报错,保存不了,仔细观察发现,a表和b表中外键关联字段类型有差异,a的主键是无符号的,b表的a_id字段是有符号类型,把b的a_id类型修改为无符号类型保存发现成功了,外键建立完毕.

mysql中的外键foreign key

一.如果一张表中有一个非主键的字段指向了别一张表中的主键,就将该字段叫做外键. 一张表中可以有多个外键. 外键的默认作用有两点: 1.对子表(外键所在的表)的作用:子表在进行写操作的时候,如果外键字段在父表中找不到对应的匹配,操作就会失败. 2.对父表的作用:对父表的主键字段进行删和改时,如果对应的主键在子表中被引用,操作就会失败. 外键的定制作用----三种约束模式: district:严格模式(默认), 父表不能删除或更新一个被子表引用的记录. cascade:级联模式, 父表操作后,子表关