02 數據庫入門學習-數據類型
一.數據存儲引擎
1.什麽是引擎 ?
引擎是一個功能的核心部分,現實中的引擎可以被分類。從動力來源來說,引擎可以分為汽油、 柴油、電動、混合動力等,需求場景的不同催生了不同的引擎類別。
在數據庫中同樣也是有引擎的。核心功能是存儲數據 涉及到存儲數據的代碼 就稱之為存儲引擎
根據不同的需求,也有著不同的引擎分類。
創建表時在最後指定引擎名稱 engine = xxx
create table t1(id int)engine=innodb create table t2(id int not null)engine=csv create table t3(id int)engine=memory create table t4(id int)engine=blackhole #innodb,默認的引擎,因為它是永久存儲並且支持事務,行鎖,外鍵 #csv,不能為空 #memory,在重啟mysql或者重啟機器後,表內數據清空 #blackhole,往表內插入任何數據,都相當於丟入黑洞,表內永遠不存記錄 insert into t1 value(1); insert into t2 value(1); insert into t3 value(1); insert into t4 value(1); select * from t1;#有值 select * from t2;#有值 select * from t3;#有值 select * from t4;#為空
二.創建表的完整語句
create table 表名(
字段名 數據類型(顯示的長度)約束條件,
字段名 數據類型(顯示的長度)約束條件,
..........
字段名 數據類型(顯示的長度)約束條件
);
mysql> create table s1(a int(19) not null, -> b int(12) not null -> ); mysql> desc s1; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | a | int(19) | NO | | NULL | | | b | int(12) | NO | | NULL | | +-------+---------+------+-----+---------+-------+
註意:①與Python的不同,最後不需要加逗號
②表名、字段名和數據類型都是必須有的
③顯示的長度和約束條件是可選的
④字段名、表名甚至庫名都不能是關鍵字
三.數據類型
1.整型
類型 | 大小 | 範圍(有符號) | 範圍(無符號) |
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 |
默認情況下,整型是有符號的,需要一個二進制位存儲
創建表的時候,給整型加上約束unsigned來表示無符號
create table i1 (id int unsigned);
1.1嚴格模式與非嚴格模式
MySQL自身對數據進行嚴格的校驗(格式、長度、類型等),比如一個整型字段我們寫入一個字符串類型的數據,只有在嚴格模式下MySQL才會報錯,非嚴格模式下不會報錯,對於一些錯誤的輸入,非嚴格模式會用0或空來替代
Mysql處於非嚴格模式下:
如果數據超出範圍
無符號: 例如 tinyint,輸入256,保存的255,最大值;輸入-123,保存0,最小值
有符號 :例如 tinyint,輸入256,保存的127,最大值;輸入-1280,存的是-128,最小值
Mysql處於嚴格模式下:
如果值超出範圍就直接報錯
為了在開發中,我們應該先判斷數據的正確性,所以應該用嚴格模式
查看當前模式 show variables like "sql_mode";
修改為嚴格模式 set global sql_mode = "STRICT_TRANS_TABLES";
1.2 長度限制對於整型的意義
mysql>create table i1(id int(2)); mysql>insert into i1 value(454555); mysql>select *from i1; +--------+ | id | +--------+ | 454555 | +--------+ 1 row in set (0.00 sec)
發現這個數也存儲成功,說明,這裏長度指的不是存儲容量限制,而是顯示的寬度。
如果你的數據超過了顯示寬度,有幾個顯示幾個。
如果不足,則補全到指定長度 得告訴它用什麽來補全。
mysql>create table i1(id int(10) zerofill);#zerofill,用0來補全 mysql> insert into i1 value(12345); mysql> select * from i1; +------------+ | id | +------------+ | 0000012345 | +------------+ 1 row in set (0.00 sec)
總結:
要限制顯示寬度
1.創建表時 給整型加上寬度
2.加上zerofill約束
有符號和無符號的最大數字需要的顯示寬度均為10,而針對有符號的最小值則需要11位才能顯示完全,所以int類型默認的顯示寬度為11是非常合理的
2.浮點型
類型 | 大小 | 範圍(有符號) | 範圍(無符號) |
float(m,d) | 4 |
-3.402823466E+38 to -1.175494351E-38 1.175494351E-38 to 3.402823466E+38 |
1.175494351E-38 to 3.402823466E+38 |
double(m,d) | 8 |
-1.7976931348623157E+308 to -2.2250738585072014E-308 2.2250738585072014E-308 to 1.7976931348623157E+308 |
2.2250738585072014E-308 to 1.7976931348623157E+308 |
decimal(m,d) | 動態 |
m表示 這個浮點數整體的長度
d表示 小數部分的長度
例如: float(5,3) 最大值: 99.999
相同點: float和double的小數部分最大長度都是30
float和double的最大長度為255
不同點: decimal的整體最大長度65
精度不同
double 比 float 精度高
decimal 是準確的 不會丟失精度
代碼驗證
mysql> create table i1(a float(100,20),b double(100,20),c decimal(65,20));
mysql> insert into i1 value(1.111111111111111111111111111111111,
1.11111111111111111111111111111111,
1.1111111111111111111111111);
mysql> select *from i1; +------------------------+------------------------+------------------------+ | a | b | c | +------------------------+------------------------+------------------------+ | 1.11111116409301760000 | 1.11111111111111120000 | 1.11111111111111111111 | +------------------------+------------------------+------------------------+
3.字符型
3.1char 定長字符
char類型的長度是固定 無論你存儲的數據有多長 占用的容量都一樣
char(3) 存儲的數據為 "a" 在硬盤保存的數據還是占3字符長度 實際保存的是"a "
如果你的數據不足指定長度 就在後面用空格補全
在硬盤中存儲的是一連串的二進制,char類型取的時候是按照指定長度。
3.2varchar 變長字符
varchar 長度是可變的 存儲的數據有多長就占用多長
varchar(3) 存儲的數據為 "a" 在硬盤保存的數據還是占1字符長度 實際保存的是"a"
varchar存儲數據時,會在數據前會用1~2Bytes顯示後面的數據的長度,方便取。
vharchar 能支持的最大長度是65535 用於保存數據長度的數據最長兩個bytes
3.3驗證:
使用一個 char_length的函數 可以查看字符的長度
mysql> create table i1(a char(4),b varchar(4)); mysql> insert into i1 value(‘x‘,‘x‘); mysql> select char_length(a),char_length(b) from i1; +----------------+----------------+ | char_length(a) | char_length(b) | +----------------+----------------+ | 1 | 1 | +----------------+----------------+ #兩個字段的長度都為1
3.4結論:
這是因為,mysql在存儲時,自動加上的空格,對使用者而言是沒有意義的,所以mysql自動幫你處理空格了,我們可以設置sql模式 來讓它現出原形。
mysql> set global sql_mode = "PAD_CHAR_TO_FULL_LENGTH,STRICT_TRANS_TABLES";
設置完成後重啟msyql 再次查詢長度
mysql> select char_length(a),char_length(b) from i1; +----------------+----------------+ | char_length(a) | char_length(b) | +----------------+----------------+ | 4 | 1 | +----------------+----------------+
3.5註意:
當你在執行這樣的查詢語句時 mysql會自動將參數末尾的空格去除
mysql> select *from i1 where name = "xcq "; +------+------------+ | id | name | +------+------------+ | 1 | xcq | +------+------------+
當你在使用模糊搜索時 要註意 定長字符 後面可能會有空格 所以最好在後面加上百分號 %
mysql> select *from i1 where name like "xcq%"; +------+------------+ | id | name | +------+------------+ | 1 | xcq | +------+------------+ 1 row in set (0.00 sec) mysql> select *from i1 where name like "xcq"; Empty set (0.00 sec) # % 任意個數的任意字符 # _ 1個任意字符
4.時間和日期
4.1time
時分秒 HH:MM:SS
#手動輸入時分秒 mysql> create table i1 (a time); mysql> insert into i1 value(‘19:32:56‘); mysql> select *from i1; +----------+ | a | +----------+ | 19:32:56 | +----------+ #也可以用now()來獲取當前年月日時分秒 mysql> insert into i1 value(now()); mysql> select *from i1; +----------+ | a | +----------+ | 19:33:41 | +----------+
4.2year
年份
#手動輸入年份 mysql> create table i1 (a year); mysql> insert into i1 value(‘2019‘); mysql> select *from i1; +------+ | a | +------+ | 2019 | +------+ #通過now()獲取當前年月日時分秒 mysql> insert into i1 value(now()); mysql> select *from i1; +------+ | a | +------+ | 2018 | +------+
4.3date
日期 年月日
#手動輸入年月日 mysql> create table i1 (a date); mysql> insert into i1 value(‘2019-1-1‘); mysql> select *from i1; +------------+ | a | +------------+ | 2019-01-01 | +------------+ #通過now()獲取當前年月日時分秒 mysql> insert into i1 value(now()); mysql> select *from i1; +------------+ | a | +------------+ | 2018-09-12 | +------------+
4.4 datetime和timestamp
日期加時間 年月日 時分秒 年份最大是9999
時間戳 從1970-1-1開始算 年份最大是2037
#手動輸入年月日 時分秒 mysql> create table i1 (a datetime);#timestamp mysql> insert into i1 value(‘2019-1-1 1:1:1‘); mysql> select *from i1; +---------------------+ | a | +---------------------+ | 2019-01-01 01:01:01 | +---------------------+ #通過now()獲取當前年月日時分秒 mysql> insert into i1 value(now()); mysql> select *from i1; +---------------------+ | a | +---------------------+ | 2018-09-12 19:43:36 | +---------------------+
4.5總結:
共同點: 時間的存取通過字符串類型
都可以使用now()函數來插入當前時間
datetime 和 時間戳都能夠表示日期和時間
不同之處是: 年份最大範圍不同
時間戳可以為空 代表當前時間
時間戳在你更新記錄時 會自動更新為當前時間
5.枚舉和集合
5.1枚舉
enum,提前設置?個範圍 你的數據只能是 其中之?(多選?) 例如性別
#正確情況 mysql> create table i1 (id int,name char(10),sex enum(‘man‘,‘woman‘,‘othor‘)) mysql> insert into i1 value(1,‘sql‘,‘man‘); mysql> select *from i1; +------+------------+------+ | id | name | sex | +------+------------+------+ | 1 | sql | man | +------+------------+------+ #錯誤示範:不能添加不在枚舉裏的字符 mysql> insert into i1 value(1,‘sql‘,‘123‘);#報錯 ERROR 1064 (42000): You have an error in your SQL syntax check the manual that corresponds to your MySQL server version for the right syntax to use near ‘mysql> insert into i1 value(1,‘sql‘,‘123‘)‘ at line 1
5.2集合
set,提前設置?個範圍 你的數據只能是其 中?部分(多選多) 例如愛好
mysql> create table i1 (id int,name char(10),hobby set(‘eat‘,‘play‘,‘sleep‘)); mysql> insert into i1 value(1,‘sql‘,‘eat,play‘); mysql> select *from i1; +------+------------+----------+ | id | name | hobby | +------+------------+----------+ | 1 | sql | eat,play | +------+------------+----------+
02 數據庫入門學習-數據類型