1. 程式人生 > 其它 >資料庫基本資料型別及約束條件

資料庫基本資料型別及約束條件

目錄

概要

1、儲存引擎

​ MyISAM

​ InnoDB

​ memory

​ blackhole

2、MySQL基本資料型別

​ 1、整型

​ 2、浮點型

​ 3、字元型別

​ 4、日期型別

​ 5、列舉與集合型別

3、約束條件

​ unsigned

​ zerofill

​ not null

​ default

​ unique

​ primary key

1、儲存引擎

  • 1、什麼是儲存引擎

​ 儲存引擎可以簡單的理解為處理資料的方式。

  • 2、如何檢視儲存引擎

命令:show engines;

  • 3、四個重要的搜尋引擎
# 儲存引擎簡介
1、MyISAM
	MySQL5.5之前預設的儲存引擎
    	優點:存取速度相比於InnoDB更快
    	缺點:不支援事務、行級鎖和外來鍵,針對資料的操作相對於InnoDB來說安全性較差   
2、InnoDB
	MySQL5.5之後預設的儲存引擎
    	優點:支援事務、行級鎖和外來鍵,針對資料的操作相對於MyISAM來說更加安全
    	缺點:存取資料的速度相較於MySQL來說較慢
3、memory
	執行與記憶體之中,基於記憶體存取資料
    	速度最快,但是斷電即丟失
4、blackhole
	寫入其中的資料都會立刻消失,可以看成是垃圾處理站

  • 儲存引擎建立表的不同點
1、使用四種不同的引擎建立表
    	create table t1(id int) engine=myisam;
    	create table t2(id int) engine=innodb;
    	create table t3(id int) engine=memory;
    	create table t4(id int) engine=blackhole;
2、往每個表中插入資料
	insert into t1 values(1);
    	insert into t2 values(1);
    	insert into t3 values(1);
    	insert into t4 values(1);
  • 檢視每個表中的資料
1.從以上的實驗可以看出,blackhole儲存引擎確實是存進去的資料立即消失,

類似垃圾處理站。

2.想要證明memory確實是基於記憶體來存取資料斷電即丟失需要對MySQL服務

端進行重啟,實驗結果如下。

由於我用的MySQL版本是5.6,所以可以在不指定儲存引擎建立表格,

可以看出預設使用的是innodb,實驗結果如下。

  • 儲存引擎在建立表的不同
MyISAM會建立三個檔案

	.frm	表結構檔案

	.MYD	表資料檔案

	.MYI	表索引檔案(索引的作用是加快資料的查詢)

InnoDB會建立兩個檔案

	.frm	表結構檔案

	.ibd	表資料和索引檔案

memory會建立一個檔案

	.frm	 表結構檔案

blackhole會建立一個檔案

	.frm	表結構檔案

  結論:從以上情況也可以得出,MyISAM相較於InnoDB儲存引擎來說,存取速度相對較快,原因就在於,MyISAM儲存引擎的每個表文件都是獨立分開的,所以在存取速度上要更加的快捷

2、MySQL基本資料型別之整型

  • 整型型別介紹
1、MySQL資料型別之整型

    分類:tinyInt smallint int bigint
    區別:不同的int型別能夠儲存的數字範圍是不一樣的
    數字範圍比較:tinyint < smallint < int < bigint

2、注意事項
    1、針對是否存在正負號的問題(正負號需要佔一個位元位)
    2、針對手機號碼,只能用bigint # 由於手機號位數都是11位,但是int只有十位,所以儲存手機號只能用bigint
  • 數值範圍區分
  • 研究預設情況下是否需要正負號
1、建立表格
	create table t6(id tinyint);
    	create table t7(id smallint);
    	create table t8(id int);
    	create table t9(id bigint);
2、插入資料
	insert into t6 values(-999),(999);
    	insert into t7 values(-999),(999);
    	insert into t8 values(-999),(999);
    	insert into t9 values(-111111111111111),(111111111111111);

結論:所有的int型別預設都需要正負號

3、MySQL基本資料型別之浮點型

  • 浮點型型別介紹
1、MySQL資料型別之浮點型

    	分類:float double decimal
        	基本語法格式:
            	float(255,30)	# 總共255位,小數佔30位
            	double(255,30)	# 總共255位,小數佔30位
            	decimal(65,30)	# 總共65位,小數佔30位

  • 研究三者的區別
1、利用三種資料型別建立三張表
	create table t10(id float(255,30));
    	create table t11(id double(255,30));
    	create table t12(id decimal(65,30));
