MySQL 多键

Posted 天天好心情

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 多键相关的知识,希望对你有一定的参考价值。

1.外键: 用来建立两张表之间的关系
- 一对多
- 多对多
- 一对一

2.了解知识点:
    - 修改表的操作
    - 复制表操作

研究表与表之间的关系:
1.定义一张 员工部门表
id, name, gender, dep_name, dep_desc

- 将所有数据存放在一张表中的弊端:
    1.结构不清晰 ---> 不致命
    2.浪费空间   ---> 不致命
    3.可扩展性极差 ---> 不可忽视的弊端
        - 类似于将所有python代码存放在一个py文件中,强耦合到一起了----> 解耦合 ----> 拆分表


    - 拆分表解决以上问题.

    - 需要给两张表之间,建立一种强有力的关系, 使用 “外键”

- !!!!! ****** 如何确认表与表之间的关系是 (一对多、多对多、一对一)
    - 注意: 要确立两张表之间的关系,必须站在两个位置去思考:
        - 站在员工表的位置: 多个员工能否对应一个部门?  能!!!

            - 员工与部门: 多 对 一

                - 员工表单向 多 对 一 部门表

        - 站在部门表的位置: 多个部门能够对应一个员工?  不能!!!

        总结: 凡是单向 多 对 一 的表关系,称之为 一对多 的外键关系。

- 外键: 语法: foreign key(当前表中建立关系的外键字段) references 被关联表名(id)

# 创建两张表
    1.必须先建立被关联表,再建立关联表

# 被关联表:
    dep:
        create table dep(
            id int primary key auto_increment,
            dep_name varchar(16),
            dep_desc varchar(255)
        );

