zoukankan      html  css  js  c++  java
  • 数据库(三)

    前言

    本篇博客主要内容为表之间的关系、多表关联、复制表;查询如单表查询、多表关联查询

    表之间关系

    为什么要分表?

    假如现在有两种数据,一种是部门数据一种是员工数据,如果两中数据放在同一张表中则会造成:

    • 数据重复
    • 结构混乱
    • 扩展维护性差
    • 需要分表

    所以需要把表中会造成混乱的数据分出来,分成两张表。

    mysql> create table dept(id int primary key auto_increment,name char(20),job char(20));
    
    mysql> create table emp(id int primary key auto_increment,name char(20),gender char,age int,salary float,d_id int);
    

    什么时候需要分表?

    当出现大量重复数据时,当一条记录中的数据不属于同一类时需要分表。

    分表之后产生的问题,员工表可以存储一个不存在的部门编号,这样的数据是不完整的无效数据,必须找到一种方法可以在物理层面建立关联关系。

    以上建表语句可以建立逻辑上的关联关系,这有建表的人才明白其中的关系,而 mysql 并不知道关系,所以需要通过外键来进行约束,说明这两张表的关联关系。

    外键的使用

    mysql> create table 表名(字段名 类型(长度),foreign key(外键的字段名) references 要关联表名(主键名));
    

    使用外键时必须分清主从关系,也就是要分清先键那张表,因为在使用外键关联表时,需要知道对方表的表名,所以要关联的表应该是主表,应该先建主表,这样才能关联起来。

    外键的第一个约束

    先键主表,再建从表

    mysql> create table dept(id int primary key auto_increment,name char(20),job char(20));
    
    mysql> create table emp(id int primary key auto_increment,name char(20),d_id int,foreign key(d_id) references dept(id));
    

    外键的第二个约束

    数据先插入主表,再插入从表数据

    mysql> insert into dept values(1,'hr','招聘');
    
    mysql> insert into emp values(1,'张无忌',1);
    

    外键的第三个约束

    删除数据时先删从表,再删主表

    mysql> delete from emp where name = '张无忌';
    
    mysql> delete from dept where id = 1;
    

    外键的第四个约束

    从表更新外键时必须保证外键是存在的。

    外键的第五个约束

    更新主表的 id 时,要么先删除从表关联的数据,或者把关联数据关联到其他的主表 id。

    有了这几种约束后,可以保证数据的完整性。相应的受到外键约束,主表的删除和更新操作受到限制,很多情况下,删除主表某个数据需要至少两条sql 语句,会很麻烦。

    外键的第六个约束

    删除主表时,要先删除从表。

    级联操作

    删除级联

    当主表删除时,从表相关联的记录同步删除

    mysql> create table emp(id int primary key auto_increment,name char(20),d_id int,foreign key(d_id) references dept(id) on delete cascade);
    

    更新级联

    当主表 id 时,从表相关联的记录通步更新

    mysql> create table emp(id int primary key auto_increment,name char(20),d_id int,foreign key(d_id) references dept(id) on update cascade);
    

    级联方向只能是主表级联从表,可以在操作主表时自动操作从表。(单箱操作,主表变化是级联操作从表,从表的变化不会影响主表)

    一对一关系

    一对一的关系只需要加一个外键来关联即可,但是需要给外键加上唯一约束。有主从关系的都需要先建主表。

    mysql> create customer(c_id int primary key auto_increment,name char(20),phonenum char(11),addr char(20));
    
    mysql> create student(s_id int primary key auto_increment,name char(20),class char(11),number char(20),housenum char(20),c_id int unique,foreign key(c_id) references customer(c_id)); 
    

    一对一的另一种使用场景,当一个表的字段太多,而常用的字段不多时,可以采取垂直分表的方式来提高效率,比如个人信息有身份证、性别、年龄、地址等,可以拆分为基础信息和细节信息;也有另一种提升效率的方式,水平分表,当一个表中的数据记录太多时,效率会降低,可以采取水平分表,字段完全相同。

    多对多关系

    假如有两张表,一张表存的是老师,另一张表存的是学生。因为一个老师可以教多个学生,一个学生也可以有多个老师,所以这是双向多对一的关系,也就是多对多的关系。那么应该怎么存储数据呢?

    可以通过增加一个中间表来存储两张表的关系,然后其他两张表分别用一个字段作为外键来关联中间表。(只要是多对多关系都是靠中间表来存储两张表之间的关系)除了中间表,另外两张都是主表,具体先建哪种主表没有先后顺序。多对多关系至少需要三张表。

    mysql> create table stu(id int primary key auto_increment,name char(20));
    
    mysql> create table tea(id int primary key auto_increment,name char(20));
    
    mysql> create table tsr(id int primary key auto_increment,t_id int,s_id int,foreign key(t_id) references tea(id),foreign key(s_id) references stu(id));
    

    因为老师和学生都是主表,关系表是从表,所以需要先插入老师和学生的数据,接着插入中间表的数据。

    多对多关系表中因为已经有了 id 为主键,所以可以重复存入相同的学生和老师关系数据,可以通过联合主键改变。

    多对一关系

    mysql> create table dept(id int primary key auto_increment,name char(20),job char(20));
    
    mysql> create table emp(id int primary key auto_increment,name char(20),d_id int,foreign key(d_id) references dept(id));
    

    复制表

    mysql> create table 新表名 select * from 被复制的表名;
    

    注意不会复制主键和约束条件,数据结构都可以复制。

    mysql> create table 新表名 select * from 源表名 where 1 = 2;
    

    当where 后面条件不成立时,只会复制表结构。

    蠕虫复制

    自我复制。

    mysql> insert into 表名 select * from 表名;
    

    如果有主键

    mysql> insert into 表名(其他字段) select 其他字段 from 表名;
    

    在日常开发中,如果对性能要求很高,不应该使用外键

    1. 效率降低
    2. 耦合 关系多起来会造成管理麻烦

    这时候关系只是逻辑关系很有可能产生错误数据。

  • 相关阅读:
    读书笔记Review: HTTP and HttpServletRequest
    读书笔记JavaScript Patterns_chapter6_Code Reuse Patterns
    读书笔记Review: servlet lifecycle and API
    读书笔记Review: HttpServletResponse
    简单分析Ext.ComponentMgr 函数
    翻译 Extjs in action中的Event flow in the DOM
    struts中的web.xml
    读书笔记_Extjs In Action_The Component Life Cycle
    web service中的事件
    Remoting学习笔记
  • 原文地址:https://www.cnblogs.com/zuanzuan/p/9997948.html
Copyright © 2011-2022 走看看