數據庫(四):數據類型


進擊の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)

*****
*****


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM