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个外键约束)。好比咱们建立外键时就省略了外键线束名称。