Python学习之旅—Mysql数据库之数据类型和约束
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习之旅—Mysql数据库之数据类型和约束相关的知识,希望对你有一定的参考价值。
前言
本篇博客我们主要专注于解决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)
;
结语:
本篇博客主要梳理了数据类型相关联的知识点,大家需要重点掌握不同数据类型的约束,下一篇我们将重点梳理使用外键来定义不同表之间的关系。
以上是关于Python学习之旅—Mysql数据库之数据类型和约束的主要内容,如果未能解决你的问题,请参考以下文章