zoukankan      html  css  js  c++  java
  • 数据库3表之间的关系

    一.一对多

    当我们把所有的信息存在同一张表中:

    缺点:

      结构不清晰,分不清主次(员工信息还是部门信息是主体)

      扩展性差(假设要取消销售部需要一个个去删除)

      其中有重复的内容,造成内存的浪费

    解决方式:(将表进行拆分)

    当我们拆分成2张表的时候,这时候表和表之间就没有关系了,现在我们需要找出其中的关系并给他们建立关系.这时候就用到外键了.

    站在员工的角度:
        一名员工只能属于一个部门
    站在部门的角度:
        一个部门可以有多名员工

    一对多关系的建立:

    ps:当理出关系后,建表时一定要先创建被关联表,要不会报错

     

    #创建被关联表dep
    create table dep(
        id int primary key auto_increment,
        dep_name char(10),
        dep_comment char(60)
    );
    #创建emp表
    create table emp(
        id int primary key auto_increment,
        name char(16),
        gender enum('male','female') not null default 'male',
        dep_id int,
        foreign key(dep_id) references dep(id)
    );

    ps:当我们建好表之后插入数据,这是也要先插入被关联表中的数据,要不也会报错

    #先插入被关联的表数据
    insert into dep(dep_name,dep_comment) values
    ('sb教学部','sb辅导学生学习,教授python课程'),
    ('外交部','老男孩上海校区驻张江形象大使'),
    ('nb技术部','nb技术能力有限部门');
    
    #在插入关联表数据
    insert into emp(name,gender,dep_id)  values
    ('alex','male',1),
    ('egon','male',2),
    ('lxx','male',1),
    ('wxx','male',1),
    ('wenzhou','female',3);

    删除值:若此时删除dep表中的id=1的值,这时候会报错:

    原因是此时这两张表还在关联,你要是删除了dep中的id=1的信息,那表emp中dep_id=1的值就是无家可归的孤儿了,所以不能删除.

    修改:当我们要修改emp表中的dep_id值,若要将其改成dep中存在的id值是可以的,但是若要修改为不存在的值也会报错:

    若想改变着这种情况有以下方法:

    1.删表重建

    2.先删除员工表中的数据,再删部门表

    这些方式当数据量较大时都比较耗费时间.所以都不采用,联想将两表的数据进行关联,同步删除同步修改

    create table dep(
        id int primary key auto_increment,
        dep_name char(10),
        dep_comment char(60)
    );
    
    create table emp(
        id int primary key auto_increment,
        name char(16),
        gender enum('male','female') not null default 'male',
        dep_id int,
        foreign key(dep_id) references dep(id)
        on update cascade  # 级联修改  (同步修改)
        on delete cascade  # 级联删除  (同步删除)
    );

    二.多对多

    当表之间的关系时多对多的时候,若我们还像一对多一样去创建表的话,就会出现和之前创建表一样的情况,那是因为两表之间都存在外键,相互关联,先建谁都不行,这时候就需要一个第三方来和他们关联,将其数据进行整合关联.这时候这两张表看起来就没有任何关系了

    #创建作者表
    create table author(
        id int primary key auto_increment,
        name char(16)
    );
    #创建书表
    create table book(
        id int primary key auto_increment,
        bname char(16),
        price int
    );
    #创建第三方表
    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
    );
    ps:一定要注意逗号的使用

    三.一对一

    左边的一张表一条数据唯一对应右边表的一条数据(或不存在对应),反过来也成立

    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
    );
    ps:外键一般放置在查询较多的表中

    总结:总结表和表之间的关系一定要站在双方的角度去看,不能只看一边,当有两个一对多的时候就是多对多,当有一个一对多就是一对多,当没有一对多关系时可能为两情况,要么没关系,要么就是一对一的关系,这需要我们自己去判断

    修改表:

    语法:
    1. 修改表名  
          ALTER TABLE 表名 
                              RENAME 新表名;
    2. 增加字段
          ALTER TABLE 表名
                              ADD 字段名  数据类型 [完整性约束条件…],
                              ADD 字段名  数据类型 [完整性约束条件…];
          ALTER TABLE 表名
                              ADD 字段名  数据类型 [完整性约束条件…]  FIRST;
          ALTER TABLE 表名
                              ADD 字段名  数据类型 [完整性约束条件…]  AFTER 字段名;                       
    3. 删除字段
          ALTER TABLE 表名 
                              DROP 字段名;
    4. 修改字段  # modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
          ALTER TABLE 表名 
                              MODIFY  字段名 数据类型 [完整性约束条件…];
          ALTER TABLE 表名 
                              CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];

    复制表:

    # 查询语句执行的结果也是一张表,可以看成虚拟表
    
    # 复制表结构+记录 (key不会复制: 主键、外键和索引)
    create table new_service select * from service;
    
    # 只复制表结构
    select * from service where 1=2;        //条件为假,查不到任何记录
    
    create table new1_service select * from service where 1=2;  
    
    create table t4 like employees;

     

  • 相关阅读:
    通过加载Xib文件来创建UITableViewCell造成复用数据混乱问题方案
    iOS开发过程中常见错误问题及解决方案
    iOS开发常用第三方库
    KVC和KVO的理解(底层实现原理)
    iOS面试必备-iOS基础知识
    iOS应用适配IPV6
    Runtime运行时的那点事儿
    iOS应用性能调优的25个建议和技巧
    iOS清除缓存功能开发
    微信浏览器跳转页面后再返回,如何恢复到跳转前的位置的问题。
  • 原文地址:https://www.cnblogs.com/z929chongzi/p/11383435.html
Copyright © 2011-2022 走看看