• python 之 数据库(字段的约束条件,表之间的关系)


    10.6 约束条件

    10.61 not null 、default

    create table t15(
        id int,
        name char(16) not null,
        sex enum('male','female','other') not null default "male"
    );
    #alter table t15 modify name char(16) not null;
    insert into t15(id,name) values
    (1,'egon1'),
    (2,'egon2'),
    (3,'egon3');
    ​
    mysql> desc t15;
    +-------+-------------------------------+------+-----+---------+-------+
    | Field | Type                          | Null | Key | Default | Extra |
    +-------+-------------------------------+------+-----+---------+-------+
    | id    | int(11)                       | YES  |     | NULL    |       |
    | name  | char(16)                      | NO   |     | NULL    |       |
    | sex   | enum('male','female','other') | NO   |     | male    |       |
    +-------+-------------------------------+------+-----+---------+-------+
    ​
    mysql> select * from t15;
    +------+-------+------+
    | id   | name  | sex  |
    +------+-------+------+
    |    1 | egon1 | male |
    |    2 | egon2 | male |
    |    3 | egon3 | male |
    +------+-------+------+

    10.62 unique

    mysql中存在一种专门的数据结构,叫 key,又称为索引,通过该数据结构可以减少 i/o 次数,从而加速查询效率 index key : 只有加速查询的效果,没有约束的功能 unique key:不仅有加速查询的效果,还附加了一种约束的功能 primary key:不仅有加速查询的效果,还附加了一种约束的功能,并且innodb存储引擎会按照主键字段的值 来组织表中所有的数据,所以一种inndob表中必须有、而且只能有一个主键,通常为该表的id字段

    unique:限制字段的值的唯一性,单从约束角度去看:唯一性约束

    #单列唯一
    create table t16(
        id int unique,
        name char(16)
    );
    ​
    # 联合唯一(不能完全相同)
    create table server(
        id int unique,
        ip char(15),
        port int,
        unique(ip,port)
    );
    mysql> desc server;
    +-------+----------+------+-----+---------+-------+
    | Field | Type     | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id    | int(11)  | YES  | UNI | NULL    |       |
    | ip    | char(15) | YES  | MUL | NULL    |       |
    | port  | int(11)  | YES  |     | NULL    |       |
    +-------+----------+------+-----+---------+-------+
    insert into server values(1,'1.1.1.1',3306),(2,'1.1.1.1',3307),(3,'1.1.1.2',3306);
    mysql> select * from server;
    +------+---------+------+
    | id   | ip      | port |
    +------+---------+------+
    |    1 | 1.1.1.1 | 3306 |
    |    2 | 1.1.1.1 | 3307 |
    |    3 | 1.1.1.2 | 3306 |
    +------+---------+------+

    10.63 primary key

    primary key:单单从约束角度去看,primary key就等同于 not null + unique 强调: 1、一张表中必须有,并且只能有一个主键 2、一张表中都应该有一个id字段,而且应该把id字段做成主键

    create table t17(
        id int primary key,
        name char(16),
        age int,
        sex char(6)
    )engine=innodb;
    ​
    ​
    #联合主键(不完全相同,但不能为空)
    create table t19(
        ip char(15),
        port int,
        primary key(ip,port)
    );
    mysql> desc t19;
    +-------+----------+------+-----+---------+-------+
    | Field | Type     | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | ip    | char(15) | NO   | PRI |         |       |
    | port  | int(11)  | NO   | PRI | 0       |       |
    +-------+----------+------+-----+---------+-------+

    10.64 auto_increment

    只能给被约束成key的字段加自增属性,默认起始位置是1,步长也为1

    # primary key auto_increment
    create table t20(
        id int primary key auto_increment,
        name char(16)
    )engine=innodb;
    ​
    mysql> insert t20(name) values('egon1');
    mysql> insert t20(name) values('egon2');
    mysql> select * from t20;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | egon1 |
    |  2 | egon2 |
    +----+-------+

    10.7 表关系

    10.71 多对一(foreign key)

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

    • 表的组织结构复杂不清晰

    • 浪费空间

    • 扩展性极差

      2、寻找表与表之间的关系的方法: 举例:emp表 dep表 步骤一: part1: 1、先站在左表emp的角度 2、去找左表emp的多条记录能否对应右表dep的一条记录

      part2: 1、站在右表dep的角度 2、去找右表dep的多条记录能否对应左表emp的一条记录 3、如何实现? 在emp表中新增一个dep_id字段,该字段指向dep表的id字段

      4、foreign key会带来什么样的效果?

    约束1:在创建表时,先建被关联的表dep,才能建关联表emp

    create table dep(
        id int primary key auto_increment,
        dep_name char(10),
        dep_comment char(60)
    );
    mysql> desc dep;
    +-------------+----------+------+-----+---------+----------------+
    | Field       | Type     | Null | Key | Default | Extra          |
    +-------------+----------+------+-----+---------+----------------+
    | id          | int(11)  | NO   | PRI | NULL    | auto_increment |
    | dep_name    | char(10) | YES  |     | NULL    |                |
    | dep_comment | char(60) | YES  |     | NULL    |                |
    +-------------+----------+------+-----+---------+----------------+
    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)
    );
    mysql> desc emp;
    +--------+-----------------------+------+-----+---------+----------------+
    | Field  | Type                  | Null | Key | Default | Extra          |
    +--------+-----------------------+------+-----+---------+----------------+
    | id     | int(11)               | NO   | PRI | NULL    | auto_increment |
    | name   | char(16)              | YES  |     | NULL    |                |
    | gender | enum('male','female') | NO   |     | male    |                |
    | dep_id | int(11)               | YES  | MUL | NULL    |                |
    +--------+-----------------------+------+-----+---------+----------------+

    约束2:在插入记录时,必须先插被关联的表dep,才能插关联表emp

    insert into dep(dep_name,dep_comment) values
    ('sb教学部','sb辅导学生学习,教授python课程'),
    ('外交部','形象大使'),
    ('nb技术部','nb技术能力有限部门');
    mysql> select * from dep;
    +----+-------------+-------------------------------------------+
    | id | dep_name    | dep_comment                               |
    +----+-------------+-------------------------------------------+
    |  1 | sb教学部    | sb辅导学生学习,教授python课程            |
    |  2 | 外交部      | 形象大使                                  |
    |  3 | 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 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 |
    +----+---------+--------+--------+

    约束3:更新与删除都需要考虑到关联与被关联的关系(不能直接改变dep表的id) 解决方案:

    1、先删除关联表emp,再删除被关联表dep,准备重建
    mysql> drop table emp;
    mysql> drop table dep;
    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技术能力有限部门');
    mysql> select * from dep;
    +----+------------------+------------------------------
    | id | dep_name         | dep_comment                  |
    +----+------------------+------------------------------
    |  1 | sb教学部         | sb辅导学生学习,教授python课程 |
    |  2 | 外交部           | 形象大使                      |
    |  3 | 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 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 |
    +----+------------------+--------+--------+
    ​
    # 同步删除
    mysql> delete from dep where id=1;
    mysql> select * from dep;
    +----+------------------+------------------
    | id | dep_name         | dep_comment     |
    +----+------------------+------------------
    |  2 | 外交部           | 形象大使          |
    |  3 | nb技术部         | nb技术能力有限部门 |
    +----+------------------+------------------
    mysql> select * from emp;
    +----+------------------+--------+--------+
    | id | name             | gender | dep_id |
    +----+------------------+--------+--------+
    |  2 | egon             | male   |      2 |
    |  5 | wenzhou          | female |      3 |
    +----+------------------+--------+--------+
    ​
    #同步更新
    mysql> update dep set id=200 where id =2;
    mysql> select * from dep;
    +-----+------------------+----------------
    | id  | dep_name         | dep_comment   |
    +-----+------------------+----------------
    |   3 | nb技术部         | nb技术能力有限部|
    | 200 | 外交部           | 形象大使        |
    +-----+------------------+----------------
    mysql> select * from emp;
    +----+------------------+--------+--------+
    | id | name             | gender | dep_id |
    +----+------------------+--------+--------+
    |  2 | egon             | male   |    200 |
    |  5 | wenzhou          | female |      3 |
    +----+------------------+--------+--------+
    View Code

    10.72 多对多(foreign key)

    1、什么是多对多 两张表之间是一个双向的多对一关系,称之为多对多 2、如何实现? 建立第三张表,该表中有一个字段是fk左表的id,还有一个字段是fk右表的id

    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);
    insert into author(name) values
    ('egon'),
    ('alex'),
    ('wxx');
    mysql> select * from author;
    +----+------+
    | id | name |
    +----+------+
    |  1 | egon |
    |  2 | alex |
    |  3 | wxx  |
    +----+------+
    insert into book(bname,price) values
    ('python从入门到入土',200),
    ('葵花宝典切割到精通',800),
    ('九阴真经',500),
    ('九阳神功',100);
    mysql> select * from book;
    +----+-----------------------------+-------+
    | id | bname                       | price |
    +----+-----------------------------+-------+
    |  1 | python从入门到入土          |   200 |
    |  2 | 葵花宝典切割到精通           |   800 |
    |  3 | 九阴真经                    |   500 |
    |  4 | 九阳神功                    |   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),(3,3),(3,4);
    mysql> select * from author2book;
    +----+-----------+---------+
    | id | author_id | book_id |
    +----+-----------+---------+
    |  1 |         1 |       3 |
    |  2 |         1 |       4 |
    |  3 |         2 |       2 |
    |  4 |         2 |       4 |
    |  5 |         3 |       1 |
    |  6 |         3 |       2 |
    |  7 |         3 |       3 |
    |  8 |         3 |       4 |
    +----+-----------+---------+

    10.73 一对一(unique+foreign key)

    一对一:左表的一条记录唯一对应右表的一条记录,反之也一样
    
    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);
    insert into customer(name,qq,phone) values
    ('李飞机','31811231',13811341220),
    ('王大炮','123123123',15213146809),
    ('守榴弹','283818181',1867141331),
    ('吴坦克','283818181',1851143312),
    ('赢火箭','888818181',1861243314),
    ('战地雷','112312312',18811431230);
    mysql> select * from customer;
    +----+-----------+-----------+-------------+
    | id | name      | qq        | phone       |
    +----+-----------+-----------+-------------+
    |  1 | 李飞机    | 31811231  | 13811341220 |
    |  2 | 王大炮    | 123123123 | 15213146809 |
    |  3 | 守榴弹    | 283818181 | 1867141331  |
    |  4 | 吴坦克    | 283818181 | 1851143312  |
    |  5 | 赢火箭    | 888818181 | 1861243314  |
    |  6 | 战地雷    | 112312312 | 18811431230 |
    +----+-----------+-----------+-------------+
    insert into student(class_name,customer_id) values
    ('python',3),('java',4),('c++',5);
    mysql> select * from student;
    +----+-------------+-------------+
    | id | class_name  | customer_id |
    +----+-------------+-------------+
    |  1 | python     |           3 |
    |  2 | java       |           4 |
    |  3 | c++        |           5 |
    +----+-------------+-------------+
  • 相关阅读:
    创建你的 /proc 文件
    在 /proc 里实现文件
    使用 /proc 文件系统
    printk函数速率限制
    printk函数打开和关闭消息
    printk 函数消息是如何记录的
    mysql存储程序
    Javascript 笔记与总结(1-1)作用域
    Java实现 LeetCode 142 环形链表 II(二)
    Java实现 LeetCode 142 环形链表 II(二)
  • 原文地址:https://www.cnblogs.com/mylu/p/11285625.html
Copyright © 2020-2023  润新知