zoukankan      html  css  js  c++  java
  • 外键(FOREIGN KEY)

    引子:把所有数据都存放于一张表的弊端

        1、表的组织结构复杂不清晰 
        2、浪费空间 
        3、扩展性极差 

    为了解决上述的问题,就需要用多张表来存放数据。

    表与表的记录之间存在着三种关系:一对多、多对多、一对一的关系。

    处理表之间关系问题就会利用到FOREIGN KEY

    多对一关系:

    被关联表称为主表,关联表称为子表

    子表通过foreign key 关联主表,子表多条记录可以关联主表一条记录

    示例如下:

    mysql> show create table dep;  #主表
    +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table | Create Table                                                                                                                                                                                                       |
    +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | dep   | CREATE TABLE `dep` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `dep_name` char(10) DEFAULT NULL,
      `dep_comment` char(60) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |
    +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.01 sec)
    
    mysql> show create table emp;
    +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                          |
    +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | emp   | CREATE TABLE `emp` (  #子表
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` char(16) CHARACTER SET latin1 DEFAULT NULL,
      `gender` enum('male','female') CHARACTER SET latin1 NOT NULL DEFAULT 'male',
      `dep_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `dep_id` (`dep_id`),
      CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 |
    +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    
    mysql> 
    mysql> insert into dep(dep_name,dep_comment) values ('教学部','辅助学生学习,教授课程'),('公关部','处理危机公关'),('技术部','开发项目,研究技术');
    Query OK, 3 rows affected (0.01 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> insert into emp(name,gender,dep_id)  values ('monicx0','male',1), ('monicx1','male',2), ('monicx2','male',1), ('monicx3','male',1), ('lili','female',3);
    Query OK, 5 rows affected (0.00 sec)
    Records: 5  Duplicates: 0  Warnings: 0
    
    mysql> select * from dep;
    +----+-----------+---------------------------------+
    | id | dep_name  | dep_comment                     |
    +----+-----------+---------------------------------+
    |  1 | 教学部    | 辅助学生学习,教授课程           |
    |  2 | 公关部    | 处理危机公关                    |
    |  3 | 技术部    | 开发项目,研究技术               |
    |  4 | 教学部    | 辅助学生学习,教授课程           |
    |  5 | 公关部    | 处理危机公关                    |
    |  6 | 技术部    | 开发项目,研究技术               |
    +----+-----------+---------------------------------+
    6 rows in set (0.00 sec)
    
    mysql> select * from emp;
    +----+---------+--------+--------+
    | id | name    | gender | dep_id |
    +----+---------+--------+--------+
    |  1 | monicx0 | male   |      1 |
    |  2 | monicx1 | male   |      2 |
    |  3 | monicx2 | male   |      1 |
    |  4 | monicx3 | male   |      1 |
    |  5 | lili    | female |      3 |
    |  6 | monicx0 | male   |      1 |
    |  7 | monicx1 | male   |      2 |
    |  8 | monicx2 | male   |      1 |
    |  9 | monicx3 | male   |      1 |
    | 10 | lili    | female |      3 |
    +----+---------+--------+--------+
    10 rows in set (0.00 sec)
    
    mysql> 

    修改主表记录查看影响:

    mysql> update dep set id=99 where id=3;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> select * from dep;
    +----+-----------+---------------------------------+
    | id | dep_name  | dep_comment                     |
    +----+-----------+---------------------------------+
    |  1 | 教学部    | 辅助学生学习,教授课程           |
    |  2 | 公关部    | 处理危机公关                    |
    |  4 | 教学部    | 辅助学生学习,教授课程           |
    |  5 | 公关部    | 处理危机公关                    |
    |  6 | 技术部    | 开发项目,研究技术               |
    | 99 | 技术部    | 开发项目,研究技术               |
    +----+-----------+---------------------------------+
    6 rows in set (0.00 sec)
    
    mysql> select * from emp;
    +----+---------+--------+--------+
    | id | name    | gender | dep_id |
    +----+---------+--------+--------+
    |  1 | monicx0 | male   |      1 |
    |  2 | monicx1 | male   |      2 |
    |  3 | monicx2 | male   |      1 |
    |  4 | monicx3 | male   |      1 |
    |  5 | lili    | female |     99 |
    |  6 | monicx0 | male   |      1 |
    |  7 | monicx1 | male   |      2 |
    |  8 | monicx2 | male   |      1 |
    |  9 | monicx3 | male   |      1 |
    | 10 | lili    | female |     99 |
    +----+---------+--------+--------+
    10 rows in set (0.00 sec)
    
    mysql> 
    mysql> delete from dep where id=1;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from dep;
    +----+-----------+---------------------------------+
    | id | dep_name  | dep_comment                     |
    +----+-----------+---------------------------------+
    |  2 | 公关部    | 处理危机公关                    |
    |  4 | 教学部    | 辅助学生学习,教授课程           |
    |  5 | 公关部    | 处理危机公关                    |
    |  6 | 技术部    | 开发项目,研究技术               |
    | 99 | 技术部    | 开发项目,研究技术               |
    +----+-----------+---------------------------------+
    5 rows in set (0.00 sec)
    
    mysql> select * from emp;
    +----+---------+--------+--------+
    | id | name    | gender | dep_id |
    +----+---------+--------+--------+
    |  2 | monicx1 | male   |      2 |
    |  5 | lili    | female |     99 |
    |  7 | monicx1 | male   |      2 |
    | 10 | lili    | female |     99 |
    +----+---------+--------+--------+
    4 rows in set (0.00 sec)
    
    mysql> 

    多对多关系:

    多对多关系就是A,B 两张表,A 表的一条记录可以关联B表的多个条记录 ,B表的一条记录也可以关联A 表的多条记录。

    mysql> show create table authorG
    *************************** 1. row ***************************
    Table: author
    Create Table: CREATE TABLE `author` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` char(16) CHARACTER SET latin1 DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)

    mysql> show create table bookG
    *************************** 1. row ***************************
    Table: book
    Create Table: CREATE TABLE `book` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `book_name` varchar(16) DEFAULT NULL,
    `price` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)

    mysql>

    insert into author(name) values
    ('monicx1'),
    ('monicx2'),
    ('monicx3')
    ;
    insert into book(book_name,price) values
    ('python从入门到入土',200),
    ('liunx从入门到入土',400),
    ('java从入门到入土',300),
    ('php从入门到入土',100)
    ;
    #建立第三张表:
    create table author2book(
        id int primary key auto_increment,
        author_id int,
        book_id int,
        foreign key(author_id) references author(id)
        on update cascade
        on delete cascade,
        foreign key(book_id) references book(id)
        on update cascade
        on delete cascade
    );
     
    insert into author2book(author_id,book_id) values
    (1,3),
    (1,4),
    (2,2),
    (2,4),
    (3,1),
    (3,2);
    mysql> select * from author2book;
    +----+-----------+---------+
    | id | author_id | book_id |
    +----+-----------+---------+
    |  3 |         2 |       2 |
    |  4 |         2 |       4 |
    |  5 |         3 |       1 |
    +----+-----------+---------+
    3 rows in set (0.00 sec)
    
    mysql> select * from book;
    +----+--------------------------+-------+
    | id | book_name                | price |
    +----+--------------------------+-------+
    |  1 | python从入门到入土       |   200 |
    |  2 | liunx从入门到入土        |   400 |
    |  3 | java从入门到入土         |   300 |
    |  4 | php从入门到入土          |   100 |
    +----+--------------------------+-------+
    4 rows in set (0.00 sec)
    
    mysql> delete from book where id=2;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from author2book;    #主表的操作都会影响关联的子表,因为我们配置了  caseade
    +----+-----------+---------+
    | id | author_id | book_id |
    +----+-----------+---------+
    |  4 |         2 |       4 |
    |  5 |         3 |       1 |
    +----+-----------+---------+
    2 rows in set (0.00 sec)
    
    mysql> 

    一对一关系:

    左表的一条记录唯一对应右表的一条记录,反之也一样

    create table customer(
        id int primary key auto_increment,
        name char(20) not null,
        qq char(10) not null,
        phone char(16) not null
    );
     
    create table student(
        id int primary key auto_increment,
        class_name char(20) not null,
        customer_id int unique, #该字段一定要是唯一的
        foreign key(customer_id) references customer(id) #此时外键的字段一定要保证unique
        on delete cascade
        on update cascade
    );

    ORM 

    #多表操作,一对一模型
    #先建立主表,再建立子表,子表关联主表。
    class AuthorDetail(models.Model):
        nid = models.AutoField(primary_key=True)
        birthday=models.DateField()
        telephone=models.CharField(max_length=11)
        addr=models.CharField(max_length=64)
    
    class Author(models.Model):
        nid=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
        age=models.IntegerField()
    #建立一对一联级
        ad_chain=models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)
    #
    class Publish(models.Model):
        nid=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
        city=models.CharField(max_length=32)
        email=models.EmailField()
    
    class NewBook(models.Model):
    
        nid=models.AutoField(primary_key=True)
        book_name=models.CharField(max_length=32)
        price=models.DecimalField(max_digits=5,decimal_places=2)
        #建立一对多关系,外键字段在多的一方,一个出版社可以出版多本书
        publish=models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
        #建立多对多关系,一个作者可以对应多本书,一本书可以对应过个作者,会自动创建第三章表
        author=models.ManyToManyField(to='Author',)
    """
  • 相关阅读:
    配置变量的信息
    Smarty保留变量信息
    选择排序
    java.utils.HashMap数据结构分析
    HashMap的工作原理
    Dubbo
    五种单例模式:
    Redis的持久化机制包括RBD和AOF两种,对于这两种持久化方式各有优势
    Zookeeper要安装在奇数个节点,但是为什么?
    Redis搭建多台哨兵
  • 原文地址:https://www.cnblogs.com/zy09/p/13739616.html
Copyright © 2011-2022 走看看