数据库(四):数据类型

进击のpython

*****

数据库——数据类型


数据库的数据类型主要是针对这几点进行讲解:

数值类型,日期类型,字符串类型,枚举与集合类型

学完之后相信你就能够对int和char有个更清晰的了解!


数值类型

整数类型

整型:tinyint smallint mediumint int bigint

小数:float:位数短不准

​ double:位数长不准

​ decimal:贼准

作用:存储年龄,等级,id,各种号码等... ...

其实这些类型仅仅是代表着数字的范围不同

类型 大小 范围(有符号) 范围(无符号)
tinyint 1字节 (-128,127) (0,255)
smallint 2字节 (-32768,32767) (0,65535)
mediumint 3字节 (-8388608,8388607) (0,16777215)
int 4字节 (-2147483648,2147483647) (0,4294967295)
bigint 8字节 (-9223372036854775808,9223372036854775807) (0,18446744073709551615)
float 4字节 (-2147483648,2147483647) (0,4294967295)
double 8字节 (-9223372036854775808,9223372036854775807) (0,18446744073709551615)
decimal

int的范围是2**(4*8-1),因为符号占一个位,所以减一,那当没有符号的时候就是2**(4*8)-1

要是存储的数据超过限定值呢???

mysql> create table t1(id tinyint);
Query OK, 0 rows affected (0.93 sec)

mysql> show tables;
+----------------+
| Tables_in_text |
+----------------+
| t1             |
+----------------+
1 row in set (0.08 sec)

mysql> desc t1;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | tinyint(4) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.51 sec)

mysql> insert into t1 values(-129),(128);
Query OK, 2 rows affected, 2 warnings (0.58 sec)
Records: 2  Duplicates: 0  Warnings: 2

mysql> select * from t1;
+------+
| id   |
+------+
| -128 |
|  127 |
+------+
2 rows in set (0.01 sec)

可以看到,当存储的值超过了限定值,那么就会存储边缘值入库

也可以设定没有符号:create table t2(id tinyint unsigned);

mysql> create table t2(id tinyint unsigned);
Query OK, 0 rows affected (1.01 sec)

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

mysql> insert into t2 values(-129),(1000);
Query OK, 2 rows affected, 2 warnings (0.43 sec)
Records: 2  Duplicates: 0  Warnings: 2

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

mysql> select * from t2;
+------+
| id   |
+------+
|    0 |
|  255 |
+------+
2 rows in set (0.00 sec)

结果也如我们预想一样~

那么坑就来了! char(数字)这么写过,那int(数字也是可以的)

int(数字)是可存储最大的数位对吧

我们来试一下create table t3(id int(1)); 应该是存一位数:

mysql> create table t3(id int(1));
Query OK, 0 rows affected (1.18 sec)

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

确实也像我们想的这样的表结构

现在就往里面填信息:

mysql> insert into t3 values(10000);
Query OK, 1 row affected (0.38 sec)

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

存没存进去????

原来啊,这个数值类型比较特殊,后面设置的数字,叫做显示宽度,存储位数根本就无法修改!

这个特性是数值类型特有的!!!!!!!别的不是这样的!!!!!

为了让你更深的理解,再说一个 zerofill 意思是用0填充

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

mysql> insert into t4 values(1);
Query OK, 1 row affected (0.39 sec)

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

为什么是显示宽度呢?在这里显示宽度为5,不够宽度,前面用0占位

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

mysql> select * from t4;
+------------+
| id         |
+------------+
|      00001 |
| 4294967295 |
+------------+
2 rows in set (0.00 sec)

当数据超过五位,那该存什么数据还是什么数据~~

当然你也应该留意过,不写的时候有个默认的长度10

因为最大位数就是10位!机智吧~~所以以后就不用指定了

小数没什么说的,这里就提一下就行:小数都有两个参数,第一个是最大数字总数,第二个是最大小数位数

float:总数255位 小数30位,前面不准确

double:总数255位 小数30位,后面不准确,更精确

decimal:总数65位,小数30位,一直准确,本质存的是字符串

日期类型

create table student(id int,name char(5),born_year year,birth_date date,class_time time,reg_time datetime);

mysql> create table student(id int,name char(5),born_year year,birth_date date,class_time time,reg_time datetime);
Query OK, 0 rows affected (0.83 sec)

mysql> desc student;
+------------+----------+------+-----+---------+-------+
| Field      | Type     | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| id         | int(11)  | YES  |     | NULL    |       |
| name       | char(5)  | YES  |     | NULL    |       |
| born_year  | year(4)  | YES  |     | NULL    |       |
| birth_date | date     | YES  |     | NULL    |       |
| class_time | time     | YES  |     | NULL    |       |
| reg_time   | datetime | YES  |     | NULL    |       |
+------------+----------+------+-----+---------+-------+
6 rows in set (0.06 sec)

这样就创建好了一个student表

接下来填数据

insert into student values (1,'ponny',now(),now(),now(),now());

mysql> select * from student;
+------+-------+-----------+------------+------------+---------------------+
| id   | name  | born_year | birth_date | class_time | reg_time            |
+------+-------+-----------+------------+------------+---------------------+
|    1 | ponny |      2019 | 2019-08-31 | 09:53:32   | 2019-08-31 09:53:32 |
+------+-------+-----------+------------+------------+---------------------+
1 row in set (0.00 sec)

now()是MySQL提供的获取当前时分秒年月日的方法,此时表的数据类型是year,代表着只接受年这个数据

当然你也可以自己插入,一个一个传值的那种,就不写了

当然除了datetime,还有一种时间类型叫做timestamp,那这两个方法到底有什么区别呢?

第一点就在于支持的时间不同,datetime的日期范围是1001——9999年,timestamp支持1970——2038年

