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