约束条件与数据类型的关系

时间:2022-09-21 11:06:23

创建表___约束条件(语法):
约束条件与数据类型的宽度一样,都是可选参数

作用:用于保证数据的完整性和一致性

一: not null: 不允许传空

default: 默认值

比如创建一个为t11的表:

create table t11(
    id int,
    name char(6),
    sex enum('male','female') not null default 'male'
    );
 
#sex选项只能选择一个,而且不能为空,如果不选默认就指定为male   

往t11表里面插入数据:

insert into t11(id,name) values(1,'egon');
insert into t11(id,name) values(2,'alex');
注意:在创建表时有多个字段,插入数据时要对应着插,
当创建表出现enum时,插入数据的时候需指定.比如id,name指定,sex设置为默认就不用指定.

用select * from t11; 语句查询:

mysql> select * from t1
+------+------+------+
| id   | name | sex  |
+------+------+------+
|    1 | egon | male |
|    2 | alex | male |
+------+------+------+
结果显示:

二: unique:限制字段传入的值是唯一,不能重复

1. 设置唯一约束:

创建表时:

方式一:
create table department(
    id int unique,
    name char(10)unique);
方式二:
create table department(
    id int unique,
    name char(10),
    unique(id),;
    unique(name)
    );

插入数据时方式一样:须确保插入的数据的唯一性.

insert into department values
(1,'IT'),
(2,'Sale');

结果显示如下:

mysql> select * from department;
+------+------+
| id   | name |
+------+------+
|    1 | IT   |
|    2 | Sale |
+------+------+
保证了id,name字段的数据唯一性

==- 延伸扩展: 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)

2:联和唯一:

单独某一个字段重复可以,只要合在一起就不能重复,而且单独和联和唯一可以结合在一起使用.

先来创建表:

create table services(
    id int,
    ip char(15),
    port int,
    unique(id),      #也可单独创建时设置唯一约束
    unique(ip,port)  #创建时联和起来用,
    );
                     #PS:socket应用时ip,port是联和在一起运用的

插入数据:

 insert into services values
 (1,'192.168.11.10',80),
 (2,'192.168.11.10',87),
 (3,'192.168.11.113',80);

结果显示:

mysql> select * from  services;
+------+----------------+------+
| id   | ip             | port |
+------+----------------+------+
|    1 | 192.168.11.10  |   80 |
|    2 | 192.168.11.10  |   87 |
|    3 | 192.168.11.113 |   80 |
+------+----------------+------+

三:primary key (主键) primary又分单列主键,复合主键

作用:组织表的数据,提高查询速度

从约束的角度讲就是: not null unique字段的值不为空且唯一

从存储角度来说我们用的存储引擎,默认用的是innodb

对于innodb存储引擎来说,一张表内必须有一个主键

primary key又分单列主键,复合主键

那么如果建primary key(主键):

1.单列主键:

创建: 通常id设为主键


 create table t17(
     id  int primary key, #意思是说id不能为空
     name char(16)
     );

插入数据:

 insert into t17 values(1,'egon'),(2,'alex');
 
 insert into t17(name) values('wxx'); #这里在插入数据的时候没有插入id号.

显示结果:

mysql> select * from t17;
+----+------+
| id | name |
+----+------+
|  0 | wxx  |
|  1 | egon |
|  2 | alex |
从结果来看:在创建表时.id字段设置为 primary key 不能为空
          在插入数据wxx时,又没有插入id号
结果来看,在没有传入id值时,会默认的加一个id号为0进去
注意: BUT如果你再次插入数据的时候,还是没有将id的值传入时,
     那么就会插入数据失败,因为在不传值给id时,他只会默认将值为0,赋值一次.

mysql> desc t17;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(11)  | NO   | PRI | NULL    |       |
| name  | char(16) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+

2.复合主键:

mysql> insert into t18(name) values
    -> ('alex77888');
ERROR 1062 (23000): Duplicate entry '0' for key 'id'
mysql>  create table t19(
    ->     ip char(15),
    ->     port int,
    ->     primary key (ip,port)
    ->     );