2、插入資料
	insert into t10 values(1.111111111111111111111);
    	insert into t11 values(1.111111111111111111111);
    	insert into t12 values(1.111111111111111111111);

 結論:從下面的結果中可以看出,三種類型的精確度不同:float < double < decimal

至於使用哪一個,分情況而定
  一般情況下小數點後面只需要保留兩位,一次你float就足夠了
  如果是一些對於精度要求較高的作業,則需要考慮其他的
# 注:有時候很多看似用數字儲存的資料,可能都是存的字串
# ps:python本身對數字的精確度並不敏感,之所以能夠從事人工智慧這一類高精度作業,其原因得益於功能強大的模組

4、M有SQL基本資料型別之字元型別

  • 字元型別介紹
1、MySQL基本資料型別之字元型別

    分類:char、varchar
    特徵描述
  	char(4):定長型別,最多隻能存四個字元,多了報錯,少了自動用空格填充為4個
        	varchar(4):變長型別,最多隻能存四個字元,多了報錯,少了有幾個則存幾個
    '''
    但是有一點需要注意的是,針對MySQL5.6版本,超出範圍不會報錯,而是自動幫你擷取並儲存,但是這種行為是不合理的,因此在研究該特性時,需要保留該特性
    '''
    方式1:修改配置檔案(永久)
    方式2:命令修改環境變數(暫時性)
    	show variables like '%mode%';  # 展示所有帶mode的環境變數
        	set session  # 當前視窗有效
        	set global  # 當前服務端有效
        	完整修改命令:
          	set global sql_mode = 'strict_trans_tables';
        	# 修改完畢之後退出客戶端重新進入即可,這樣就會實現我們上述所說的超過報錯的情況
  • 研究超過字元長度時報錯的情況
1、使用char和varchar建立兩張表
	create table t13(name char(4));
    	create table t14(name varchar(4));
2、往表中新增超過字元長度的資料
	insert into t13 values('jason');
    	insert into t14 values('jason');

可以看出再不修改時,是不會報錯的

下面實驗修改後的情況

  • 研究定長與變長的特性
1、往表中插入未達到指定長度的字元
	insert into t13 values('j');
    	insert into t14 values('j');

# 統計某個欄位資料的長度 
select char_length(欄位名) from 表名,where 篩選條件;

  從上面的資料我們會發現,char所存取的應該是4,但是為什麼也是1?

  其實這是因為,mysql在往硬碟上存資料時,確實是補了相應的空格數來實現定長,但是在取出來的時候會自動把補加的空格再去掉,所以展示我們的就是1個字元長度,其實這是可以用修改環境變數sql_mode去改變的

# 命令:
	set global sql_mode ='srtricts_trans_tables,pad_char_to_full_length'
# 這裡需要注意一點,再修改環境變數時,新設定的會把原來的覆蓋,所以要想增加,就要把原來設定好的也加上



'''
在設定好環境變數以後,退出當前客戶端並重新進入,有一點需要注意,設定完環境變數以後,我們之前插入的資料是不受影響的,所以這裡使用另外一條命令,清空表裡的資料
	命令格式:truncate table 表名;該命令清空表資料後會保留表結構
'''

1、設定完環境變數就,重啟客戶端,並清空原來的表
	truncate table t13;
    	truncate table t14;
2、重新插入資料
	insert into t13 values('j');
    	insert into t14 values('j');
3、再檢視對應欄位的字元長度
	select char_length(name) from t13;
    	select char_length(name) from t14;

從以上執行截圖就可以看出,char確實是定長型別,varchar是變長型別。

  • char與varchar的對比
char
	優點:整存整取,存取速度快
    	缺點:消耗儲存空間
varchar
	優點:節約儲存空間
    	缺點:存取速度相對於char較慢

