1. 程式人生 > 實用技巧 >SQL約束

SQL約束

	1. DQL:查詢語句
		1. 排序查詢
		2. 聚合函式
		3. 分組查詢
		4. 分頁查詢

	2. 約束
	3. 多表之間的關係
	4. 正規化
	5. 資料庫的備份和還原

# DQL:查詢語句
	1. 排序查詢
		* 語法:order by 子句
			* order by 排序欄位1 排序方式1 ,  排序欄位2 排序方式2...

		* 排序方式:
			* ASC:升序,預設的。
			* DESC:降序。

		* 注意:
			* 如果有多個排序條件,則當前邊的條件值一樣時,才會判斷第二條件。


	2. 聚合函式:將一列資料作為一個整體,進行縱向的計算。
		1. count:計算個數
			1. 一般選擇非空的列:主鍵
			2. count(*)
		2. max:計算最大值
		3. min:計算最小值
		4. sum:計算和
		5. avg:計算平均值
		

		* 注意:聚合函式的計算,排除null值。
			解決方案:
				1. 選擇不包含非空的列進行計算
				2. IFNULL函式

	3. 分組查詢:
		1. 語法:group by 分組欄位;
		2. 注意:
			1. 分組之後查詢的欄位:分組欄位、聚合函式
			2. where 和 having 的區別?
				1. where 在分組之前進行限定,如果不滿足條件,則不參與分組。having在分組之後進行限定,如果不滿足結果,則不會被查詢出來
				2. where 後不可以跟聚合函式,having可以進行聚合函式的判斷。

			-- 按照性別分組。分別查詢男、女同學的平均分

			SELECT sex , AVG(math) FROM student GROUP BY sex;
			
			-- 按照性別分組。分別查詢男、女同學的平均分,人數
			
			SELECT sex , AVG(math),COUNT(id) FROM student GROUP BY sex;
			
			--  按照性別分組。分別查詢男、女同學的平均分,人數 要求:分數低於70分的人,不參與分組
			SELECT sex , AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex;
			
			--  按照性別分組。分別查詢男、女同學的平均分,人數 要求:分數低於70分的人,不參與分組,分組之後。人數要大於2個人
			SELECT sex , AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex HAVING COUNT(id) > 2;
			
			SELECT sex , AVG(math),COUNT(id) 人數 FROM student WHERE math > 70 GROUP BY sex HAVING 人數 > 2;


			
	4. 分頁查詢
		1. 語法:limit 開始的索引,每頁查詢的條數;
		2. 公式:開始的索引 = (當前的頁碼 - 1) * 每頁顯示的條數
			-- 每頁顯示3條記錄 

			SELECT * FROM student LIMIT 0,3; -- 第1頁
			
			SELECT * FROM student LIMIT 3,3; -- 第2頁
			
			SELECT * FROM student LIMIT 6,3; -- 第3頁

		3. limit 是一個MySQL"方言"


