·MySQL-完整性约束

目录

约束

- not null

- default

- unique

- 单例唯一约束

- 多列唯一约束 

- not null + unique :主键

- auto_increment

- auto_increment_increment : 步长 and 起始偏移量:auto_increment_offset

- primary key

-单列做主键

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

- foreign key

- 多表关系


约束

除了数据类型外额外添加的约束,以保证数据的合法性和完整性。

分类:

  • not null :非空约束,即数据不能为空
  • default:默认值约束,即可指定字段的默认值
  • unique:唯一性约束,即该字段的值不可重复。例:身份证号
  • zerfill :使用0进行填充
  • unsigned :无符号
  • auto_increment :自动增长,通常搭配主键字段使用。
  • primary key:主键约束,用于唯一标识表中一条数据。
  • foreign key:外键约束,用于多表之间建立联系。

- not null

定义:非空约束,即数据不能为空

create table student (id ind,name char(10) not null);

- default

定义:默认值约束,即可指定字段的默认值

create table user (id ind,name char(10) not null,sex char(1) default "woman");

- unique

定义:唯一性约束,即该字段的值不可重复。例:身份证号

  • 1.unique本质是一种索引,是一种数据结构,用于提高查询效率。
  • 2.可以为空。
  • 3.一张表中可以存有多个唯一约束。

- 单例唯一约束

'''方法一'''
create table department1(
id int,
name varchar(20) unique,
comment varchar(100)
);


'''方法二'''
create table department2(
id int,
name varchar(20),
comment varchar(100),
constraint uk_name unique(name)
);

- 多列唯一约束 

create table t6
( idcard char(18),
phonenumber char(11),
unique(idcard,phonenumber) ); # 联合唯一

''' 即:身份证相同 并且 手机号相同(与运算) 则判断重复'''

- not null + unique :主键

mysql> create table t1(id int not null unique);
Query OK, 0 rows affected (0.02 sec)

mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

- auto_increment

定义:自动增长,通常搭配主键字段使用,只能用于整形

'''不指定id,则自动增长'''

create table student(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male'
);

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    |                |
+-------+-----------------------+------+-----+---------+----------------+
mysql> insert into student(name) values
    -> ('name1'),
    -> ('name2')
    -> ;

mysql> select * from student;
+----+-------+------+
| id | name  | sex  |
+----+-------+------+
|  1 | name1 | male |
|  2 | name2 | male |
+----+-------+------+


'''手动指定相应id'''

mysql> insert into student values(4,'111','female');
Query OK, 1 row affected (0.00 sec)

mysql> insert into student values(7,'222','female');
Query OK, 1 row affected (0.00 sec)

mysql> select * from student;
+----+-------+--------+
| id | name  | sex    |
+----+-------+--------+
|  1 | name1 | male   |
|  2 | name2 | male   |
|  4 | 111   | female |
|  7 | 222   | female |
+----+-------+--------+


'''对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长'''

mysql> delete from student;
Query OK, 4 rows affected (0.00 sec)

mysql> select * from student;
Empty set (0.00 sec)

mysql> insert into student(name) values('111');
mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  8 | 111  | male |
+----+------+------+


'''
应该用truncate清空表,比起delete一条一条地删除记录
truncate是直接清空表,在删除大表时用它
'''

mysql> truncate student;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into student(name) values('name');
Query OK, 1 row affected (0.01 sec)

mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  1 | name | male |
+----+------+------+
1 row in set (0.00 sec)

- auto_increment_increment : 步长 and 起始偏移量:auto_increment_offset

#在创建完表后,修改自增字段的起始值

mysql> create table student(
    -> id int primary key auto_increment,
    -> name varchar(20),
    -> sex enum('male','female') default 'male'
    -> );

mysql> alter table student auto_increment=3;

mysql> show create table student;
.......
ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

mysql> insert into student(name) values('name');
Query OK, 1 row affected (0.01 sec)

mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  3 | name | male |
+----+------+------+
row in set (0.00 sec)

mysql> show create table student;
.......
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8


#也可以创建表时指定auto_increment的初始值,注意初始值的设置为表选项,应该放到括号外

create table student(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male'
)auto_increment=3;




#设置步长

sqlserver:自增步长
    基于表级别
    create table t1(
        id int。。。
    )engine=innodb,auto_increment=2 步长=2 default charset=utf8

mysql自增的步长:
    show session variables like 'auto_inc%';
    
    #基于会话级别
    set session auth_increment_increment=2 #修改会话级别的步长

    #基于全局级别的
    set global auth_increment_increment=2 #修改全局级别的步长(所有会话都生效)


#!!!注意了注意了注意了!!!
If the value of auto_increment_offset is greater than that of auto_increment_increment, the value of auto_increment_offset is ignored. 

翻译:如果auto_increment_offset的值大于auto_increment_increment的值,则auto_increment_offset的值会被忽略 ,这相当于第一步步子就迈大了,扯着了蛋
比如:设置auto_increment_offset=3,auto_increment_increment=2




mysql> set global auto_increment_increment=5;
Query OK, 0 rows affected (0.00 sec)

mysql> set global auto_increment_offset=3;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'auto_incre%'; #需要退出重新登录
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+



create table student(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male'
);