Query OK, 0 rows affected (0.09 sec)

mysql>
mysql>
mysql> insert into t19  values
    -> ('1.1.1.1',80),
    -> ('1.1.1.1',79);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from t19;
+---------+------+
| ip      | port |
+---------+------+
| 1.1.1.1 |   79 |
| 1.1.1.1 |   80 |
+---------+------+
2 rows in set (0.00 sec)

==总结:通常对于innodb存储引擎来说,一张表内必须有一个主键,一般设置id字段为主键.==

四:auto_increment

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

1.不指定id,则自动增长

mysql>
mysql> create table t20(
    ->     id int primary key auto_increment,
    ->     name  char(18)
    ->     );
Query OK, 0 rows affected (0.23 sec)

mysql>
mysql>
mysql>
mysql> insert into t20(name) values
    -> ('egon'),
    -> ('alex'),
    -> ('wxx');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql>
mysql> desc t20;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(18) | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> select * from t20;
+----+------+
| id | name |
+----+------+
|  1 | egon |
|  2 | alex |
|  3 | wxx  |
+----+------+

2.指定id:


mysql> insert into t20(id, name) values
    -> (7,'哈哈哈');   #指定id,让从7开始
Query OK, 1 row affected (0.01 sec)

#再次插入数据时,还是从指定id号7开始往后自增
mysql> insert into t20(name) values
    -> ('egon1'),
    -> ('egon2'),
    -> ('egon3');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

看结果:
mysql> select * from t20;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | egon      |
|  2 | alex      |
|  3 | wxx       |
|  7 | 哈哈哈    |
|  8 | egon1     |
|  9 | egon2     |
| 10 | egon3     |
+----+-----------+
7 rows in set (0.00 sec)

==注意:==

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

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


mysql> delete from t20;
Query OK, 0 rows affected (0.00 sec)

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

mysql>  insert into t20(name) values('xqw');
Query OK, 1 row affected (0.07 sec)

mysql> select * from t20;
+----+------+
| id | name |
+----+------+
| 11 | xqw  |
+----+------+
1 row in set (0.00 sec)

mysql> truncate t20;  
Query OK, 0 rows affected (0.10 sec)

mysql>  insert into t20(name) values('xqw');
Query OK, 1 row affected (0.07 sec)

mysql> select * from t20;
+----+------+
| id | name |
+----+------+
|  1 | xqw  |
+----+------+
1 row in set (0.00 sec)

3.了解知识点:

输入指令:  show variables like 'auto_inc%'; #查看msyql增加配置的变量,像以auto_inc开头的任意字符的所有变量,
会出现:
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1    |    #auto_increment_increment  步长默认为1         
| auto_increment_offset    | 1     |   #auto_increment_offset起始偏移量默认为1
+--------------------------+-------+


如何设置步长:
set  session  auto_increment_increment= 1;  #本次设置有效的步长,
set  global  auto_increment_increment= 5;  #本次全局有效步长,前提是要所有的会话要重新登录,加载一遍才有效.

如果设置起始偏移量:
 set  global auto_increment_offset =3;
 
强调: 起始偏移量要 <= 步长

以下实例,在命令行输入指令设置:
set  global  auto_increment_increment= 5;
set  global auto_increment_offset =3;

之后退出: exit
然后在登录mysql查看是否设置成功:

mysql> show variables like 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 5     |
| auto_increment_offset    | 3     |
+--------------------------+-------+
#显示已经设置成功

下面来进行验证:
创建t21的表:
mysql> create table t21(
    ->     id int primary key auto_increment,
    ->     name  char(18)
    ->     );
Query OK, 0 rows affected (0.10 sec)


插入数据:
mysql> insert into t21(name) values
    -> ('egon3'),
    -> ('alex'),
    -> ('egon7'),
    -> ('wxx');
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

验证插入的数据,id数据信息;
mysql> select * from t21;
+----+-------+
| id | name  |
+----+-------+
|  3 | egon3 |
|  8 | alex  |
| 13 | egon7 |
| 18 | wxx   |
+----+-------+
#从来结果来看已经改变id的起始值和步长数.