## 約束
	* 概念: 對錶中的資料進行限定,保證資料的正確性、有效性和完整性。	
	* 分類:
		1. 主鍵約束:primary key
		2. 非空約束:not null
		3. 唯一約束:unique
		4. 外來鍵約束:foreign key

	* 非空約束:not null,值不能為null
		1. 建立表時新增約束
			CREATE TABLE stu(
				id INT,
				NAME VARCHAR(20) NOT NULL -- name為非空
			);
		2. 建立表完後,新增非空約束
			ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;

		3. 刪除name的非空約束
			ALTER TABLE stu MODIFY NAME VARCHAR(20);
	
	
	* 唯一約束:unique,值不能重複
		1. 建立表時,新增唯一約束
			CREATE TABLE stu(
				id INT,
				phone_number VARCHAR(20) UNIQUE -- 添加了唯一約束
			
			);
			* 注意mysql中,唯一約束限定的列的值可以有多個null
		
		
		2. 刪除唯一約束
		
			ALTER TABLE stu DROP INDEX phone_number;
		
		3. 在建立表後,新增唯一約束
			ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;
	
	* 主鍵約束:primary key。
		1. 注意:
			1. 含義:非空且唯一
			2. 一張表只能有一個欄位為主鍵
			3. 主鍵就是表中記錄的唯一標識

		2. 在建立表時,新增主鍵約束
			create table stu(
				id int primary key,-- 給id新增主鍵約束
				name varchar(20)
			);

		3. 刪除主鍵
			-- 錯誤 alter table stu modify id int ;
			ALTER TABLE stu DROP PRIMARY KEY;

		4. 建立完表後,新增主鍵
			ALTER TABLE stu MODIFY id INT PRIMARY KEY;

		5. 自動增長:
			1.  概念:如果某一列是數值型別的,使用 auto_increment 可以來完成值得自動增長

			2. 在建立表時,新增主鍵約束,並且完成主鍵自增長
			create table stu(
				id int primary key auto_increment,-- 給id新增主鍵約束
				name varchar(20)
			);

			
			3. 刪除自動增長
			ALTER TABLE stu MODIFY id INT;
			4. 新增自動增長
			ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;


	* 外來鍵約束:foreign key,讓表於表產生關係,從而保證資料的正確性。
		1. 在建立表時,可以新增外來鍵
			* 語法:
				create table 表名(
					....
					外來鍵列
					constraint 外來鍵名稱 foreign key (外來鍵列名稱) references 主表名稱(主表列名稱)
				);

		2. 刪除外來鍵
			ALTER TABLE 表名 DROP FOREIGN KEY 外來鍵名稱;

		3. 建立表之後,新增外來鍵
			ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名稱 FOREIGN KEY (外來鍵欄位名稱) REFERENCES 主表名稱(主表列名稱);
		
		
		4. 級聯操作
			1. 新增級聯操作
				語法:ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名稱 
						FOREIGN KEY (外來鍵欄位名稱) REFERENCES 主表名稱(主表列名稱) ON UPDATE CASCADE ON DELETE CASCADE  ;
			2. 分類:
				1. 級聯更新:ON UPDATE CASCADE 
				2. 級聯刪除:ON DELETE CASCADE 
	