第二点就是datetime存储数据占八个字节,timestamp占四个字节,所以datetime虽然占空间,但是考虑到时间的范围

还是选择datetime更好一点

那既然知道区别了,下面就研究一下各个数据类型的特点吧:

YEAR:YYYY(1901/2155)

DATE:YYYY-MM-DD(1001-01-01/9999-12-31)

TIME:HH:MM:SS('838:59:59'/'838:59:59')

DATETIME:YYYY-MM-DD HH:MM:SS(1001-01-01 00:00:00/9999-12-31 23:59:59)

TIMESTAMP:YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 某时)

字符类型

这个类型只需要了解两个就行,一个是char,一个是varchar

char指的是定长的字符,varchr指的是变长的字符

create table t5(name char(5));

create table t6(name varchar(5));

(这个括号里的数字可是实打实的规定存储字符的长度)

在这就要开始解释什么是定长,什么是变长了

定长就决定了,如果传的字符不够五个,就用空格给我补上

变长就决定了,如果传的字符不够五个,传的什么放进去什么

我们可以验证一下:

insert into t5 values("he");

insert into t6 values("he");

直接select吗?我觉得不是很行(你可以试一下),因为不够的字符都是空格补充的

你想知道有多少个空格是属于数据库的是很难的

所以我们才采用一种迂回的办法,查看返回值的长度

select char_length(name) from t5;

select char_length(name) from t6;

mysql> select char_length(name) from t5;
+-------------------+
| char_length(name) |
+-------------------+
|                 2 |
+-------------------+
1 row in set (0.00 sec)

mysql>
mysql> select char_length(name) from t6;
+-------------------+
| char_length(name) |
+-------------------+
|                 2 |
+-------------------+
1 row in set (0.00 sec)

但是这个MySQL很骚,骚就骚在,数据存储的时候有空格,当你查看的时候,就把空格去掉了

那为了不让去掉应该有的空格,我们需要设置一下SQL

SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';

这会再执行查看语句就会发现他“原形毕露”!

mysql> select char_length(name) from t5;
+-------------------+
| char_length(name) |
+-------------------+
|                 5 |
+-------------------+
1 row in set (0.00 sec)

mysql>
mysql> select char_length(name) from t6;
+-------------------+
| char_length(name) |
+-------------------+
|                 2 |
+-------------------+
1 row in set (0.00 sec)

再多说一句,存储数据的时候会自动的把末尾的空格去掉,看清楚是末尾的!!

而在模糊查询的时候就不会去掉了,这个我们后面说

那定长和边长变长到底有什么区别呢?

如果我想存一组数据 ponny18女学生

利用char存起来就应该是:

ponny|18 |女 |学生 |

当我想拿的时候就是五个五个一取,没有问题

但是对于varchar来说,就没办法,因为变长,导致存的数据不知道多长,就可能会取到18女这种数据

所以,变长在存取数据的同时,在前面还专门的用一个字符来存储这个数据的长度

5+ponny|2+18|1+女|2+学生

官网上的图解是这样的:

所以说,单纯的说char比varchar浪费空间是不对的,如果正好在限制值上,char反而会更省空间

而且,一个字节最多存储255个数,也就意味着,字符的长度超过255个,varchar要再产生一个字节来存储个数

同时字符类型的存储是有长度上限的,所以像存储那些大的数据,一般存储的是个链接,然后指向另一个服务器

一个专门存放文件之类大文件的服务器

总结一下:char存储更快,但是占地有点大,由于现在更追求速度,所以最好使用char!

枚举类型&集合类型

枚举类型就是一堆里选一个当做数据

create table t7(id int,name char(6),sex enum('male','female'));

mysql> create table t7(id int,name char(6),sex enum('male','female'));
Query OK, 0 rows affected (1.00 sec)

mysql> desc t7;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id    | int(11)               | YES  |     | NULL    |       |
| name  | char(6)               | YES  |     | NULL    |       |
| sex   | enum('male','female') | YES  |     | NULL    |       |
+-------+-----------------------+------+-----+---------+-------+
3 rows in set (0.04 sec)

对表进行赋值:

mysql> insert into t7 values(1,'ponny','male');
Query OK, 1 row affected (0.39 sec)

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

那要是传的不是规定的数据呢?

mysql> insert into t7 values(2,'tony','other');
Query OK, 1 row affected, 1 warning (0.08 sec)

mysql> select * from t7;
+------+-------+------+
| id   | name  | sex  |
+------+-------+------+
|    1 | ponny | male |
|    2 | tony  |      |
+------+-------+------+
2 rows in set (0.00 sec)

可以看到,如果传的值不规范,就不会将该数据记录在表中

而集合类型就是多选多

mysql> alter table t7 add (hobby set("sing","dance","Rap"));
Query OK, 0 rows affected (1.34 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc t7;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type                      | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id    | int(11)                   | YES  |     | NULL    |       |
| name  | char(6)                   | YES  |     | NULL    |       |
| sex   | enum('male','female')     | YES  |     | NULL    |       |
| hobby | set('sing','dance','Rap') | YES  |     | NULL    |       |
+-------+---------------------------+------+-----+---------+-------+
4 rows in set (0.05 sec)

mysql> insert into t7 values(3,"Tom","male","dance,Rap");
Query OK, 1 row affected (0.37 sec)

mysql> select * from t7;
+------+-------+------+-----------+
| id   | name  | sex  | hobby     |
+------+-------+------+-----------+
|    1 | ponny | male | NULL      |
|    2 | tony  |      | NULL      |
|    3 | Tom   | male | dance,Rap |
+------+-------+------+-----------+
3 rows in set (0.00 sec)

*****
*****
原文地址:https://www.cnblogs.com/jevious/p/11438170.html