'''
	1、在上面我們研究了char與varchar的主要特徵:
		定長型別與變長型別,這一點就決定了對儲存空間的使用情況,varchar比char更節省空間
	2、整存整取以及存取速度的快慢又是什麼造成的
		當我們利用char與varchar分別往硬碟上儲存不同長度的字元時,
		char:char的定長特性決定了在存的時候按照固定長度存,取的時候
				按照固定長度取,這樣對於資料的存取就比較明朗了起來。
		varchar:由於varchar是變長型別,在存的時候是根據每條資料的長度來存,
				但是取的時候就無法去判斷每條資料的初始長度,為了解決這個問題,varchar
				採用了報頭的概念,即給每條資料加上固定一個位元組的報頭來記錄每條資料的長度
		varchar在存的時候:先計算每條資料的長度(即將計算後的資料長度存於報頭裡)
				取的時候:先獲取報頭裡的資料(即獲取每條資料的原始長度)
'''
# 到底使用char還是varchar
	在以前,幾乎使用的都是char,而現在很多情況下都是使用varchar,這是由於varchar的相容性更好,
	也即是由於varchar的變長特性決定的

    	進了公司之後 會通過郵件你每個欄位的英文名和中文名及型別等專案的諸多資訊

 # 補充:在建立欄位的時候可以為每個欄位新增備註
	命令格式:create table 表名(
    		欄位名1,欄位型別1 comment '欄位名中文註釋'
        		欄位名2,欄位型別2comment '欄位名中文註釋'
    		);

5、整形中括號內數字的作用

從上面的圖中會引出一個問題,整型int括號內的11是幹什麼用的?
	在上面講char與varchar時,我們知道,括號內的數字是來限制數字的長度的,
    	那麼,整型中括號內的數字又是幹什麼的?

'''
	在整型中括號內的數字並不是用來限制儲存數字的長度的,
	而是用來控制展示的數字長度的
	我們在以後定義整型的時候,不需要自己新增數字,使用預設的就可以了。

'''
  • 研究整型括號內數字的作用
1、建立一個新的表格,並設定展示的長度,同時利用zerofill約束條件(這個下面細說,這裡先說明一下,zerofill的作用是,不夠的位置用0來填充)
	create table t1(id int(4) zerofill);
2、插入資料
	insert into t1 values(4);

實驗結果如下

結論:整型是比較特殊的存在,是唯一一個不需要限制儲存長度的型別

6、MySQL基本資料型別之列舉與集合

  • 列舉與集合簡介
# 列舉:多選一
	關鍵字:enum()  # 只能從括號內給出的資料選擇
    	示例:
    	create table user(
        	id int ,
            	name varchar(32),
            	gender enum('male','female','others')
        	);
# 集合:多選多(包含多選一)
	關鍵字:set()  # 只能從括號中給出的資料選擇
    	示例:
    	create table userinfo(
        	id int,
            	name varchar(32),
            	hobby set('sing','dance','rap')
        	);
  • 研究列舉與集合的多多選一和多選多特性
1、使用列舉與集合分別建立兩張不同的表
	create table user(
    	id int,
        	name varchar(32),
        	gender enum('male','female','others')
    	);
    create table userinfo(
    	id int,
        	name varchar(32),
       	hobby set('sing','dance','rap')
    	);
 2、往表中新增資料
    1、往user表中體驗價資料時,新增的資料在enum括號內,且只新增一個
    	insert into user values(1,'json','male');
    3、往userinfo表中新增資料時,新增的資料不在set括號內
    	insert into userinfo values(2,'tony','basketball');
    4、往userinfo表中新增資料時,新增的資料在set括號內,且一次性為多個
    	insert into userinfo values(2,'tom','sing,dance,rap');

實驗結果如下

結論:列舉型別只能多選一,集合可以多選多或者多選一,但是選擇資料都必須是在括號記憶體在的資料,否則就會新增失敗,出現warning。

7、MySQL基本資料型別之日期型別

1、日期型別關鍵字

    date	年月日
    datetime	年月日時分秒
    time	時分妙
    year	年
2、示例
	以學生基本資訊表為例
	create table student(
    	id int,
        	name varchar(32),
        	reg_time date,
        	birth datetime,
        	study_time time,
        	join_time year
    	);
    	新增學生基本資訊
	insert into student values(1,'jason','2022-2-22','2022-2-22 22:22:22','22:22:22','2022');

實驗結果如下

8、MySQL建立表的完整語法

# 完整語法結構
create table 表名(
	欄位名1 欄位型別1(數字) 約束條件,
    	欄位名2 欄位型別2(數字) 約束條件,
    	欄位名3 欄位型別3(數字) 約束條件
    	....
    	);

# 注意事項
	1、欄位名和欄位型別是必須要有的
    	2、數字和約束條件是可算的,並且約束條件可以有多個,且用空格隔開即可
    	3、最後一個語句的結尾不要加逗號,否則會報錯

9、MySQL裡的約束條件

# MySQL裡的約束條件相當於在欄位型別的基礎之上新增的額外約束,例如我們上面所講的zerofill

# 約束條件簡介
	zerofill	多餘的使用數字0填充
    	unsingned	讓數字沒有正負號
    	not null	非空
    	default		預設值
    	unique		唯一值
    	primary key	主鍵
    	zuto_increment	自增
# 新增表資料的方式
	方式1:按照欄位順序一一傳值
    	isnert into 表名 values();
        	例如:insert into t1 values(1,'jason');
    方式2:自定義傳值順序,甚至可以不傳
    	insert into 表名(欄位名) values(根據前面的欄位名傳值);
        	例如:insert into t1(name,id) values('jason',1)
        	且可以不傳值
        	insert into t1(id) values(1);
	#注:在MySQL中不傳資料,會使用關鍵字NULL填充,意即為空,類似於python中的None
  • not null(非空)
not null	非空

    示例:
    	create table t2(
        	id int,
            	name varchar(32) not null
        	);
	insert into t2(name,id) values('jason',1);

結論:設定為非空的欄位必須要傳值

  • default(預設值)
default	預設值
	示例:
    	create table t3(
        	id int,
            	name varchar(32) not null,
            	gender enum('male','female','others') default 'male'
        	);
	insert into t3(name,id) values('jason',1);

結論:所有的欄位都可以設定預設值,使用者可以不給該欄位傳值,則使用預設的,若傳值,則使用使用者傳的值

  • unsingned(讓數字沒有正負號)
unsingned	讓數字沒有正負號
	示例:
    	create table t4(
        	id tinyint unsigned
        	);
	insert into t4 values(-999),(999);

結論:設定為unsigned的欄位,將忽略正負號,一般顯示為正數

  • unique(唯一值)
unique	唯一值
	# 在以後建立表時,可能會存在資料相同的情況,這時候就需要設定一個唯一值來便於存取資料。
	1、單列唯一
    	create table t15(
        	id int,
            	name varchar(32) unique
        );
	insert into t5(name,id) values('jason',1);
    # 聯合唯一的意思是,若不希望有出現重複的兩組資料a和b,即a可以重複,b可以重複,但是a和b不能同時重複
    2、聯合唯一
    	crete table t5(
        	id int,
            	name varchar(32),
            	student_id bigint,
            	unique(id,student_id)
        	);
	insert into t5 values(1,'jason',17113710101);

單列唯一

聯合唯一

結論:唯一值的存是為了更好的去標識表中的資料,便於資料的存取

  • primary key(主鍵)
prinmary key	主鍵
	
   	# 主鍵的存在從約束層面上來說,相當於是not null+unique(非空且唯一),在此基礎上,還可以加快資料的查詢
    '''
    	InnoDB規定了一張表有且必須只有一個主鍵
    		因為InnoDB是通過主鍵的方式構造表的,若沒有設定主鍵
    	情景1:沒有主鍵和其他約束條件
    		InnoDB會採用隱藏的欄位作為主鍵,但是這種並不能加快資料的查詢
    	情景2:沒有主鍵但是有非空且唯一的欄位
    		會自動將該欄位升級為主鍵
    '''
    示例:
    	create table t16(
        	id int not null unique,
            	age int not null unque
        );

結論:以後在建立表的時候一定要設定主鍵,並且主鍵欄位一般是表的id欄位

  • auto_increment(自增)
auto_increment	自增

	'''
		由於主鍵一般都是類似於資料的唯一標識,並且主鍵一般都是數字型別
		我們在新增資料的時候,若資料量過多,很容易就會忘記接下來的序號是多少,而且這樣操作太麻煩,於是我們可以用自增這條屬性來實現我們的需求
	'''
    示例;
    	create table t17(
       		id int ptinmary key auto_increment,
            	name varchar(32)
        );

結論:在使用自增特性時,帶有自增約束的主鍵(一般是表的id欄位)可以不用插入主鍵欄位對應的值,會自動從1開始自增,每次加1

10、自增的特性

1、在研究完自增如何使用以後,我們把表裡的資料刪除以後會發現,自增並沒有消失,那麼如何解決這個問題,這裡介紹兩個刪除表資料的方法
	方式1;delete from 表名 # 無法影響到自增
    	方式2:truncate 表名  # 清空表資料且重置主鍵值,並保留表結構
2、結論
	因此,如果想要在刪除表資料以後,同時重置表中的主鍵值,可以用truncate關鍵字,而delete只是單純的刪除資料,不會影響到主鍵

使用delete刪除表資料

使用truncate刪除表資料