## 資料庫的設計

	1. 多表之間的關係
		1. 分類:
			1. 一對一(瞭解):
				* 如:人和身份證
				* 分析:一個人只有一個身份證,一個身份證只能對應一個人
			2. 一對多(多對一):
				* 如:部門和員工
				* 分析:一個部門有多個員工,一個員工只能對應一個部門
			3. 多對多:
				* 如:學生和課程
				* 分析:一個學生可以選擇很多門課程,一個課程也可以被很多學生選擇
		2. 實現關係:
			1. 一對多(多對一):
				* 如:部門和員工
				* 實現方式:在多的一方建立外來鍵,指向一的一方的主鍵。
			2. 多對多:
				* 如:學生和課程
				* 實現方式:多對多關係實現需要藉助第三張中間表。中間表至少包含兩個欄位,這兩個欄位作為第三張表的外來鍵,分別指向兩張表的主鍵
			3. 一對一(瞭解):
				* 如:人和身份證
				* 實現方式:一對一關係實現,可以在任意一方新增唯一外來鍵指向另一方的主鍵。

		3. 案例
			-- 建立旅遊線路分類表 tab_category
			-- cid 旅遊線路分類主鍵,自動增長
			-- cname 旅遊線路分類名稱非空,唯一,字串 100
			CREATE TABLE tab_category (
				cid INT PRIMARY KEY AUTO_INCREMENT,
				cname VARCHAR(100) NOT NULL UNIQUE
			);
			
			-- 建立旅遊線路表 tab_route
			/*
			rid 旅遊線路主鍵,自動增長
			rname 旅遊線路名稱非空,唯一,字串 100
			price 價格
			rdate 上架時間,日期型別
			cid 外來鍵,所屬分類
			*/
			CREATE TABLE tab_route(
				rid INT PRIMARY KEY AUTO_INCREMENT,
				rname VARCHAR(100) NOT NULL UNIQUE,
				price DOUBLE,
				rdate DATE,
				cid INT,
				FOREIGN KEY (cid) REFERENCES tab_category(cid)
			);
			
			/*建立使用者表 tab_user
			uid 使用者主鍵,自增長
			username 使用者名稱長度 100,唯一,非空
			password 密碼長度 30,非空
			name 真實姓名長度 100
			birthday 生日
			sex 性別,定長字串 1
			telephone 手機號,字串 11
			email 郵箱,字串長度 100
			*/
			CREATE TABLE tab_user (
				uid INT PRIMARY KEY AUTO_INCREMENT,
				username VARCHAR(100) UNIQUE NOT NULL,
				PASSWORD VARCHAR(30) NOT NULL,
				NAME VARCHAR(100),
				birthday DATE,
				sex CHAR(1) DEFAULT '男',
				telephone VARCHAR(11),
				email VARCHAR(100)
			);
			
			/*
			建立收藏表 tab_favorite
			rid 旅遊線路 id,外來鍵
			date 收藏時間
			uid 使用者 id,外來鍵
			rid 和 uid 不能重複,設定複合主鍵,同一個使用者不能收藏同一個線路兩次
			*/
			CREATE TABLE tab_favorite (
				rid INT, -- 線路id
				DATE DATETIME,
				uid INT, -- 使用者id
				-- 建立複合主鍵
				PRIMARY KEY(rid,uid), -- 聯合主鍵
				FOREIGN KEY (rid) REFERENCES tab_route(rid),
				FOREIGN KEY(uid) REFERENCES tab_user(uid)
			);

		
	2. 資料庫設計的正規化
		* 概念:設計資料庫時,需要遵循的一些規範。要遵循後邊的正規化要求,必須先遵循前邊的所有正規化要求

			設計關係資料庫時,遵從不同的規範要求,設計出合理的關係型資料庫,這些不同的規範要求被稱為不同的正規化,各種正規化呈遞次規範,越高的正規化資料庫冗餘越小。
			目前關係資料庫有六種正規化:第一正規化(1NF)、第二正規化(2NF)、第三正規化(3NF)、巴斯-科德正規化(BCNF)、第四正規化(4NF)和第五正規化(5NF,又稱完美正規化)。

		* 分類:
			1. 第一正規化(1NF):每一列都是不可分割的原子資料項
			2. 第二正規化(2NF):在1NF的基礎上,非碼屬性必須完全依賴於碼(在1NF基礎上消除非主屬性對主碼的部分函式依賴)
				* 幾個概念:
					1. 函式依賴:A-->B,如果通過A屬性(屬性組)的值,可以確定唯一B屬性的值。則稱B依賴於A
						例如:學號-->姓名。  (學號,課程名稱) --> 分數
					2. 完全函式依賴:A-->B, 如果A是一個屬性組,則B屬性值得確定需要依賴於A屬性組中所有的屬性值。
						例如:(學號,課程名稱) --> 分數
					3. 部分函式依賴:A-->B, 如果A是一個屬性組,則B屬性值得確定只需要依賴於A屬性組中某一些值即可。
						例如:(學號,課程名稱) -- > 姓名
					4. 傳遞函式依賴:A-->B, B -- >C . 如果通過A屬性(屬性組)的值,可以確定唯一B屬性的值,在通過B屬性(屬性組)的值可以確定唯一C屬性的值,則稱 C 傳遞函式依賴於A
						例如:學號-->系名,系名-->系主任
					5. 碼:如果在一張表中,一個屬性或屬性組,被其他所有屬性所完全依賴,則稱這個屬性(屬性組)為該表的碼
						例如:該表中碼為:(學號,課程名稱)
						* 主屬性:碼屬性組中的所有屬性
						* 非主屬性:除過碼屬性組的屬性
						
			3. 第三正規化(3NF):在2NF基礎上,任何非主屬性不依賴於其它非主屬性(在2NF基礎上消除傳遞依賴)


## 資料庫的備份和還原

	1. 命令列:
		* 語法:
			* 備份: mysqldump -u使用者名稱 -p密碼 資料庫名稱 > 儲存的路徑
			* 還原:
				1. 登入資料庫
				2. 建立資料庫
				3. 使用資料庫
				4. 執行檔案。source 檔案路徑
	2. 圖形化工具: