一:引擎
引擎決定數據庫存取數據的方式==>不同的特點==>不同的用戶體驗
前提是:引擎是建表時規定,提供給表使用的,不是數據庫
show engines; #展示所有引擎 重點:innodb(默認):支持事務,行級鎖,外鍵 myisam:查詢效率要優於innodb,當不需要支持事務,行級鎖,外鍵,可以通過設置myisam來優化數據庫 具體實現: use db1; create table t1(id int)engine=innodb; create table t2(id int)engine=myisam; create table t3(id int)engine=blackhole; create table t4(id int)engine=memory; insert into t1 values(1); insert into t2 values(1); insert into t3 values(1); insert into t4 values(1); select * from t1; ...
二:創建表完整語法
create table 表名( 字段名1 類型[(寬度) 約束條件], 字段名2 類型[(寬度) 約束條件], 字段名3 類型[(寬度) 約束條件] )engine=innodb charset=utf8; []:表示可選參數
create table db1(name char(3) not null); 數據插入時,name不能為空(null),且最長只能存放三個字符 總結: 寬度和約束條件為可選參數,用來限制存放數據的規則
三:數據庫模式
sql_mode:反映數據庫的全局變量
數據庫模式限制的是客戶端對服務器操作數據的方式(是否嚴格)
兩種模式:
no_engine_substitution;非安全性,默認
strict_trans_table;安全模式
具體操作: 查看當前數據庫模式: show variables like "%sql_mode%"; #匹配0~n個任意字符 ==> 模糊查詢 設置為安全模式: set global sql_mode="strict_trans_table"; 重啟連接(客戶端): quit 應用: create table t1(name char(2)); insert into t1 values("ab"); #正常格式 insert into t1 values("abcd"); #錯誤,過長:Data too long for column 'name' at row 1
四:數據類型
Mysql數據庫支持:整形,浮點型,字符型,時間類型,枚舉類型,集合類型
4.1:整形
類型: tinyint:1字節 -128~127 smallint:2字節 mediumint:3字節 int:4字節 -2147483648~2147483647 bigint:8字節 約束: unsigned:無符號 zerofill:0填充 不同類型所占字節數不一樣,決定所占空間及存放數據的大小限制
例子:
create table t8(x tinyint); insert into t8 values(200); #非安全模式存入,值只能到最大值127 select (x) from t8;
寬度: 1.不能決定整形存放數據的寬度,超過寬度可以存放,最終由數據類型所占字節決定 2.如果沒有超過寬度,且有zerofill限制,會用0填充前置位的不足位 3.沒有必要規定整形的寬度,默認設置的寬度就為該整形能存放數據的最大寬度
例如:
create table t2(x int(5) unsigned zerofill);
insert into t2 values(10);
select * from t2;
例子1: create table t3(x int(5)); insert into t3 values(123456); select (x) from t3; #結果:123456 insert into t3 values(2147483648); select (x) from t3; #結果: 2147483647
create table t10(x int(5) unsigned zerofill); # 區域0~4294967295 insert into t10 values(10); select x from t10; # 結果: 00010 insert into t10 values(12345678900); select x from t10; # 結果: 4294967295
4.2浮點型
類型: float:4字節, 3.4E -38~3.4E+38 double:8字節,1.7E-308~1.7E+308 decimal: M,D 大值基礎上+2 寬度:限制存儲寬度 (M,D)=>M為位數,D為小數位 float(255,30):精度最低,最常用 double(255,30):精度高,占位多 decimal(65,30):字符串存,全精度
例子:
一: create table t5(age float(256,30)); #ERROR 1439 (42000): Display width out of range for column 'age' (max = 255) create table t5 (age float(255, 31)); #ERROR 1425 (42000): Too big scale 31 specified for column 'age'. Maximum is 30. 二: create table t6(age float(256,30)); create table t7(x double(255,30)); create table t8(x decimal(65,30)); insert into t6 values(1.1111111111111111111111111); insert into t7 values(1.1111111111111111111111111); insert into t8 values(1.1111111111111111111111111); select * from t6; #小數據,精度要求不高,均采用float來存儲 select * from t7; select * from t8; alter table t8 modify x decimal(10,5);# 1.11111 => 限制了數據的存儲寬度 結果:見附圖
4.3字符型
類型: char:定長 varchar:不定長 寬度: 限制存儲寬度 char(4):以4個字符存儲以char屬性存儲的數據 varchar(4):數據長度決定字符長度,為可變長度存儲數據
例子:
create table t9(x char(4),y varchar(4)); insert into t9 values("Haru","Lani"); select x,y from t9; +------+------+ | x | y | +------+------+ | Haru | Lani | +------+------+ 1 row in set (0.00 sec)
但是這樣:
insert into t9 values("Grace","Shelly"); #非安全模式數據丟失,可以存放,安全模式報錯
select x,y from t9; #Query OK, 1 row affected, 2 warnings (0.06 sec)可以正常顯示丟失后(不完整)的數據
+------+------+
| x | y |
+------+------+
| Haru | Lani |
| Grac | Shel |
+------+------+
2 rows in set (0.00 sec)
insert into t9 values("a","b"); 驗證數據所在字符長度 前提:安全模式下以空白填充字符 set global sql_mode="strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH"; 重啟連接 select char_length(x),char_length(y) from t9; #a是char,占四個字符,b是varchar,字符是幾個,就占幾個 +----------------+----------------+ | char_length(x) | char_length(y) | +----------------+----------------+ | 4 | 4 | | 4 | 4 | | 1 | 1 | +----------------+----------------+ 3 rows in set (0.05 sec)
重點:存儲數據的方式 ==>數據庫優化
char:一定按規定的寬度存放數據,以規定寬度讀取數據,通常更占空間
varchar:首先根據數據長度計算所需寬度,並在數據開始以數據頭方式將寬度信息保存起來,是一個計算耗時過程,首先讀取寬度信息,以寬度信息為依准讀取數據,通常節省空間。
8: zero egon Grace yanghuhu
8:4zero 4egon 5Grace 8yanghuhu
注:varchar的數據頭占1~2個字節
規定char | varchar寬度均為4,用來存放4個字符的數據,char存取更高效,char占4個字符,varchar占5個字符,char更節省空間
總結:數據長度相近的數據提倡用char來存放數據,數據需要高速存取,以空間換時間,采用char類型。
4.4時間類型
類型: year:yyyy(1901/2155) date:yyyy-MM-dd(1000-01-01/9999-12-31) time:HH:mm:ss datetime:yyyy-MM-dd HH-mm-ss(1970-01-01 00:00:00/2308-01-19 (具體幾點不知道))
一: create table t10(my_year year,my_date date,my_time time); insert into t10 values(); #三個時間類型的默認值均是null insert into t10 values(2156,null,null); #在時間范圍外,不允許插入該條數據 insert into t10 values(1,"2000-01-01 12:00:00",null);# 2001 2000-01-01 null insert into t16 values(2019, '2019-01-08', "15-19-30"); # time報格式錯誤 => 按照時間規定格式存放數據 alter table t16 change my_year myYear year(2); # 時間的寬度修改后還是采用默認寬度 => 不需要關系寬度 二: create table t17(my_datetime datetime, my_timestamp timestamp); insert into t17 values(null, null); # 可以為空, 不能為null,賦值null采用默認值current_timestamp insert into t17 values('4000-01-01 12:00:00', '2000-01-01 12:00:00'); # 在各自范圍內可以插入對應格式的時間數據 # datetime VS timestamp datetime:時間范圍,不依賴當前時區,8字節,可以為null timestamp:時間范圍,依賴當前時區,4字節,有默認值CURRENT_TIMESTAMP
4.5枚舉與集合
類型:
enum:單選
set:多選
create table t19( sex enum('male','female','wasai') not null default 'wasai', # 枚舉 hobbies set('play','read','music') # 集合 ); insert into t19 values (null, null); # sex不能設置null insert into t19 values (); # wasai null insert into t19 (hobbies) values ('play,read'), ('music,play'); # sex采用默認值, 對hobbies字段添加兩條記錄 insert into t19 (sex,hobbies) values ('male,female', 'play'); # sex字段只能單選
4.6約束條件
primary key:主鍵,唯一標識,表都會擁有,不設置為默認找第一個 不空,唯一字段;為標識則創建隱藏字段 foreing key:外鍵 unique key:唯一性數據, 該條字段的值需要保證唯一,不能重復 auto_increment:自增,只能加給key字段輔助修飾 not null:不為空 default:默認值 unsigned:無符號 zerofill:0填充 注: 1.鍵可以提高數據的存取效率,提高io 2.聯合唯一 create table web ( ip char(16), port int, unique(ip,port) ); 3.聯合主鍵 create table web ( ip char(16), port int, primary key(ip,port) );
例子:
# eg:1 # 單列唯一 create table t20 ( id int unique ); # 聯合唯一 create table web ( ip char(16), port int, unique(ip,port) ); # 如果聯合兩個字段,兩個字段全相同才相同,否則為不同 insert into web values ('10.10.10.10', 3306), ('10.10.10.10', 3306);
注:
1.表默認都有主鍵,且只能擁有一個主鍵字段(單列主鍵|符合主鍵)
2.沒有設置主鍵的表,數據庫系統會自上而下將第一個規定為unique not null字段自動提升為primary key 主鍵
3.如果整個表都沒有unique not null 字段且沒有primary key 字段,系統會默認創建一個隱藏字段作為主鍵
4.通常必須手動指定表的主鍵,一般用id字段,且id字段一般類型為int, 因為int類型可以為auto_increment
# eg:2 create table t21(id int auto_increment); # 自增約束必須添加給key的字段 # eg:3 create table t21(id int primary key auto_increment); # 自增要結合key,不賦值插入,數據會自動自增, 且自增的結果一直被記錄保留 # eg:4 # 聯合主鍵 create table t22( ip char(16), port int, primary key(ip,port) ); # 如果聯合兩個字段,兩個字段全相同才相同,否則為不同 insert into web values ('10.10.10.10', 3306), ('10.10.10.10', 3306);