mysql> insert into student(name) values('name1'),('name2'),('name3');
mysql> select * from student;
+----+-------+------+
| id | name  | sex  |
+----+-------+------+
|  3 | name1 | male |
|  8 | name2 | male |
| 13 | name3 | male |
+----+-------+------+

- primary key

约束角度看,主键字段的值不为空且唯一。但主键主要是innodb存储引擎组织数据的依据。

一张表中必须有且只有一个主键。

-单列做主键

============单列做主键===============

'''方法一:not null+unique'''

create table department1(
id int not null unique, #主键
name varchar(20) not null unique,
comment varchar(100)
);

mysql> desc department1;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | NO   | UNI | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.01 sec)


'''方法二:在某一个字段后用primary key'''

create table department2(
id int primary key, #主键
name varchar(20),
comment varchar(100)
);

mysql> desc department2;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | YES  |     | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.00 sec)


'''方法三:在所有字段后单独定义primary key'''

create table department3(
id int,
name varchar(20),
comment varchar(100),
constraint pk_name primary key(id); #创建主键并为其命名pk_name

mysql> desc department3;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | YES  |     | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.01 sec)

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

复合主键 :表的主键含有一个以上的字段组成 
比如 
create table test 

   name varchar(19), 
   id number, 
   value varchar(10), 
   primary key (name,id) 


上面的name和id字段组合起来,就是表的复合主键 
因为name字段可能会出现重名,所以要加上ID字段这样就可以保证记录的唯一性 
一般情况下,主键的字段长度和字段数目要越少越好 

==================多列做主键================

create table service(
ip varchar(15),
port char(5),
service_name varchar(10) not null,
primary key(ip,port)
);


mysql> desc service;
+--------------+-------------+------+-----+---------+-------+
| 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.00 sec)


mysql> insert into service values
    -> ('172.16.45.10','3306','mysqld'),
    -> ('172.16.45.11','3306','mariadb')
    -> ;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0


mysql> insert into service values ('172.16.45.10','3306','nginx');
ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'

- foreign key

定义:外键约束,用于多表之间建立联系。

- 多表关系

  1. 一对一:表A的一条记录唯一对应表B的一条记录,反之亦然。
    例:一个人对应一个身份证,一个身份证代表一个人。
    foreign key(A字段) references B(id) # A字段和外键的字段一定要保证unique
  2. #一定是student来foreign key表customer,这样就保证了:
    #1 学生一定是一个客户,
    #2 客户不一定是学生,但有可能成为一个学生
    
    
    create table customer(
    id int primary key auto_increment,
    name varchar(20) not null,
    qq varchar(10) not null,
    phone char(16) not null
    );
    
    
    create table student(
    id int primary key auto_increment,
    class_name varchar(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 student(class_name,customer_id) values
    ('3班',3),
    ('1期',4),
    ('2期',5)
    ;

    2.一对多(多对一):表A中的多条数据对应表B中的一条数据,则A的外键是B字段。
                   例:一个出版社出版多本不同的书。

  3. =====================多对一=====================
    create table press(
    id int primary key auto_increment,
    name varchar(20)
    );
    
    create table book(
    id int primary key auto_increment,
    name varchar(20),
    press_id int not null,
    foreign key(press_id) references press(id)
    on delete cascade
    on update cascade
    );
    
    
    insert into press(name) values
    ('北京工业地雷出版社'),
    ('人民音乐不好听出版社'),
    ('知识产权没有用出版社')
    ;
    
    insert into book(name,press_id) values
    ('九阳神功',1),
    ('九阴真经',2),
    ('九阴白骨爪',2),
    ('独孤九剑',3),
    ('降龙十巴掌',2),
    ('葵花宝典',3)
    ;

    3.多对多:表A的多条信息对应表B的一条信息,且,表B的多条信息对应表A的一条信息。
          例如:一个作者可以写多本书,一本书可以有多个作者。
        注:解决多对多需求方法:建立一个中间表,分别外键联系AB表,将两边主键序号一一对应。

    =====================多对多=====================
    create table author(
    id int primary key auto_increment,
    name varchar(20)
    );
    
    
    #这张表就存放作者表与书表的关系,即查询二者的关系查这表就可以了
    
    create table author2book(
    id int not null unique auto_increment,
    author_id int not null,
    book_id int not null,
    constraint fk_author foreign key(author_id) references author(id)
    on delete cascade
    on update cascade,
    constraint fk_book foreign key(book_id) references book(id)
    on delete cascade
    on update cascade,
    primary key(author_id,book_id)
    );
    
    
    #插入四个作者,id依次排开
    
    insert into author(name) values('author1'),('author2'),('author3'),('author4');
    
    #每个作者与自己的代表作如下
    
    1 author1: 
          1 九阳神功
          2 九阴真经
          3 九阴白骨爪
          4 独孤九剑
          5 降龙十巴掌
          6 葵花宝典
    
    
    2 author2: 
          1 九阳神功
          6 葵花宝典
    
    3 author3:
          4 独孤九剑
          5 降龙十巴掌
          6 葵花宝典
    
    4 author4:
          1 九阳神功
    
    
    insert into author2book(author_id,book_id) values
    (1,1),
    (1,2),
    (1,3),
    (1,4),
    (1,5),
    (1,6),
    (2,1),
    (2,6),
    (3,4),
    (3,5),
    (3,6),
    (4,1)
    ;

     

 

你可能感兴趣的:(MySQL)