Python学习之旅—Mysql数据库之数据类型和约束

时间:2022-09-21 11:32:27

前言

   本篇博客我们主要专注于解决Mysql数据库中的数据类型和约束,将重点聚焦于字符类型,日期类型,集合类型和主键和unique等知识点,希望各位可以好好掌握今天的知识点。

一.整数类型

#整数类型:TINYINT SMALLINT MEDIUMINT INT BIGINT
#作用:存储年龄,等级,id,各种号码等
#ps:默认都是有符号的
关于整数类型,我们需要关注一点,即整形的宽度指的是显示宽度,而不是存储宽度
我们来看看如下的例子:

create table t1(id int(1));
insert into t1 values(256111);
select * from t1;

create table t2(id int(20));
insert into t2 values(256111);
select * from t2;

create table t3(id int(20) zerofill);
insert into t3 values(256111);
select * from t3;

mysql> create table t4(id int);
Query OK, 0 rows affected (0.46 sec)

mysql> desc t4;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.02 sec)

mysql> insert into t4 values(1111111111111111111111111111111111111111111);
Query OK, 1 row affected, 2 warnings (0.17 sec)

mysql> select * from t4;
+------------+
| id |
+------------+
| 2147483647 |
+------------+
1 row in set (0.00 sec)


mysql> create table t5(id int unsigned);
Query OK, 0 rows affected (0.45 sec)

mysql> desc t5;
+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | YES | | NULL | |
+-------+------------------+------+-----+---------+-------+
1 row in set (0.01 sec)

mysql> insert into t5 values(11111111111111111111111111111111111111111);
Query OK, 1 row affected, 2 warnings (0.05 sec)

mysql> select * from t5;
+------------+
| id |
+------------+
| 4294967295 |
+------------+
1 row in set (0.00 sec)

二.浮点数类型

浮点类型主要分为三种:FLOAT,DOUBLE,DECIMAL;其主要用来标识体重,薪资,价格等属性

mysql> create table t6(weight float(256,56) unsigned);
ERROR 1425 (42000): Too big scale 56 specified for column 'weight'. Maximum is 30.

mysql> create table t6(weight float(256,30) unsigned);
ERROR 1439 (42000): Display width out of range for column 'weight' (max = 255)

mysql> create table t6(weight float(255,30) unsigned);
Query OK, 0 rows affected (0.37 sec)

mysql> desc t6;
+--------+------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------------+------+-----+---------+-------+
| weight | float(255,30) unsigned | YES | | NULL | |
+--------+------------------------+------+-----+---------+-------+
1 row in set (0.01 sec)

mysql> create table t7(weight double(256,33) unsigned);
ERROR 1425 (42000): Too big scale 33 specified for column 'weight'. Maximum is 30
mysql> create table t7(weight double(256,30) unsigned);
ERROR 1439 (42000): Display width out of range for column 'weight' (max = 255)
mysql> create table t7(weight double(255,30) unsigned);
Query OK, 0 rows affected (0.36 sec)


mysql> create table t8(weight decimal(66,33) unsigned);
ERROR 1425 (42000): Too big scale 33 specified for column 'weight'. Maximum is 30.
mysql> create table t8(weight decimal(66,30) unsigned);
ERROR 1426 (42000): Too big precision 66 specified for column 'weight'. Maximum is 65.
mysql> create table t8(weight decimal(65,30) unsigned);
Query OK, 0 rows affected (0.39 sec)

三.日期类型

日期类型主要分为如下五种: DATE:2017-11-11 出生年月日 TIME:10:14:11 上课时间 DATETIME:2017-11-11 10:14:11 注册时间,文章发布时间,员工入职时间 TIMESTAMP:2017-11-11 10:14:11 YEAR :1970 出生年  我们来验证下: CREATE DATABASE day47; use day47; create table t10( born_date DATE, class_time TIME, reg_time DATETIME, born_year YEAR ); INSERT INTO t10 VALUES ('1999-11-11', '08:30:00', '2017-03-01 11:11:11', 1992);============================================== 下面我们来看看datetime与timestamp的区别: create table t11( x datetime, y timestamp ); desc t11; mysql> desc t11; +-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| x     | datetime  | YES  |     | NULL              |                             |
| y     | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
2 rows in set (0.01 sec) 从上面的信息可知,timestamp默认是不能传空,其默认值是当前的时间戳;而datetime是可以传空的。 我们来验证下: mysql> insert into t11 values(null,null); Query OK, 1 row affected (0.04 sec) mysql> select * from t11; +------+---------------------+
| x    | y                   |
+------+---------------------+
| NULL | 2017-10-23 10:25:07 |
+------+---------------------+
1 row in set (0.00 sec) 从上面的信息可知,当我们为timestamp传递空值时,其默认值是当前的时间。  实际使用我们使用的还是datetime.

四.字符类型

