zoukankan      html  css  js  c++  java
  • Python-多表关联 外键 级联

    分表
    为什么分表

    多表关联
    多表关系 ******
    表之间的关系
    为什么要分表

    多对一
    一个外键
    多对多
    一个中间表 两个外键
    一对一
    一个外键加一个唯一约束
    外键约束 ******
    foreign key(自己的字段) references 表名(对方的主键)

    级联操作***
    on update cascade
    on delete cascade

    2.
    1.修改表
    2.复制表
    3.蠕虫复制
    sql注入攻击

    ----------------------------------------
    分表
    为什么分表,把所有数据都存放于一张表的弊端
    1、表的组织结构复杂不清晰
    2、浪费空间
    3、扩展性极差

    多表关联
    多表关系 ******
    表之间的关系
    为什么要分表

    1,多对一 (一个外键foreign key)
    create table dept(id int primary key auto_increment,name char(20),job char(20));
    create table emp(id int primary key auto_increment,name char(20),d_id int,foreign key(d_id) references dept(id));

    2,多对多 (一个中间表 两个外键foreign key)
    两张表之间是一个双向的多对一关系,称之为多对多
    如何实现?
    需要一个中间表 专门存储关联关系

    老师和学生
    一个老师可以教多个学生
    一个学生可以被多个老师教
    老师表和学生表 是多对多的关系
    需要一个中间表 专门存储关联关系

    create table teacher(id int primary key auto_increment,name char(15));
    create table student(id int primary key auto_increment,name char(15));
    #中间表
    create table tsr(
    id int primary key auto_increment,
    t_id int,s_id int,
    foreign key(t_id) references teacher(id),
    foreign key(s_id) references student(id)
    );
    现在老师和学生 都是主表 关系表是从表
    先插入老师和学生数据
    insert into teacher values
    (1,"高跟"),
    (2,"矮跟");

    insert into student values
    (1,"炜哥"),
    (2,"仨疯");

    # 插入对应关系
    insert into tsr values
    (null,1,1),
    (null,1,2),
    (null,2,2);

    3,一对一 (一个外键foreign key加一个唯一约束unique)
    左表的一条记录唯一对应右表的一条记录,反之也一样

    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 stu(
    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
    );

    insert into customer(name,qq,phone) values
    ('李飞机','31811231',13811341220),
    ('王大炮','123123123',15213146809),
    ('守榴弹','283818181',1867141331),
    ('吴坦克','283818181',1851143312),
    ('赢火箭','888818181',1861243314),
    ('战地雷','112312312',18811431230)
    ;


    #增加学生
    insert into stu(class_name,customer_id) values
    ('脱产3班',3),
    ('周末19期',4),
    ('周末19期',5)
    ;

    外键约束 ******
    foreign key(自己的字段) references 表名(对方的主键)

    # foreign key会带来什么样的效果?
    约束1:在创建表时,先建被关联的表dep,才能建关联表emp
    约束2:在插入记录时,必须先插被关联的表dep,才能插关联表emp
    约束3:在删除记录时,先删除关联的表的记录,再被关联的表的记录
    约束1:在创建表时,先建被关联的表dep,才能建关联表emp

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

    约束2:在插入记录时,必须先插被关联的表dep,才能插关联表emp
    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);


    约束3:更新与删除都需要考虑到关联与被关联的关系
    解决方案:
    1、先删除关联表emp,再删除被关联表dep,准备重建
    mysql> drop table emp;
    Query OK, 0 rows affected (0.11 sec)

    mysql> drop table dep;
    Query OK, 0 rows affected (0.04 sec)


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


    # 同步删除
    mysql> select * from dep;
    +----+------------------+------------------------------------------------------------------------------------------+
    | id | dep_name | dep_comment |
    +----+------------------+------------------------------------------------------------------------------------------+
    | 1 | sb教学部 | sb辅导学生学习,教授python课程 |
    | 2 | 外交部 | 老男孩上海校区驻张江形象大使 |
    | 3 | nb技术部 | nb技术能力有限部门 |
    +----+------------------+------------------------------------------------------------------------------------------+
    3 rows in set (0.00 sec)

    mysql> select * from emp;
    +----+------------------+--------+--------+
    | id | name | gender | dep_id |
    +----+------------------+--------+--------+
    | 1 | alex | male | 1 |
    | 2 | egon | male | 2 |
    | 3 | lxx | male | 1 |
    | 4 | wxx | male | 1 |
    | 5 | wenzhou | female | 3 |
    +----+------------------+--------+--------+
    5 rows in set (0.00 sec)

    mysql> delete from dep where id=1;
    Query OK, 1 row affected (0.02 sec)

    mysql> select * from dep;
    +----+------------------+------------------------------------------------------------------------------------------+
    | id | dep_name | dep_comment |
    +----+------------------+------------------------------------------------------------------------------------------+
    | 2 | 外交部 | 老男孩上海校区驻张江形象大使 |
    | 3 | nb技术部 | nb技术能力有限部门 |
    +----+------------------+------------------------------------------------------------------------------------------+
    2 rows in set (0.00 sec)

    mysql> select * from emp;
    +----+------------------+--------+--------+
    | id | name | gender | dep_id |
    +----+------------------+--------+--------+
    | 2 | egon | male | 2 |
    | 5 | wenzhou | female | 3 |
    +----+------------------+--------+--------+
    2 rows in set (0.00 sec)

    #同步更新
    mysql> select * from emp;
    +----+------------------+--------+--------+
    | id | name | gender | dep_id |
    +----+------------------+--------+--------+
    | 2 | egon | male | 2 |
    | 5 | wenzhou | female | 3 |
    +----+------------------+--------+--------+
    2 rows in set (0.00 sec)

    mysql> update dep set id=200 where id =2;
    Query OK, 1 row affected (0.04 sec)
    Rows matched: 1 Changed: 1 Warnings: 0

    mysql> select * from dep;
    +-----+------------------+------------------------------------------------------------------------------------------+
    | id | dep_name | dep_comment |
    +-----+------------------+------------------------------------------------------------------------------------------+
    | 3 | nb技术部 | nb技术能力有限部门 |
    | 200 | 外交部 | 老男孩上海校区驻张江形象大使 |
    +-----+------------------+------------------------------------------------------------------------------------------+
    2 rows in set (0.00 sec)

    mysql> select * from emp;
    +----+------------------+--------+--------+
    | id | name | gender | dep_id |
    +----+------------------+--------+--------+
    | 2 | egon | male | 200 |
    | 5 | wenzhou | female | 3 |
    +----+------------------+--------+--------+
    2 rows in set (0.00 sec)

    级联操作***
    on delete cascade 当主表删除记录时 从表相关联的记录同步删除
    on update cascade 当主表id更新时 从表相关联的记录同步更新
    注意是单向的 主表变化是 级联操作从表 从表的变化不会级联到主表

    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
    on update cascade
    );

    在日常开发中 如果性能要求贼高 不应该使用外键
    1.效率降低
    2.耦合 关系多起来后管理麻烦
    这时候 关系只是逻辑关系 很有可能产生错误数据

    2.
    1.修改表
    add 添加字段 after|first
    after 添加字段到哪个字段后面
    first 添加字段到最前面
    modify 修改字段类型
    change 修改字段名称 或 类型
    drop 删除字段
    rename 改表名

    2.复制表
    create table 新的表名 select * from 源表名;
    数据
    结构
    约束不能复制

    当条件不成立是 只复制表结构
    create table 新的表名 select * from 源表名 where 1 = 2;
    create table stu_copy2 select * from student1 where 1 = 2;

    清空表
    delete from tb1;
    强调:上面的这条命令确实可以将表里的所有记录都删掉,但不会将id重置为0,
    所以收该条命令根本不是用来清空表的,delete是用来删除表中某一些符合条件的记录

    delete from tb1 where id > 10;
    如果要清空表,使用truncate tb1;
    作用:将整张表重置

    3.蠕虫复制
    自我复制
    insert into 表名称 select *from 表名;
    如果有主键 避开主键字段
    insert into 表名称(其他字段) select 其他字段 from 表名;

    sql注入攻击
    一个了解sql语法的攻击者 可以在输入框输入sql语句

    1255241708 123
    select *from user where account = ":"drop database mysql" and pwd = "123";







  • 相关阅读:
    C#跨窗体操作
    搞IT的不如去养鸡养猪了
    C# 委托实例(跨窗体操作控件)
    FastReport 自定义页长
    SQL 根据一个表更新另一个表的内容
    Delphi中用ADOQuery实现主从表的例子(转)
    旅行的意义
    嘉州影院的网址
    纯粹的人
    Delphi中流的使用:压缩与解压缩(TCompressionStream、TDecompressionStream)
  • 原文地址:https://www.cnblogs.com/du-jun/p/9995621.html
Copyright © 2011-2022 走看看