• 15-3 完整性约束介绍


    一 约束条件介绍:
    约束条件与数据类型的宽度一样,都是可选参数

    作用:用于保证数据的完整性和一致性
    主要分为:
    PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录
    FOREIGN KEY (FK) 标识该字段为该表的外键
    NOT NULL 标识该字段不能为空
    UNIQUE KEY (UK) 标识该字段的值是唯一的
    AUTO_INCREMENT 标识该字段的值自动增长(整数类型,而且为主键)
    DEFAULT 为该字段设置默认值

    UNSIGNED 无符号
    ZEROFILL 使用0填充

    二 not null与default
    not null - 不可空
    null - 可空


    默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值
    create table tb1(
    nid int not null defalut 2,
    num int not null
    )

    1 null
    mysql> create table t1(id int);
    Query OK, 0 rows affected (0.50 sec)
    
    mysql> desc t1;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | YES  |     | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    1 row in set (0.01 sec)
    
    mysql> insert into t1 values();
    Query OK, 1 row affected (0.10 sec)


    2 not null

    mysql> create table t2(id int not null);
    Query OK, 0 rows affected (0.64 sec)
    
    mysql> desc t2;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | NO   |     | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    1 row in set (0.00 sec)
    再次插入空报错:
    mysql> insert into t2 values();
    ERROR 1364 (HY000): Field 'id' doesn't have a default value


    3 defalut
    #设置id字段有默认值后,则无论id字段是null还是not null,都可以插入空,插入空默认填入default指定的默认值

    mysql> create table t3(id int default 1);
    mysql> insert into t3 values();
    Query OK, 1 row affected (0.09 sec)
    
    mysql> select * from t3;
    +----+
    | id |
    +----+
    |  1 |
    +----+
    1 row in set (0.00 sec)
    可以再次更改:
    mysql> alter table t3 modify id int not null default 1;

    三 unique唯一,不重复
    1 uniqe:

     创建一个表
    mysql> create table department1(
        -> id int,
        -> name varchar(20) unique,
        -> comment varchar(100)
        -> );
    Query OK, 0 rows affected (0.69 sec)
    
    
     插入数据
    mysql> insert into department1 values(1,'IT','技术');
    Query OK, 1 row affected (0.10 sec)
    再次插入数据报错:
    mysql> insert into department1 values(1,'IT','技术');
    ERROR 1062 (23000): Duplicate entry 'IT' for key 'name'

    2 uniqe和not null 相当于主键 primary key

    mysql> create table t4(id int not null unique);
    Query OK, 0 rows affected (0.61 sec)
    
    mysql> desc t4;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | NO   | PRI | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    1 row in set (0.01 sec)


    3 联合唯一 unique
    mysql> create table service(
        -> id int primary key auto_increment,
        -> name varchar(20),
        -> host varchar(15) not null,
        -> port int not null,
        -> unique(host,port) #联合唯一
        -> );
    Query OK, 0 rows affected (0.69 sec)
    
    插入数据:
    
    insert into service values(1,'nginx','192.168.0.10',80),(2,'haproxy','192.168.0.20',80),(3,'mysql','192.168.0.30',3306);
    再次插入报错:
    mysql> insert into service(name,host,port) values('nginx','192.168.0.10',80);
    ERROR 1062 (23000): Duplicate entry '192.168.0.10-80' for key 'host'



    四 primary key
    从约束角度看primary key字段的值不为空且唯一,那我们直接使用not null+unique不就可以了吗,要它干什么?

    主键primary key是innodb存储引擎组织数据的依据,innodb称之为索引组织表,一张表中必须有且只有一个主键。

    一个表中可以:

    单列做主键
    多列做主键(复合主键)

    1 单列做主键

    方法1:
    mysql> create table t5(id int not null unique,name varchar(20) not null unique,comment varchar(100));
    Query OK, 0 rows affected (0.63 sec)
    
    mysql> desc t5;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | NO   | UNI | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    3 rows in set (0.01 sec)
    
    方法2:在某一个字段后用primary key
    mysql> create table t6(id int primary key unique,name varchar(20),comment varchar(100));
    Query OK, 0 rows affected (0.70 sec)
    
    mysql> desc t6;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | YES  |     | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    3 rows in set (0.01 sec)
    
    方法3:在所有字段后单独定义primary key
    mysql> create table t7(id int,name varchar(20),comment varchar(100),constraint pk_name primary key(id));#创建主键并为其命名pk_name
    Query OK, 0 rows affected (0.64 sec)
    
    mysql> desc t7;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | YES  |     | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    3 rows in set (0.01 sec)


    2 多列做主键(复合主键)

    mysql> create table t8(ip varchar(15),port char(5),service_name varchar(10) not null,primary key(ip,port));
    Query OK, 0 rows affected (0.58 sec)
    
    mysql> desc t8;
    +--------------+-------------+------+-----+---------+-------+
    | Field        | Type        | Null | Key | Default | Extra |
    +--------------+-------------+------+-----+---------+-------+
    | ip           | varchar(15) | NO   | PRI | NULL    |       |
    | port         | char(5)     | NO   | PRI | NULL    |       |
    | service_name | varchar(10) | NO   |     | NULL    |       |
    +--------------+-------------+------+-----+---------+-------+
    3 rows in set (0.01 sec)
    插入数据:
    mysql> insert into t8 values('172.16.45.10','3306','mysqld'),('172.16.45.11','3306','mariadb');
    Query OK, 2 rows affected (0.33 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    再次插入数据报错:
    mysql> insert into service values ('172.16.45.10','3306','nginx');
    ERROR 1136 (21S01): Column count doesn't match value count at row 1

    五 auto_increment

    约束字段为自动增长,被约束的字段必须同时被key约束

    1 不指定id
    mysql> create table student(id int primary key auto_increment,name varchar(20),sex enum('male','female') default 'male');
    Query OK, 0 rows affected (0.96 sec)
    
    mysql> desc student;
    +-------+-----------------------+------+-----+---------+----------------+
    | Field | Type                  | Null | Key | Default | Extra          |
    +-------+-----------------------+------+-----+---------+----------------+
    | id    | int(11)               | NO   | PRI | NULL    | auto_increment |
    | name  | varchar(20)           | YES  |     | NULL    |                |
    | sex   | enum('male','female') | YES  |     | male    |                |
    +-------+-----------------------+------+-----+---------+----------------+
    3 rows in set (0.01 sec)
    
    mysql> insert into student(name) values
        -> ('egon'),
        -> ('alex')
        -> ;
    Query OK, 2 rows affected (0.35 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> select * from student;
    +----+------+------+
    | id | name | sex  |
    +----+------+------+
    |  1 | egon | male |
    |  2 | alex | male |
    +----+------+------+
    2 rows in set (0.00 sec)


    2 指定id

    mysql> insert into student values(4,'taibai','female');
    Query OK, 1 row affected (0.33 sec)
    
    mysql> select * from student;
    +----+--------+--------+
    | id | name   | sex    |
    +----+--------+--------+
    |  1 | egon   | male   |
    |  2 | alex   | male   |
    |  4 | taibai | female |
    +----+--------+--------+
    3 rows in set (0.00 sec)

    3 删除id后,会不会从新开始自增?

    #对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长
    mysql> delete from student;
    Query OK, 3 rows affected (0.37 sec)
    
    mysql> select * from student;
    Empty set (0.00 sec)
    
    mysql> insert into student(name) values('ysb');
    Query OK, 1 row affected (0.09 sec)
    
    mysql> select * from student;
    +----+------+------+
    | id | name | sex  |
    +----+------+------+
    |  5 | ysb  | male |
    +----+------+------+
    1 row in set (0.00 sec)
    
    #如果用truncate是接清空表,那么表的id会从新开始计算
    例子:
    mysql> truncate student;
    Query OK, 0 rows affected (0.54 sec)
    
    mysql> select * from student;
    Empty set (0.00 sec)
    
    mysql> insert into student(name) values('egon');
    Query OK, 1 row affected (0.33 sec)
    
    mysql> select * from student;
    +----+------+------+
    | id | name | sex  |
    +----+------+------+
    |  1 | egon | male |
    +----+------+------+
    1 row in set (0.00 sec)


    六 foreign key 用于关联
    1-1 快速理解foreign key
    1 创建父表
    #表类型必须是innodb存储引擎,且被关联的字段,即references指定的另外一个表的字段,必须保证唯一

    mysql> create table department(
        -> id int primary key,
        -> name varchar(20) not null
        -> )engine=innodb;
    Query OK, 0 rows affected (0.60 sec)

    2 创建子表:
    #dpt_id外键,关联父表(department主键id),同步更新,同步删除

    mysql> create table employee(
        -> id int primary key,
        -> name varchar(20) not null,
        -> dpt_id int,
        -> constraint fk_name foreign key(dpt_id)
        -> references department(id)
        -> on delete cascade
        -> on update cascade
        -> )engine=innodb;
    Query OK, 0 rows affected (0.34 sec)

    分别再插入数据:
    mysql> insert into department values
        -> (1,'欧德博爱技术有限事业部'),
        -> (2,'艾利克斯人力资源部'),
        -> (3,'销售部');
    Query OK, 3 rows affected (0.09 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> insert into employee values
        -> (1,'egon',1),
        -> (2,'alex1',2),
        -> (3,'alex2',2),
        -> (4,'alex3',2),
        -> (5,'李坦克',3),
        -> (6,'刘飞机',3),
        -> (7,'张火箭',3),
        -> (8,'林子弹',3),
        -> (9,'加特林',3)
        -> ;
    Query OK, 9 rows affected (0.19 sec)
    Records: 9  Duplicates: 0  Warnings: 0


    #删父表department,子表employee中对应的记录跟着删

    mysql> delete from department where id=3;
    Query OK, 1 row affected (0.45 sec)
    
    mysql> select * from employee;
    +----+-------+--------+
    | id | name  | dpt_id |
    +----+-------+--------+
    |  1 | egon  |      1 |
    |  2 | alex1 |      2 |
    |  3 | alex2 |      2 |
    |  4 | alex3 |      2 |
    +----+-------+--------+
    4 rows in set (0.00 sec)

    #更新父表department,子表employee中对应的记录跟着改

    mysql> update department set id=22222 where id=2;
    Query OK, 1 row affected (0.37 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> select * from employee;
    +----+-------+--------+
    | id | name  | dpt_id |
    +----+-------+--------+
    |  1 | egon  |      1 |
    |  2 | alex1 |  22222 |
    |  3 | alex2 |  22222 |
    |  4 | alex3 |  22222 |
    +----+-------+--------+
    4 rows in set (0.00 sec)

    2-1 如何找出两张表之间的关系

    分析步骤:
    #1、先站在左表的角度去找
    是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)

    #2、再站在右表的角度去找
    是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)

    #3、总结:
    #多对一:
    如果只有步骤1成立,则是左表多对一右表
    如果只有步骤2成立,则是右表多对一左表

    #多对多
    如果步骤1和2同时成立,则证明这两张表时一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系

    #一对一:
    如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可


  • 相关阅读:
    打造自己的 C# WinForm 应用程序的 SQL Server 连接配置界面
    怎么修改app.config的值
    将DATATABLE中的数据导入到数据库中
    C# 多线程使用progressBar进度条控件
    程序员技术练级攻略2
    c#中Setting.setting的使用
    该行已经属于另一个表
    Microsoft 数据访问技术的过去、现在和未来
    Winform专栏
    在 C# 中使用设置 Settings.settings
  • 原文地址:https://www.cnblogs.com/huningfei/p/9401767.html
Copyright © 2020-2023  润新知