那么问题来了,一般情况不这么设置id,假如别人这么设置我如何改回来呢?
直接设置设置起始偏移量和步长为1就好啦,记得要退出重新登录mysql才有效哦!

五: foreign key 处理表与表之间的关联关系

1.建表:

  • 先建被关联的表并保证被关联的字段唯一: 用unique 或 primary key
create table dep(
    id int primary key ,
    name char(16),
    comment char(50)
);
  • 在建关联的表:

指定外键(dep表), 指定删除同步: on delete cascade,更新同步;ou update cascade

说明:在emp表里面新增加一个字段叫部门dep_id关联,只存技术部门的id就可以.就将俩张表建立起关联关系

create table emp(
    id int primary key,
    name char(10),
    sex enum('male','female'),
    dep_id int,   #增加一个关联的字段
    foreign key(dep_id) references dep(id) #关联,我的部门id,关联那张表,关联dep的那个字段#
    on delete cascade  #删除同步
    on update cascade  #更新同步
    );
  1. 插入数据:
#先往被关联表插入记录
insert into dep values
(1,'IT','技术能力有限部门'),
(2,'销售','销售能力有限部门'),
(3,'财务','花钱特别多的部门');
在往关联表插入数据:
insert into emp values
(1,'egon','male',1),
(2,'alex','male',2),
(3,'wupeiqi','female',2),
(4,'ganenjie','male',3),
(5,'wupeiqi','male',2);

3.显示结果:

dep表:
mysql> select * from dep;
+----+--------+--------------------------+
| id | name   | comment                  |
+----+--------+--------------------------+
|  1 | IT     | 技术能力有限部门         |
|  2 | 销售   | 销售能力有限部门         |
|  3 | 财务   | 花钱特别多的部门         |
+----+--------+--------------------------+
emp表:
mysql> select * from emp;
+----+----------+--------+--------+
| id | name     | sex    | dep_id |
+----+----------+--------+--------+
|  1 | egon     | male   |      1 |
|  2 | alex     | male   |      2 |
|  3 | wupeiqi  | female |      2 |
|  4 | ganenjie | male   |      3 |
|  5 | wupeiqi  | male   |      2 |
+----+----------+--------+--------+

4.体现删除同步:


 输入指令删除具体那一条信息: delete from dep where id =1;
 
 结果:
 mysql> select * from emp;  
+----+----------+--------+--------+
| id | name     | sex    | dep_id |
+----+----------+--------+--------+
|  2 | alex     | male   |      2 |
|  3 | wupeiqi  | female |      2 |
|  4 | ganenjie | male   |      3 |
|  5 | wupeiqi  | male   |      2 |
+----+----------+--------+--------+

mysql> select * from dep;
+----+--------+--------------------------+
| id | name   | comment                  |
+----+--------+--------------------------+
|  2 | 销售   | 销售能力有限部门         |
|  3 | 财务   | 花钱特别多的部门         |
+----+--------+--------------------------+

5.体现更新同步:

输入指令更新具体那一条信息:update dep set id=202 where id = 2;

结果:

mysql> select * from dep;
+-----+--------+--------------------------+
| id  | name   | comment                  |
+-----+--------+--------------------------+
|   3 | 财务   | 花钱特别多的部门         |
| 202 | 销售   | 销售能力有限部门         |
+-----+--------+--------------------------+

mysql> select * from emp;
+----+----------+--------+--------+
| id | name     | sex    | dep_id |
+----+----------+--------+--------+
|  2 | alex     | male   |    202 |
|  3 | wupeiqi  | female |    202 |
|  4 | ganenjie | male   |      3 |
|  5 | wupeiqi  | male   |    202 |
+----+----------+--------+--------+

==注意:==

1、foreign key 要慎用,后续扩展非常麻烦;

2、通过应用程序的逻辑层面来实现;

3、涉及到数据库的变动,代码多数要重构;

4、表之间的3种关系——多对一、多多对、一对一.