char类型: 范围:0-255 特点: 定长,简单粗暴,浪费空间(待存储的数据长度<宽度限制),存取速度快 varchar类型: 范围:0-21844 特点: 变长,精准,节省空间(待存储的数据长度<宽度限制),存取速度慢
注意:如果我们需要存储的是定长的字段,推荐使用char,例如IP地址;而且当我们使用where条件进行过滤时,由于它的存取速度比较
快,所以更加适合使用where条件来过滤。如果是一些不定常的字段,而且不会使用到where条件进行过滤时,推荐使用varchar(),例如
关于某件商品的评价等等。

五.枚举与集合类型

枚举与集合类型往往对应这样的需求,例如某些字段的值是固定的几个,例如性别,男或者女,此时我们就可以将性别这个字段设定
为枚举类型;使用enum关键字修饰;再例如,用户的字段属性可能有多个值,其他用户属性可以从这几个值中选取几个作为自己的值。
例如以用户权限表为例子,管理员具有查看学生,修改学生表,创建学生记录的功能,而班主任只能查看学生记录,此时如果需要定义具体的
权限,我们就可以将权限描述字段定义为一个集合即可。
create table t18( id
int, name char(10), sex enum('male','female','None') # 表示只能从集合中取一个值 ); # 修改表的结构,表示不能传递空,默认是male alter table t18 modify sex enum('male','female','None') not null default 'male'; insert into t18 values(1,'egon','xxxxx'); insert into t18(id,name) values(1,'egon'); 下面我们来关注下set集合:表示多选,例如下面的例子中我为hobbies设置值时,可以从里面选择多个值进行组合。 create table t19( id int, name char(10), hobbies set('music','read','basketball','football','eat','sleep') ); insert into t19 values(1,'egon','music,read,eat');

六.字段的约束

KEY: primay key 主键,一个表中只能有一个主键,主键的意思就是非空且唯一 unique 定义该字段的值唯一 【001】我们设置一个整形字段直接自增,会报错:提示只能有一个自增长的字段,要么是unique key,要么是primary key
mysql
> create table t20(id int auto_increment,name char(10)); ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key create table t20(id int primary key auto_increment,name char(10)); create table t21(id int not null unique auto_increment,name char(10)); 比较t20和t21这两张表,我们发现primary key和not null unique是等同的 【002】下面我们来验证下,一张表中是否可以建立多个主键 create table t22( id int primary key, name char(10) ); create table t23( id int, name char(10), constraint pri_id primary key(id) # 在字段定义完毕后,再来限制它为主键,这里pri_id给约束起一个名字 ); 上面的方式也可以像如下的方式这样写(实际中我们还是直接在定义字段的时候就指定主键) create table t24( id int, name char(10), primary key(id) ); 下面我们演示直接加入unique key,下面两种方式均可以 create table t25( id int, name char(10), constraint uni_id unique(id) ); create table t26( id int, name char(10), unique(id) ); #只能有一个主建,但是可以有多个not null unique # 创建如下这张表时会报错,因为一张表中只能存在一个主键 create table t27( id int, name char(10), primary key(id), primary key(name) ); 一张表中可以有多个not null unique create table t28( id int not null unique, name char(10) not null unique ); DESC t28; 虽然可以存在多个not null unique,但是最终只有一个成为了主键,只有ID成为了主键 即如果你在定义一个表时,没有使用primary key定义主键,那么默认就用第一个not null unique修饰的字段作为主键 表中不一定需要存在主键 我们最后来看一个联合唯一的主键 需求:现在我使用t29来存储一个服务信息, 为了保证每个服务是独立的,我需要保证该服务所对应的IP地址和端口的组合不一样 IP地址可以一样,只要端口不一样即可,这就设计到联合唯一的概念。我们可以将 ip和端口设置为一个联合主键 #联合唯一 create table t29( id int, ip char(15), # 由于IP地址是固定的长度,所以我们推荐使用char类型 port int, primary key(ip,port) ); insert into t29 values (1,'1.1.1.1',3306), (2,'1.1.1.2',3306), (3,'1.1.1.1',8080) ; 现在问题来了,这样设置不合理,因为ID这个字段应该是自增的,用来标识此时到了多少条记录 既然是自增的,那么就要将它设置为一个key,要么是primary key,要么是unique key; 通常ID字段设置为primary key,我们通常查询表时,都是通过ID字段来作为查询依据,这涉及到 MySQL的优化机制。像上面的那样,如果设置将IP和port设置为primary key,以后查询就很不方便。 而同时我们又要保证ip和port的组合不为空且唯一,所以只能将其设置为unique。 这样设置完毕后,就可以保证ip和port是联合唯一的,但主键不是它们两个 create table t30( id int primary key auto_increment, ip char(15) not null, port int not null, unique(ip,port) ); desc t30; 此时我们可以得知ip和port就是联合唯一的,下面我们插入值就可以使用如下的方式啦,非常方便: insert into t30(ip,port) values ('1.1.1.1',3306), ('1.1.1.1',3307), ('1.1.1.2',3307) ;

结语:

   本篇博客主要梳理了数据类型相关联的知识点,大家需要重点掌握不同数据类型的约束,下一篇我们将重点梳理使用外键来定义不同表之间的关系。