zoukankan      html  css  js  c++  java
  • mysql外键使用和事物使用

    mysql外键功能主要是为了保证关联表数据的一致性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值!

    例如:

      a b 两个表

      a表中存有 客户号,客户名称

      b表中存有 每个客户的订单

      有了外键后

      你只能在确信b 表中没有客户x的订单后,才可以在a表中删除客户x

      建立外键的前提: 本表的列必须与外键类型相同(外键必须是外表主键)。

      指定主键关键字: 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);

      说明:把id列 设为外键 参照外表outTable的id列 当外键的值删除 本表中对应的列筛除 当外键的值改变 本表中对应的列值改变。

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

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

    外键的定义语法:
    [CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
        REFERENCES tbl_name (index_col_name, ...)
        [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
        [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
    该语法可以在 CREATE TABLE 和 ALTER TABLE 时使用,如果不指定CONSTRAINT symbol,MYSQL会自动生成一个名字。
    ON DELETE、ON UPDATE表示事件触发限制,可设参数:
    RESTRICT(限制外表中的外键改动)
    CASCADE(跟随外键改动)
    SET NULL(设空值)
    SET DEFAULT(设默认值)
    NO ACTION(无动作,默认的)

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

    CREATE TABLE `dage` (
     2  `id` int(11NOT NULL auto_increment,
     3  `name` varchar(32default '',
     4  PRIMARY KEY  (`id`)
     5) ENGINE=InnoDB DEFAULT CHARSET=latin1;
     6
     7CREATE TABLE `xiaodi` (
     8  `id` int(11NOT NULL auto_increment,
     9  `dage_id` int(11default NULL,
    10  `name` varchar(32default '',
    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;


    插入个大哥:

     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)


    插入个小弟:

     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+----+---------+--------------+


    把大哥删除:

     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`))


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

    插入一个新的小弟:

     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


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

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

    mysql> 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


    再次试着把大哥删了:

     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了呢!

    下面是php中事物使用的小例子

    <?php
    mysql_connect("XXXXXXX", 'root', 'root');
    mysql_select_db("XXXXX");
    mysql_query("SET NAMES utf8");
    mysql_query("BEGIN");
    $rs =mysql_query("insert into TEST values (2, 'title1')");
    $rs1 = mysql_query("insert into TEST2 values (3, 1, 'username')");
    var_dump($rs);
    var_dump($rs1);
    if($rs && $rs1)  {
    	mysql_query("COMMIT");
    } else {
    	mysql_query("ROLLBACK");
    }
    
  • 相关阅读:
    bzoj 1017 魔兽地图DotR
    poj 1322 chocolate
    bzoj 1045 糖果传递
    poj 3067 japan
    timus 1109 Conference(二分图匹配)
    URAL 1205 By the Underground or by Foot?(SPFA)
    URAL 1242 Werewolf(DFS)
    timus 1033 Labyrinth(BFS)
    URAL 1208 Legendary Teams Contest(DFS)
    URAL 1930 Ivan's Car(BFS)
  • 原文地址:https://www.cnblogs.com/agang-php/p/4392718.html
Copyright © 2011-2022 走看看