# 关联表:
    emp:
        create table emp(
            id int primary key auto_increment,
            name varchar(16),
            age int,
            gender enum(\'male\', \'female\', \'others\') default \'male\',
            dep_id int not null,
            foreign key(dep_id) references dep(id)
        );

# 插入数据:
    - 1.必须先插入被关联表(dep)的数据,再插入关联表(emp)的数据。


    # dep:
        insert into dep(dep_name, dep_desc) values(\'nb_外交部\', \'国际形象大使部门\'),
        (\'sb_教学部\', \'造程序员部门!!!!\'),
        (\'技术部\', \'技术有限部门\');

    # emp:
        insert into emp(name, age, gender, dep_id)
        values(\'tank\', 17, \'male\', 1),
        (\'jason\', 70, \'male\', 2),
        (\'sean\', 50, \'male\', 2),
        (\'egon\', 88, \'male\', 2),
        (\'owen\', 95, \'female\', 3);

        # 报错,
        insert into emp(name, age, gender, dep_id) values(\'大饼\', 100, \'others\', 999);

# 更新数据或删除数据
    - 更新数据
    # 报错
    update emp set dep_id=100 where id=2;
    # 报错
    update dep set id=100 where id=1;

    # 先删除已关联的dep_id字段,才能修改dep表中的关联id字段。
    delete from emp where id=1;
    update dep set id=100 where id=1;

    # 删除: 先删除关联表中的记录,在删除被关联表中的记录
        - 删除emp表中的dep_id为2的记录
        delete from emp where dep_id=2;

        - 再删除dep表中id为2的记录
        delete from dep where id=2;





- 级联更新与级联删除
    - on update cascade
    - on delete cascade
- 创建表
    # 被关联表:
        dep2:
            create table dep2(
                id int primary key auto_increment,
                dep_name varchar(16),
                dep_desc varchar(255)
            );

    # 关联表:
        emp2:
            create table emp2(
                id int primary key auto_increment,
                name varchar(16),
                age int,
                gender enum(\'male\', \'female\', \'others\') default \'male\',
                dep_id int not null,
                foreign key(dep_id) references dep2(id)
                on update cascade
                on delete cascade
            );

- 插入数据
    # dep:
        insert into dep2(dep_name, dep_desc) values(\'nb_外交部\', \'国际形象大使部门\'),
        (\'sb_教学部\', \'造程序员部门!!!!\'),
        (\'技术部\', \'技术有限部门\');

    # emp:
        insert into emp2(name, age, gender, dep_id)
        values(\'tank\', 17, \'male\', 1),
        (\'jason\', 70, \'male\', 2),
        (\'sean\', 50, \'male\', 2),
        (\'egon\', 88, \'male\', 2),
        (\'owen\', 95, \'female\', 3);

        # 报错,
        insert into emp(name, age, gender, dep_id) values(\'大饼\', 100, \'others\', 999);


- 更新数据或删除数据
    - 更新记录
        update dep2 set id=200 where id=1;

    - 删除记录
        delete from dep2 where id=200;

注意: mysql中没有 多对一  只要 一对多

- 多对多:
    也必须站在两张表的位置去思考;

    - 错误示范:
        - 创建book表
            create table book(
                id int primary key auto_increment,
                title varchar(20),
                price int,
                book_content varchar(255),
                author_id int,
                foreign key(author_id) references author(id)
                on update cascade
                on delete cascade
            );

        - 创建author表
            create table author(
                id int primary key auto_increment,
                name varchar(16),
                age int,
                book_id int,
                foreign key(book_id) references book(id)
                on update cascade
                on delete cascade
            );

- 问题: 无法知道哪张表是被关联表


- 利用第三张表,为两张表建立“多对多外键关系”。
    - book:
        create table book(
                id int primary key auto_increment,
                title varchar(20),
                price int,
                book_content varchar(255)
        );

    - author:
        create table author(
                id int primary key auto_increment,
                name varchar(16),
                age int
        );


    - book2author:
        create table book2author(
            id int primary key auto_increment,
            book_id int,
            author_id int,
            foreign key(book_id) references book(id)
            on update cascade
            on delete cascade,
            foreign key(author_id) references author(id)
            on update cascade
            on delete cascade
        );

- 插入数据
    - book
    insert into book(title, price, book_content) values
    (\'金瓶mei\', 199, \'讲述朦胧时光的小故事\'),
    (\'python从入门到断气\', 2000, \'学习如何一夜秃头\'),
    (\'三体\', 200, \'跟着大佬进入宇宙奇幻世界\')
    ;

    - author
    insert into author(name, age) values
    (\'egon\', 68),
    (\'jason\', 88);

    - book2author:
    insert into book2author(book_id, author_id) values
    (1, 1),
    (1, 2),
    (2, 2),
    (3, 1);

    # 报错, 插入的数据,book_id, author_id必须存在
    insert into book2author(book_id, author_id) values (4, 4);

    # 更新或删除
        # 更新
            - update book set price=6666 where id=1;
            - update book set id=4 where id=1;

        # 删除
            - delete from book where id=4;

        - 一对一:
    - 两张之间的关系 一一对应,将一张数据量比较大的表,拆分成两张表。
        - user_info:
            id, name, age, gender, hobby, id_card

        - user:
            id , name, age, detail_id(外键)

        - detail:
            id, gender, hobby, id_card

        user与detail表建立了 一对一的外键 关系。
        foreign key 应该建在 使用频率较高的一方。

    - 创建表
        # 被关联表
        create table customer(
            id int primary key auto_increment,
            name varchar(16),
            media varchar(32)
        );
        # 关联表
        create table student(
            id int primary key auto_increment,
            addr varchar(255),
            phone char(11),
            id_card char(18),

            # 外键必须设置为唯一的
            customer_id int unique,
            foreign key(customer_id) references customer(id)
            on update cascade
            on delete cascade
        );

    - 插入数据
        insert into customer(name, media) values
        (\'hcy\', \'facebook\'),
        (\'zsb1\', \'ig\'),
        (\'zsb2\', \'vk\'),
        (\'hb\', \'探探\');


        insert into student(addr, phone, id_card, customer_id) values
        (\'上海\', \'15214546711\', \'440888888888888888\', 1),
        (\'北京\', \'18888888888\', \'440777777777777777\', 2);

        # 报错,一对一,关系必须 一一对应
        insert into student(addr, phone, id_card, customer_id) values (\'上海\', \'15214546711\', \'440888888888888888\', 1);
了解:

- 修改表的操作

  - 语法:  注意: mysql 关键字不区分大小写

    1. 修改表名

       ALTER TABLE 表名  RENAME 新表名;

    2. 增加字段
       ALTER TABLE 表名
       ADD 字段名 数据类型 [完整性约束条件…],
       ADD 字段名 数据类型 [完整性约束条件…];  # 添加到最后一列

       ALTER TABLE 表名
       ADD 字段名 数据类型 [完整性约束条件…] FIRST;  # 添加到第一列

       ALTER TABLE 表名
       ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;  # 添加到某一列之后

    3. 删除字段
       ALTER TABLE 表名
       DROP 字段名;

    4. 修改字段
       ALTER TABLE 表名
       MODIFY 字段名 数据类型 [完整性约束条件…];  # 修改数据类型

       ALTER TABLE 表名
       CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];  # 修改字段名,保留字段类型

       ALTER TABLE 表名
       CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];  # 修改字段名与字段类型

- 复制表的操作:
  复制表结构+记录 (key不会复制: 主键、外键和索引)
  mysql> create table new_service select * from service;

  只复制表结构

  将select * from service where 1=2; ---> 不要真实数据,需要表结构

  mysql> create table new_customer select * from customer where 1=2;  这个只是复制表的结构

以上是关于MySQL 多键的主要内容,如果未能解决你的问题,请参考以下文章

c#中的多键字典? [复制]

如何在pyspark中使用reduceByKey作为多键和单值[重复]

CoreData:使用 NSPredicate 过滤一对多对多关系(此处不允许错误对多键)

MongoDB——索引类型之多键索引(Multikey Index)

MongoDB——索引类型之多键索引(Multikey Index)

Qt 多键组合事件