MySQL part2

日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度學習實戰(不定時更新)


 

1.mysql數據庫的登錄的服務:
	1.用戶登錄:mysql  -u  用戶名  -p  密碼
	   可選參數:(默認連接本地服務器,可以省略下面兩個參數)
		-h  hostNameIP地址
		-P  port端口號

	2.格式:mysql  -u賬戶  -p密碼  -h數據庫服務器安裝的主機  -P數據庫端口
  		 mysql -uroot -padmin -h127.0.0.1 -P3306
  		若連接的數據庫服務器在本機上,並且端口是3306。
  		則可以簡寫: mysql -uroot -padmin

	3.啓動/停止MySQL服務:

2.SQL語句:
	1.SQL語句的分類:(關鍵字不區分大小寫)
		1.DDL、DCL、DML、DQL:
			1.DDL:數據定義語句,用來定義數據庫對象:數據庫,表,列等。關鍵字:create,alter,drop等
			2.DCL:數據控制語句,用來定義數據庫的訪問權限和安全級別,及創建用戶。
			3.DML:數據操作語句,用來對數據庫中表的記錄進行更新。關鍵字:insert,delete,update等
			4.DQL:數據查詢語句,用來查詢數據庫中表的記錄。關鍵字:select,from,where等 
 
		2.SQL包含6個部分:
			1.數據查詢語言(DQL):
				其語句,也稱爲“數據檢索語句”,用以從表中獲得數據,確定數據怎樣在應用程序給出。
				保留字SELECT是DQL(也是所有SQL)用得最多的動詞,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。
				這些DQL保留字常與其他類型的SQL語句一起使用。
			2.數據操作語言(DML):
				其語句包括動詞INSERT,UPDATE和DELETE。它們分別用於添加,修改和刪除表中的行。也稱爲動作查詢語言。
			3.事務處理語言(TPL):
				它的語句能確保被DML語句影響的表的所有行及時得以更新。TPL語句包括BEGIN TRANSACTION,COMMIT和ROLLBACK。
			4.數據控制語言(DCL):
				它的語句通過GRANT或REVOKE獲得許可,確定單個用戶和用戶組對數據庫對象的訪問。
				某些RDBMS可用GRANT或REVOKE控制對錶單個列的訪問。
			5.數據定義語言(DDL):
				其語句包括動詞CREATE和DROP。在數據庫中創建新表或刪除表(CREAT TABLE 或 DROP TABLE);
				爲表加入索引等。DDL包括許多與人數據庫目錄中獲得數據有關的保留字。它也是動作查詢的一部分。
			6.指針控制語言(CCL):
				它的語句,像DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用於對一個或多個表單獨行的操作。
		3.書寫規則:
			1.在數據庫中,SQL語句大小寫不敏感,SELECT/select/SeLeCt
			2.SQL語句可單行或多行書寫
			3.在SQL語句中,關鍵字不能跨多行或縮寫
			4.爲了提高可讀性,一般關鍵字大寫,其他小寫.
			5.空格和縮進使程序易讀

	2.SQL對數據庫進行操作:
		1.創建數據庫:
			1.create  database  數據庫名;
			2.create  database  數據庫名  character  set  字符集;
			3.create  database  數據庫名  character  set  字符集  collate  字符集的校對規則;
			4.例子:create  database  test  character  set  utf8  collate  utf8_general_ci; 
 
		    	5.一種拷貝 表結構 和 表數據的語句:(不會拷貝 表的索引)
				CREATE  TABLE  emp_copy  AS  SELECT * FROM emp
				CREATE  TABLE  emp_copy  AS  SELECT * FROM emp WHERE 1=2
			6.一種拷貝 表結構 和 表數據的語句:(不會拷貝外鍵)
				CREATE  TABLE  emp_bak LIKE emp  

		2.查看數據庫:
			1.查看所有數據庫:show  databases;
			2.查看 “用於創建數據庫的”SQL語句:show  create  database  數據庫名;

		3.修改數據庫:
			1.修改數據庫的字符集/字符集的校對規則:
				alter  database  數據庫名  character  set  字符集;
				alter  database  數據庫名  character  set  字符集  collate  字符集的校對規則;
			2.例子:alter  database  test  character  set  utf8  collate  utf8_general_ci;  

		4.刪除數據庫:
			1.drop  database  數據庫名;
			
		5.切換/使用 數據庫:
			1.use  數據庫名;

		6.查看正在使用的數據庫:
			1.select  database();

	3.SQL對錶進行操作:
		注意:and、or、not 的優先級 就是 and -->  or  -->  not 
		1.創建表:
			1.creaet  table  表名(字段名稱  字段類型(長度)  約束,  
					      字段名稱  字段類型(長度)  約束,  ......);
			    例子:
				creaet  table  test(id  int  primary  key  auto_increment,
						 userName  varchar(20)  unique,
						 passWord  varchar(20)  not  null);	
			注意:
				最後一行沒有逗號;
				若在建表中使用到了數據庫的關鍵字,比如新建一張訂單表order,但是order是數據庫中的關鍵字用來排序使用的;
				若非要使用order這個單詞,此時可以使用反引號 括起來:`order` 
 
		2.查看錶:
			1.查看當前使用的數據庫中所有的表:show  tables;
			2.查看該表的結構:desc  表名;

		3.刪除表:
			drop  table 表名;

		4.修改表:
			1.添加列(字段):
				alter  table  表名  add  字段名稱 字段類型(長度);
				alter  table  表名  add  字段名稱 字段類型(長度)  約束;
			2.修改列(字段)的類型、長度、約束:
				alter  table  表名  modify  列名  類型(長度);
				alter  table  表名  modify  列名  類型(長度)  約束;
			3.刪除列(字段):
				alter  table  表名  drop  列名/字段名
			4.修改列名(字段名):
				alter  table  表名  change  舊列名  新列名  舊列名的類型(長度);  
				alter  table  表名  change  舊列名  新列名  舊列名的類型(長度)  約束;  
			5.修改表名:
				rename  table  舊錶名  to  新表名;
			6.修改表的字符集:
				alter  table  表名  character  set  字符集;

	4.MySQL常用字段類型:
		1.Java中的字段類型			MySQL中的字段類型
		         byte/short 		         		         tinyint/smallint 
		         int/Integer				         INT/INTEGER
		         long/Long				         BIGINT

		         ---------------------------------------------------------------------------------------------
		         float/Float				         FLOAT
		         double/Double			         DOUBLE 
		         BigDecimal				         DECIMAL

		         FLOAT[(s,p)]、DOUBLE[(s,p)]:小數類型,可存放 實型、整型、精度(p)、範圍(s);
		         double(5,2):整數和小數一共佔5位,其中小數佔2位,最大值 999.99,最小 -999.99;但都不夠精準;
		         DECIMAL:定點數據類型,高精度類型,金額貨幣優先選擇;	
	         
		         ---------------------------------------------------------------------------------------------
		         boolean				         bit
		         char/String			                         char/varchar

		         BIT:我們一般存儲0或1,存儲是Java中的boolean/Boolean類型的值。
		         char(size):定長字符,0 - 255字節,size指N個字符數,若插入字符數超過設定長度,會被截取並警告。
		         varchar(size):變長字符,0 - 255字節,從MySQL5開始支持65535個字節,若插入字符數超過設定長度,會被截取並警告。
		         varchar 相當於 Java中字符串(String / StringBuilder / StringBuffer) 
		         一般存儲大量的字符串,比如文章的純文本,可以選用TEXT系列類型。
		         注意:在MySQL中,char字符 使用 '單引號' 引起來。 

		         ---------------------------------------------------------------------------------------------
		         Date				         date/time/datetime/timestamp
	
		         日期和時間類型爲DATETIME(日期+時間)、DATE(日期)、TIMESTAMP(日期+時間)、TIME(時間)、YEAR,相當於Java中Date / Calender。
		         注意:在MySQL中,日期時間值使用 '單引號' 引起來。 

		         ---------------------------------------------------------------------------------------------
		         File					         BLOB/TEXT

		         BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB:存放圖形、聲音和影像,二進制對象,0-4GB。
		         但是,在開發中,我們一般把 二進制文件的路徑 存儲在 數據庫中。
		         ---------------------------------------------------------------------------------------------
                  
		2.MySQL中的字段類型中的 char(長度) 和 varchar(長度) 的區別:
			1.char(長度):
				1.固定長度的字符 或 固定長度的字符串
				2.存儲的數據不滿固定長度的話,則額外空格補齊,大於固定長度則報錯無法插入
			2.varchar(長度):  
				1.可變長度的字符串
				2.存儲的數據不滿固定長度的話,也不會額外空格補齊,不會有任何額外操作,大於固定長度則報錯無法插入

		3. MySQL中的字段類型中的 date/time/datetime/timestamp:
			1.date:只有日期;
				date的用途:可用於 記錄生日日期
			2.time:只有時間
			3.datetime:既有日期又有時間,如果不往這個字段存值的話,則MySQL會默認使用null值存入到這個字段中
			4.timestamp:既有日期又有時間,如果不往這個字段存值的話,則MySQL會默認使用當前的系統時間存入到這個字段中
				            timestamp的用途:可用於 記錄用戶註冊時間
		
		4.MySQL中的字段類型中的 BLOB/TEXT
			1.一般不會直接把文件數據存到數據庫中,而是一般都是把上傳的文件保存到服務器本地,
			   然後可以使用varchar 記錄該文件的路徑

 		5.MySQL 以一個可選的顯示寬度指示器的形式對 SQL 標準進行擴展,這樣當從數據庫檢索一個值時,可以把這個值加長到指定的長度。
		   例如,指定一個字段的類型爲 INT(6),就可以保證所包含數字少於 6 個的值從數據庫中檢索出來時能夠自動地用空格填充。
		   需要注意的是,使用一個寬度指示器不會影響字段的大小和它可以存儲的值的範圍。一般不用指定位寬。
		   age  int(2):並不是代表age最多存儲99,查詢age值的時候 使用兩個0來佔位;

	5.約束:
		1.約束的作用:保證數據的完整性;
		2.單表約束
			1.主鍵約束:使用 primary  key 修飾,如id;
			          主鍵約束 並且默認自帶 唯一約束 和 非空約束的;
			2.唯一約束:使用 unique 修飾
			3.非空約束:使用 not  null 修飾
		3.多表約束:外鍵約束,用於多表之間保證數據的完整性;
		4.刪除約束(索引):alter  table  表名  drop  index  字段名

		5.表的約束(針對於某一列):
			1.非空約束:NOT NULL,不允許某列的內容爲空。
			2.設置列的默認值:DEFAULT。
			3.唯一約束:UNIQUE,在該表中,該列的內容必須唯一。
			4.主鍵約束:PRIMARY KEY, 非空且唯一。
			5.主鍵自增長:AUTO_INCREMENT,從1開始,步長爲1。
			6.外鍵約束:FOREIGN  KEY,A表中的外鍵列的值必須參照於B表中的某一列(B表主鍵)。
 
		6.主鍵設計,唯一標識某一行數據的:
			1.單字段主鍵:單列作爲主鍵,建議使用。
      			    複合主鍵:使用多列充當主鍵,不建議。
			2.主鍵分爲兩種:
				1.自然主鍵:使用有業務含義的列作爲主鍵(不推薦使用),比如身份證號碼;
				2.代理主鍵:使用沒有業務含義的列作爲主鍵(推薦使用);

	6.SQL對數據庫表中的數據進行操作:
		1.添加/插入 表數據:
			1.insert  /  insert  into  表名 (列名1,  列名2,  ......)  values (值1,  值2,  ......):插入一行 全部字段 / 部分字段 的數據
			2.insert  /  insert  into  表名 values (值1,  值2,  ......):插入一行 全部字段 的數據,比如有字段存入的是空值的話 必須使用null值代替
			3.insert  /  insert  into  表名 values (null,  值2,  ......):因爲id是從0開始自動增長的,所以可以不指定id的值;
									如果不存入指定的id值的話,必須改爲使用null值代替;
			3.注意:
				1.表名 和 後面的括號 之間、values 和 後面的括號 之間 都需要空格隔開,可有空格也可沒有空格隔開,但推薦有空格隔開;
				     原因:當批處理中values 和 後面的括號 之間 如果沒有使用空格隔開的話,那麼性能會慢幾倍,
					   所以values 和 後面的括號 之間需要空格隔開,滿足格式要求;
				2.插入的值的類型和順序 都要和 列名(字段名) 的類型和順序 要一致
				3.插入的值的最大長度不能超過列名(字段名) 設置的長度
				4.插入的值是字符串/日期時間,那麼使用 單引號/雙引號 引起來

 			4.一般語法:INSERT  INTO  table_name [(column [, column...])] VALUES (value [, value...]);
			5.一般來說,一條INSERT只能插入一條數據,因爲MYSQL沒有batch操作,所以,MYSQL也支持在一條INSERT中插入多條數據:
	 		    INSERT  INTO  table [(column [, column...])] VALUES (value [, value...]),(value [, value...]),...
			    當然,一條SQL的長度是有限的,可以通過調整max_allowed_packet參數;

		2.添加/插入 中文數據時,出現亂碼的原因:
			1.原因一:當前使用的字符集不支持中文;
			   解決方法:必須設置數據庫/表的字符集爲 character  set  utf8

			2.原因二:使用的是window的(黑窗口)命令提示符窗口中 進行SQL語句操作中文數據時,出現中文亂碼並且無法把中文亂碼
				      添加/插入到數據庫 ;
				      window下安裝mysql服務器時,設置了使用的是utf-8字符集,那麼MySQL數據庫服務器中的客戶端和服務器
				      都是默認使用utf-8字符集,而window平臺使用的字符集是gbk,所以在window的(黑窗口)命令提示符窗口中
				      操作中文數據也是gbk編碼,因此把該gbk編碼的中文數據傳給MySQL數據庫服務器中的客戶端時,
				      使用的默認utf-8編碼無法對 gbk編碼的中文數據 進行正常解碼識別,因此導致最終的亂碼並且無法把該亂碼數據
				      存入到數據庫中;	
			   解決方法:1.通過 show  variables  like  '%character%';  語句可以查看得知到 數據庫服務器中的 客戶端和服務器 使用的
				             字符集編碼的相關參數;
				         2.到MySQL安裝目錄下的my.ini文件中,把 數據庫服務器中的 客戶端 使用的 字符集編碼 修改爲 gbk編碼;
				         3.重啓MySQL服務:可以打開系統服務進行重啓MySQL服務 

		3.修改表數據:
			1.update  表名  set  字段名1  =  字段值,  字段名2  =  字段值:把該列上的 所有每行數據 都修改爲新的值
			2.update  表名  set  字段名  =  字段值  where  條件語句:按條件 只修改 該列上的某行數據 爲新的值
			3.注意:
				1.修改的值的類型 要和 列名(字段名) 的類型 要一致
				2.修改的值的最大長度不能超過列名(字段名) 設置的長度
				3.修改的值是字符串/日期時間,那麼使用 單引號/雙引號 引起來
			4.語法:UPDATE	  table_name  SET  columnName = value [, column = value] …  [WHERE  condition];
				 UPDATE語句也可以使用表連接,子查詢等多種方式執行;
			5.注意事項:
				1.可以多表更新:(sqlserver不允許多表更新)
					1.UPDATE  table1,  table2   SET  columnName = value [, column = value] …  [WHERE  condition]
					2.UPDATE  table1, (select ... from ...)  別名  SET  columnName = value [, column = value] …  [WHERE  condition]
					    “select ... from ...”可以作爲臨時表,使用上別名 	
				2.(mysql是不允許)update更新的表,不能用於 set子句 或 where子句的 子查詢中,
				       即子查詢中用到的表 不能和 update更新的表 是一樣;
			
		4.刪除表數據:
			1.delete  from  表名  where  條件語句:刪除表中某行數據
			2.delete  from  表名:刪除表中所有數據
			3.delete  和  truncate  的區別:
				1.delete  和  truncate  都爲刪除表中數據
				2.delete  from  表名:屬於DML(數據操作語句),逐條記錄刪除,事務可以作用在DML(數據操作語句)上,
						         意思即爲可通過 roolback; 命令語句 回滾之前的刪除操作,恢復被刪除的數據;
				3.truncate  table  表名:屬於DDL(數據定義語句),會先把表刪除了,然後重新創建一個結構一樣的空的表,
						              事務無法作用在DDL(數據操作語句)上,意思即爲無法通過 roolback; 命令語句 進行回滾
						              之前的刪除操作,無法恢復被刪除的數據;
				4.開啓事務/回滾事務:
					1.指的是邏輯上的一組操作,組成這組操作的各個邏輯單元,要麼全都成功,要麼全都失敗。
					     回滾(Rollback)指的是程序或數據處理錯誤,將程序或數據恢復到上一次正確狀態的行爲。
					2.開啓事物:START TRANSACTION  / BEGIN TRANSACTION 
					3.提交事務:COMMIT
					4.回滾事物:ROLLBACK

 			4.語法:DELETE  FROM  table_name  [WHERE  condition];
				在delete語句中,where子句是可選的部分,如果使用了where子句,則刪除的數據是符合where條件的所有記錄;
				如果省略了where子句,則全表的數據都會被刪除,delete語句的where條件也同樣支持子查詢,但是一定注意,
				刪除語句中的where條件不能是要刪除的數據表中的數據;
				所以,在涉及到 刪除的數據 是需要通過要刪除的表中的數據查詢出來的時候,
				那麼便需要把查詢結果臨時保存到另一張表,再通過delete語句刪除;


		5.查詢表數據:(like、group  by ... having、group_concat、order  by、ifnull、limit  [offset,]  row)
			1.基本查詢:select  [distinct]  *|列名  from  表名  where  條件語句
				1.select  *  from  表名:查詢所有每行數據
				2.select  列名1,  列名2,  ......  from  表名:查詢某列上的所有每行數據
				3.select  distinct  列名  from  表名:查詢並對某列上的所有每行數據進行去重
				4.select  列名1  + 列名2  +  ......  from  表名:查詢並計算多列字段數據的和
				   select  (列名1  + 列名2  +  ......) / n  from  表名:查詢並計算多列字段數據的平均值
				5.select  列名  [as]  otherName  from  表名:(as可以省略)查詢並對列名 取 別名
 
			2.條件查詢:
				1.可用於條件查詢的 運算符、關鍵字
					1.可以使用 比較運算符:>、<、=、>=、<=、<>
					2.模糊查詢:like  '_值%'
						select  *  from  表名  where  列名1  like  '_值%':% 和 _ 都爲佔位符
						          like  '_值%':該值的前面可以包含任意一個字符,該值的後面可以包含示一個或任意多個字符
						          like  '%值%':% 表示一個或任意多個字符,該值的前後都可以包含示一個或任意多個字符
						          like  '_值_':_ 表示任意一個字符,該值的前後都可以包含任意一個字符
			          			例子:
							like ‘李_’:名字中必須是兩個字,而且是姓李的。
							like ‘李%’:名字中姓李的學生,李子後可以是1個或任意個字符。
							like ‘%四’:名字中以四結尾的。
							like ‘%王%’:只要名稱中包含這個字就可以。

					3.範圍查詢:in、between ... and ...
						select  *  from  表名  where  列名  in  (值1,  值2,  ......):該列名的值可以是該多個值中任意一個值
						select  *  from  表名  where  列名  between  值1  and  值2:該列名的值在值1和值2範圍之間任意一個值
						select  *  from  表名  where  列名  >  值1  and  列名  <  值2:該列名的值在值1和值2範圍之間任意一個值
 		
					4.條件關聯:and、or、not
							select  *  from  表名  where  列名1  =  值  and  列名2  =  值:多列字段 並列條件查詢
 	
			3.排序查詢:order  by  字段名  asc / desc
				1.單個字段 升序/降序:
					order  by  字段名  asc:升序,即位置從上到下的方向上,值按小到大排序 
					order  by  字段名  desc:降序,即位置從上到下的方向上,值按大到小排序
				   	order  by  字段名:默認升序

				2.多個字段 升序/降序:(如果第一個字段值相同,則按照第二個字段值進行排序)
					order  by  字段名1  asc,  字段名2  desc:
						先按照 字段名1 進行升序排序,如果同時多個字段名1 的值相同,則按照 字段名2 進行降序排序;
					例子:
						查詢學生信息,先按照語文成績進行倒序排序,如果成績相同再按照英語成績升序排序
						select  *  from  表名  order  by  chinese  desc,  english  asc;

			4.分組統計查詢:聚合函數、ifnull函數、if函數、分頁查詢函數、分組查詢group  by ...... having ...... 
				1.聚合函數:sum():求和;count()、count(distinct 字段名):統計個數;max():獲取最大值;min():獲取最小值;avg():求平均值;
					select  avg(字段名1),  sum(字段名1)  from  表名:查詢該字段名1上的所有每行數據的 平均值 和 總和
					select  count(*)  from  表名:統計個數
				     注意:
					1.select、group  by ... having ...、order  by 後面都可以使用 聚合函數,就只有where 後面不能使用 聚合函數,
					    因爲聚合函數本身只能得出一個結果數據,即查詢的結果只有一行數據,
					    並且where本身是對全局數據進行條件查詢的,因爲是先執行from再執行where,
					    所以如果where後面可以使用聚合函數的話,就會對全部數據進行聚合函數查詢,
					    最終的查詢結果就只有一行數據,是無法獲取多行的數據的,因此也是where 後面不能使用 聚合函數的原因;
					2.在having後面可以使用聚合函數  可以代替  where後面無法使用聚合函數 的作用:
						group  by......having......:having不能單獨使用,having必須和group  by才能一起使用;
						having本身是對分組數據進行條件查詢的,而where本身是對全局數據進行條件查詢的;
						group  by  字段名 having  聚合函數:
						          having 後面可以使用 聚合函數,因此 正好可以 替代 where後面無法使用聚合函數 的作用;
						           對分組數據進行進行聚合函數查詢,每個分組都是有一條數據,所以最終查詢結果是多條數據;
					3.where 和 having 的區別:
						1.共同點:兩者都可用於對數據進行條件過濾篩選 
						2.不同點:
							1.where是執行在from之後,所以where是對錶中所有的數據進行全局條件過濾,得出查詢結果集;
							2.group  by ... having ...:
								1.having不能單獨使用,必須和  group  by 一起使用;
								2.group  by ... having ... 是執行在where之後,因此group  by是對查詢結果集進行分組的,
								    而having 是執行在group  by之後,所以having 是對分組數據進行條件過濾篩選的;
								3.having 後面要使用 聚合函數 的話,必須在 select 中寫出該聚合函數 ;
							3.聚合函數可以用在select、group  by、having、order  by 的後面,唯獨不能用在where的後面;
							     因爲聚合函數是 對查詢結果集/分組數據 的基礎上進行 條件查詢的,
							     而執行where對錶中所有數據進行條件過濾篩選之後,才能得出查詢結果集,
							     所以聚合函數無法用在where的條件查詢中;
							4.例子:
								按商品名稱統計,統計每類商品花費的總金額在5000元以上的商品,
								並且按照總金額升序排序
								select  product,  sum(price)  from  orderitem   group  by  product  having  sum(price) > 5000 
								order by  sum(price) asc;

				2.ifnull函數、if函數:
					ifnull(字段名,  0)  null值和任意值相加都會變爲null,所以必須判斷遇到null值時要變爲使用0值來代替使用
					1.sum( ifnull(字段名1,  0)  +  ifnull(字段名2,  0) ):先計算每行數據的和,然後再把每行數據之和 進行相加
					2.sum( ifnull(字段名1,  0) )  +  sum( ifnull(字段名2,  0) ):先計算每列數據的和,然後再把每列數據之和 進行相加
					3.IFNULL(expression_1,expression_2):
						如果expression_1不爲NULL,則IFNULL函數返回expression_1; 
						如果expression_1爲NULL,返回expression_2的結果
						SELECT IFNULL(NULL,"11"); 結果爲 11
					   	SELECT IFNULL("00","11");  結果爲 00

					if(true,a,b) 和 if(false,a,b):第一個參數如果是true,就返回a;第一個參數如果是false,就返回b,像三元表達式
					把salary表中的女改成男,男改成女:update salary set sex = if( sex = '男','女','男');


				3.分頁查詢函數:limit  [offset,]  row
					1.limit  [offset,]  row:從哪行開始取多少行,意思即從offset行開始取row行
						[offset,]:表示可寫可不寫,不寫offset的話,offset默認爲0,意思即初始行爲0,表示第一行開始取
						offset:從哪一行數據開始,初始行是從0開始
						row:取多少行數據
					2.select  *  from  表名  limit  0,  5:同下,從第一行開始,取5行數據;
					   select  *  from  表名  limit  5:同上,從第一行開始,取5行數據;
					   SELECT * FROM exam LIMIT  3,  1:只取第4條數據
					   SELECT * FROM exam LIMIT  3,  3:取出第4條到第6條的數據
 
				4.分組查詢group  by ...... having ...... :
					1.select  sum(字段名2)  from 表名  group  by  字段名1  having  sum(字段名2)  >  值  order  by  sum(字段名2)  asc;
					2.在having後面可以使用聚合函數  可以代替  where後面無法使用聚合函數 的作用:
						group  by......having......:having不能單獨使用,having必須和group  by才能一起使用;
						having本身是對分組數據進行條件查詢的,而where本身是對全局數據進行條件查詢的;
						group  by  字段名 having  聚合函數:
						          having 後面可以使用 聚合函數,因此 正好可以 替代 where後面無法使用聚合函數 的作用;
						          對分組數據進行進行聚合函數查詢,每個分組都是有一條數據,所以最終查詢結果是多條數據;

					3.where 和 having 的區別:
						1.共同點:兩者都可用於對數據進行條件過濾篩選 
						2.不同點:
							1.where是執行在from之後,所以where是對錶中所有的數據進行全局條件過濾,得出查詢結果集;
							2.group  by ... having ...:
								1.having不能單獨使用,必須和  group  by 一起使用;
								2.group  by ... having ... 是執行在where之後,因此group  by是對查詢結果集進行分組的,
								    而having 是執行在group  by之後,所以having 是對分組數據進行條件過濾篩選的;
								3.having 後面要使用 聚合函數 的話,必須在 select 中寫出該聚合函數 ;
							3.聚合函數可以用在select、group  by ... having ...、order  by 的後面,唯獨不能用在where的後面;
							     因爲聚合函數是 對查詢結果集/分組數據 的基礎上進行 條件查詢的,
							     而執行where對錶中所有數據進行條件過濾篩選之後,才能得出查詢結果集,
							     所以聚合函數無法用在where的條件查詢中;
							4.例子:
								按商品名稱統計,統計每類商品花費的總金額在5000元以上的商品,
								並且按照總金額升序排序
								select  product,  sum(price)  from  orderitem   group  by  product  having  sum(price) > 5000 
								order by  sum(price) asc;
				5.分組查詢語法:
					SELECT [DISTINCT] *|分組字段1 [別名] [,分組字段2 [別名] ,…] | 聚合函數
					FROM 表名稱 [別名], [表名稱 [別名] ,…]
					[WHERE 條件(s)] 
					[GROUP BY 分組字段1 [,分組字段2 ,…] ]
					[HAVING 條件 | [,聚合函數] ] 
					[ORDER BY 排序字段 ASC | DESC  [,排序字段 ASC | DESC] | [,聚合函數ASC | DESC] ] ;

					1.寫法順序:select...from...where...group  by...having...order  by...limit  start  count
					2.執行順序:from --->  where  --->  group  by  --->  select --->  having --->  order  by --->  limit  start  count
					3.where、group  by、having 、聚合函數:
						1.where 後面不能使用 聚合函數
						2.having 後面要使用 聚合函數 的話,必須在 select 中寫出該聚合函數 

					1.select、group  by ... having ...、order  by 後面都可以使用 聚合函數,就只有where 後面不能使用 聚合函數
					2.需要忽略NULL值時,需要使用ifnull函數:
						ifnull(字段名,  0)  null值和任意值相加都會變爲null,所以必須判斷遇到null值時要變爲使用0值來代替使用

					3.分組:group  by  字段名(把只要 該字段的字段值 都爲同一個值 的多行數據 都會被 分到 同一組)
						select   字段名1  from  table   group  by  字段名1 	
						1.按某字段的值進行分組查詢;
			   			    該某字段的值首先會被去重,然後按照“只要該字段爲該分組的字段值的”行數據都會被分爲這一組;
						2.使用GROUP BY的 正確寫法:
							1.group  by 後面進行分組的字段 出不出現在 select 後面的查詢字段中 都可以;
							2.select 後面出現的 單獨使用的 查詢字段 都必須出現在 group  by 後面進行分組的字段中;
							3.如果 select 後面的查詢字段中 要使用 “不是group  by的”分組字段的話,那麼便要在select 後面,
				    			   把該“不是group  by的分組字段的” select 查詢字段 放到聚合函數(sum()等)中 或 group_concat()中;
					  	                   原因:因爲首先聚合函數只會得出一個結果數據,即一行數據,
							                 而SELECT後面單獨使用的字段是可能存在多行數據的,所以不符合要求並且毫無意義,
							                 雖然不會報錯;
							4.sum() / count() / 聚合函數() / group_concat() / concat() 都可以把 “不是group  by的分組字段的” 
							    select 查詢字段 作爲參數;
				   			    group_concat():可以把多個“不是group  by的分組字段的” select 查詢字段 拼接爲 一個字符串,並且每個字段值的默認分隔符是逗號;
							   例子:select concat(字段,字段,字段) as 別名 from 表名 where 字段=xx group by concat(字段,字段,字段);
						3.使用GROUP BY的 錯誤寫法:
						           select 後面出現的 單獨使用的 查詢字段 如果沒有出現在 group  by 後面進行分組的字段中 是錯誤的;

					4.使用GROUP BY要注意的點:
						1.使用GROUP BY之後,出現在SELECT後面的字段不能單獨使用,SELECT中的字段 要麼是出現在
						     select後面的聚合函數中(如:select  count(name)),要麼出現在GROUP BY中;
					  	    原因:因爲首先聚合函數只會得出一個結果數據,即一行數據,
							  而SELECT後面單獨使用的字段是可能存在多行數據的,所以不符合要求並且毫無意義,
							  雖然不會報錯;
						2.在GROUP BY 子句中出現的字段,可以不出現在SELECT列表中 

						3.例子:
							1.聚合函數單獨使用:SELECT  COUNT(name)  FROM  table;
							2.錯誤的使用,出現了單獨使用的字段:SELECT  name,  COUNT(name)  FROM  table;
							3.如果使用GROUP BY 進行分組的話,則SELECT子句中,
							   只能出現分組的字段(GROUP BY子句中出現的字段) 或 聚合函數,
							   其他單獨使用的字段不能出現:
								1.正確做法:
									SELECT  job,  COUNT(empno),  AVG(sal)
									FROM  emp
									GROUP  BY  job;
								2.錯誤的做法:(SELECT子句中單獨使用了字段deptno)
									SELECT deptno,  job,  COUNT(empno),  AVG(sal)
									FROM   emp
									GROUP BY job;
 
					5.group_concat(字段名):可以把多個“不是group  by的分組字段的” select 查詢字段 拼接爲 一個字符串;
						1.select   字段名1 , group_concat(字段名2)  from  table   group  by  字段名1
						2.select   字段名1 , group_concat(字段名1 , 字段名2 , ......)  from  table   group  by  字段名1
						3.select   字段名1 , group_concat(字段名1 , “-” , 字段名2 , “-” , ......)  from  table   group  by  字段名1
						    使用 “-” 作爲分隔符,那麼使用group_concat拼接多個字段爲一個字符串時,
						    該字符串中的每個字段之間都帶有“-”,
						    那麼便可以使用正則表達式根據“-”從該字符串中取出每個字段值;
						4.group  by 後面的字段 可以不需要出現在 select 和 from之間,但 select 和 from之間不能單獨使用
						    group  by 後面不存在的字段,
		   				    但可以在select 和 from之間 使用 聚合(集合)函數 或 group_concat() 帶上 group  by 後面不存在的字段;

	7.SQL中select、from、where、group  by、having、order  by、limit  [offset,]  row 的定義順序 和 執行順序:
		1.定義順序:select ... from ... where ... group  by ... having ... order  by ... limit  [offset,]  row 
		  	         其中select和from是必須的,其他關鍵詞是可選的;
		  例子:select ... from ... where ... group  by 字段1, 字段2  having 字段1=xx  and  字段2 =xx  order  by 字段1 asc, 字段2 desc  limit  [offset,]  row 
		2.執行順序:from ... where ... group  by ... having ... select ... order  by ... limit  [offset,]  row 
 		3.每個關鍵字的意義:(按照執行順序來排列)
			from:從哪個數據表中 檢索數據 
			where:對錶中所有數據 進行條件過濾,根據條件 過濾表中所有數據  
			group  by:將where條件過濾過濾出來的數據進行分組查詢 
			having:對group  by已經分組好的數據 進行 條件過濾  
			select:通過where、group  by、having等進行多重條件查詢後 得出查詢結果集,然後使用select獲取出查詢結果集中的某列數據 
			order by:按照升序/降序來對 “從結果集中取出的” 列數據 進行排序 
			limit  [offset,]  row:分頁每次取出部分數據


	8.開啓事務/回滾事務:
		1.指的是邏輯上的一組操作,組成這組操作的各個邏輯單元,要麼全都成功,要麼全都失敗。
		    回滾(Rollback)指的是程序或數據處理錯誤,將程序或數據恢復到上一次正確狀態的行爲。
		2.事務的作用:從事務開啓之後 到 事務提交之前這一段時間裏面,如果程序出現異常錯誤等導致程序崩潰停止的話,
		              		即使沒有手動回滾,事務開啓之後的全部操作也照樣不會提交到數據庫中執行保存;
		              		也可以使用手動回滾 對出現的異常錯誤情況 進行處理回滾事務;
		3.開啓事物:START TRANSACTION  / BEGIN TRANSACTION 
		4.提交事務:COMMIT
		5.回滾事物:ROLLBACK
		6.delete  和  truncate  的區別:
			1.delete  和  truncate  都爲刪除表中數據
			2.delete  from  表名:屬於DML(數據操作語句),逐條記錄刪除,事務可以作用在DML(數據操作語句)上,
				  	        意思即爲可通過 roolback; 命令語句 回滾之前的刪除操作,恢復被刪除的數據;
			3.truncate  table  表名:屬於DDL(數據定義語句),會先把表刪除了,然後重新創建一個結構一樣的空的表,
					              事務無法作用在DDL(數據操作語句)上,意思即爲無法通過 roolback; 命令語句 進行回滾
					               之前的刪除操作,無法恢復被刪除的數據;
			


3.數據庫、存儲引擎:
	1.數據庫對象:存儲,管理和使用數據的不同結構形式,如:表、視圖、存儲過程、函數、觸發器、事件、索引等。
	2.數據庫:存儲數據庫對象的容器。	
	3.數據庫分兩種:
   		1.系統數據庫(系統自帶的數據庫):不能修改
        			information_schema:存儲數據庫對象信息,如:用戶表信息,列信息,權限,字符,分區等信息。
        			performance_schema:存儲數據庫服務器性能參數信息。
        			mysql:存儲數據庫用戶權限信息。
 		2.用戶數據庫(用戶自定義的數據庫):一般的,一個項目一個用戶數據庫。

	4.MySQL的存儲引擎:
		1.MySQL中的數據用各種不同的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不同的存儲機制、索引技巧、
		    鎖定水平並且最終提供不同的功能和能力。
		    通過選擇不同的技術,你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能。
		2.MyISAM:擁有較高的插入,查詢速度,但不支持事務,不支持外鍵。
		3.InnoDB:支持事務,支持外鍵,支持行級鎖定,性能較低。
		    InnoDB 存儲引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。
		    但對比MyISAM,處理效率差,且會佔用更多的磁盤空間以保留數據和索引。

4.數據庫對象:
	1.數據庫對象:包括 表、索引、視圖、圖表、缺省值、規則、觸發器、語法、函數等。
	2.數據庫對象名稱必須以字母開頭
	3.有效的字符包括數字、字母和三個特殊字符(# _ $)
	4.不要使用保留字作爲數據庫對象名稱
	5.同一用戶下的數據庫對象不能同名,即使是不同的對象類型

5.索引:
	1.索引爲 一個數據庫對象,用來加速對錶的查詢,通過使用快速路徑訪問方法快速定位數據,減少了磁盤的I/O ;
	    索引 與 表獨立存放,由數據庫自動維護;
	2.創建索引:
		自動創建索引:當在表上定義一個PRIMARY KEY時,自動創建一個對應的唯一索引;
           				當在表上定義一個外鍵時,自動創建一個普通索引;
		手動創建索引:用戶可以創建索引以加速查詢;可以在一列或者多列上創建索引;
	3.創建索引語法:CREATE  INDEX 索引名  ON table (column[, column]...);
	4.複合索引:多列在一起作爲一個索引,就叫做複合索引;
		        在很多情況下,複合索引比單個索引更好(理解原理即可);
	5.哪些值可以創建索引?
		1.外鍵一般要創建索引
		2.經常使用的查詢條件要創建索引。如果使用like ‘%’操作,不會使用索引。
		3.索引不是越多越好
		4.不要在可選值很少的屬性上面創建索引
		5.MySQL索引的使用,並不是所有情況下都會使用索引,只有當MySQL認爲索引足夠能夠提升查詢性能時纔會使用;



6.視圖:
	1.視圖也就是虛表,實際上視圖就是一個命名的查詢,用於改變基表數據的顯示。
	2.視圖的作用:
		1.可以限制對數據的訪問
		2.可以使複雜的查詢變的簡單
		3.提供了數據的獨立性
		4.提供了對相同數據的不同顯示
	3.語法:
		在CREATE  VIEW語句後加入子查詢:
			CREATE [OR REPLACE] VIEW view
     			[(alias[, alias]...)] 
     			AS subquery
     			[WITH READ ONLY];

	4.創建視圖:
		CREATE OR REPLACE VIEW  視圖名emp_v_30
		AS  SELECT  empno, ename, sal
		FROM    emp
		WHERE   deptno =30;
 
		CREATE  VIEW  視圖名sal_v_10
		AS   SELECT  employee_id  ID, last_name  NAME, salary*12  ANN_SALARY
		FROM    employees
		WHERE   department_id = 10;
 
	5.使用視圖:
		在查詢時,不需要再寫完全的Select查詢語句,只需要簡單的寫上從視圖中查詢的語句就可以了;
		例如:SELECT  *  FROM  視圖名sal_v_10;
		默認情況下,可以直接通過對視圖的DML操作去修改視圖對應表中的內容(前提是視圖中沒有通過公式導出的列);
 
	6.刪除視圖:
		刪掉視圖不會導致數據的丟失,因爲視圖是基於數據庫的表之上的一個查詢定義.
		例如:DROP VIEW  視圖名view_name;

安裝、卸載MySQL

MySQL的安裝
	1.這兩個路徑是可以改的,但是需要記住他的位置
			MySQL Server mysql服務器的安裝位置
			Server data files  數據存放的位置
	2.勾選standard configuration(手動配置)my服務器
	3.standard Charater 默認的不支持中文  需要 選擇第3個選擇 手動選擇 UTF-8
	4.Include BIn directory Windows Path 一定要勾選 否則用不了命令行
	5.modify security setting 輸入mysql最高管理員 root密碼 
	6.驗證是否安裝成功:打開命令行 輸入 mysql -u root -p  輸入密碼 顯示 welcom to the MySQL

存儲引擎選用第一個(Multifunction DataBase):多功能存儲引擎,支持多種存儲引擎;
	1.InnoDB:支持事務,支持外鍵,但是性能相對較低,開發中;
         	2.MyISAM:不支持事務,不支持外鍵,但是性能相對較高;


數據庫安裝常見錯誤

1.安裝時忘了勾選 Include BIn directory Windows Path:
	在登入MySQL服務器的時候不能直接輸入mysql登入命令,
	因爲我們沒有把MySQl的bin目錄添加到系統的環境變量裏面。
	每次輸入”cd F:\Program Files\MySQL\MySQL Server 5.7\bin“才能使用登入,
	這樣顯得比較麻煩,下面就介紹怎樣手動配置Path變量。 

	1. 打開左面右擊【我的電腦】圖標,在彈出的快捷菜單中選擇【屬性命令】。 
	2. 選擇【高級系統設置】,彈出對話框,選擇【環境變量】  
	3. 單擊【環境變量】按鈕,打開【環境變量】對話框,在系統變量列表中選擇【Path】變量 
	4.單擊【編輯】按鈕,在編輯系統變量對話框中,將MySQL的bin目錄添加到變量值中,用分號將其與其它路徑分隔開 
	5.添加完成後,單擊【確定】按鈕,這樣就完成了配置Path變量的路徑,然後就可以直接輸入mysql命令來登入數據庫了


2.數據庫安裝1045錯誤:
	提示: 1045 access denied for user 'root'@'localhost' using password yes錯誤
	解決:
	1. 開始 --> cmd  --> net stop mysql  (停用MySQL服務  沒啓動的可以省略)
	2. 找到安裝路徑 MySQL Server 5.1下的my.ini
	3. 打開 my.ini  找到  [mysqld]  然後在下面加上
    	    這句: skip_grant_tables (意思好像是 啓動MySQL服務的時候跳過權限表認證  )
	4. 然後就啓動數據庫修改密碼了  
    	    開始 --> cmd  -->  net start mysql  (啓動MySQL服務)--->  mysql  回車  (  如果成功,將出現MySQL提示符)
	5. 輸入use mysql; (連接權限數據庫)。
	6. 改密碼:update user set password=password("123") where user="root";(別忘了最後加分號) 。
	7. 刷新權限(必須步驟):flush privileges; 。 
	8. 退出 quit。 
	9. 將第3 步的 my.ini裏的 skip_grant_tables  去掉(啓動MySQL服務的時候不能讓他跳過權限表認證 )
	10. 重啓MySQL ,再進入,使用用戶名root和剛纔設置的新密碼123就可以登錄了。  


3.數據庫安裝2503錯誤:
	方法一:
		1、按WIN+R,在運行框中輸入“gpedit.msc” 確認;
		2、打開本地策略組編輯器後依次展開 :“計算機配置”-》“管理模板”-》“windows組件”-》“windows installer”,
    		       並找到“始終以提升的權限進行安裝”;
		3、雙擊該選項,設置爲“已啓用”,並應用;
		4、最後我們還要在【用戶配置】中進行同樣的操作;
		5、就可以安裝了。
	方法二:
		1、鼠標移到桌面左下角->右鍵(或者直接: WIN+X鍵),命令提示符(管理員);
		2、輸入:msiexec /package +‘msi文件路徑’(輸入的時候注意半角字符且路徑不能爲中文名)
	方法三:
    		先執行 方法一,再執行方法二

	注意:gpedit.msc 這個命令(針對win10 家庭版)可能找不到,需要升級系統到專業版,不然安裝不成功

concat() 和 group_concat()

一、CONCAT()函數
CONCAT()函數用於將多個字符串連接成一個字符串。
使用數據表Info作爲示例,其中SELECT id,name FROM info LIMIT 1;的返回結果爲
+----+--------+
| id | name   |
+----+--------+
|  1 | BioCyc |
+----+--------+
1、語法及使用特點:
CONCAT(str1,str2,…)                       
返回結果爲連接參數產生的字符串。如有任何一個參數爲NULL ,則返回值爲 NULL。可以有一個或多個參數。

2、使用示例:
SELECT CONCAT(id, ‘,’, name) AS con FROM info LIMIT 1;返回結果爲
+----------+
| con      |
+----------+
| 1,BioCyc |
+----------+

SELECT CONCAT(‘My’, NULL, ‘QL’);返回結果爲
+--------------------------+
| CONCAT('My', NULL, 'QL') |
+--------------------------+
| NULL                     |
+--------------------------+

3、如何指定參數之間的分隔符
使用函數CONCAT_WS()。使用語法爲:CONCAT_WS(separator,str1,str2,…)
CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一個參數是其它參數的分隔符。分隔符的位置放在要連接的兩個字符串之間。分隔符可以是一個字符串,也可以是其它參數。如果分隔符爲 NULL,則結果爲 NULL。函數會忽略任何分隔符參數後的 NULL 值。但是CONCAT_WS()不會忽略任何空字符串。 (然而會忽略所有的 NULL)。

如SELECT CONCAT_WS('_',id,name) AS con_ws FROM info LIMIT 1;返回結果爲
+----------+
| con_ws   |
+----------+
| 1_BioCyc |
+----------+

SELECT CONCAT_WS(',','First name',NULL,'Last Name');返回結果爲
+----------------------------------------------+
| CONCAT_WS(',','First name',NULL,'Last Name') |
+----------------------------------------------+
| First name,Last Name                         |
+----------------------------------------------+

二、GROUP_CONCAT()函數
GROUP_CONCAT函數返回一個字符串結果,該結果由分組中的值連接組合而成。
使用表info作爲示例,其中語句SELECT locus,id,journal FROM info WHERE locus IN('AB086827','AF040764');的返回結果爲
+----------+----+--------------------------+
| locus    | id | journal                  |
+----------+----+--------------------------+
| AB086827 |  1 | Unpublished              |
| AB086827 |  2 | Submitted (20-JUN-2002)  |
| AF040764 | 23 | Unpublished              |
| AF040764 | 24 | Submitted (31-DEC-1997)  |
+----------+----+--------------------------+

1、使用語法及特點:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] [,col ...]]
[SEPARATOR str_val])
在 MySQL 中,你可以得到表達式結合體的連結值。通過使用 DISTINCT 可以排除重複值。如果希望對結果中的值進行排序,可以使用 ORDER BY 子句。
SEPARATOR 是一個字符串值,它被用於插入到結果值中。缺省爲一個逗號 (","),可以通過指定 SEPARATOR "" 完全地移除這個分隔符。
可以通過變量 group_concat_max_len 設置一個最大的長度。在運行時執行的句法如下: SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;
如果最大長度被設置,結果值被剪切到這個最大長度。如果分組的字符過長,可以對系統參數進行設置:SET @@global.group_concat_max_len=40000;

2、使用示例:
語句 SELECT locus,GROUP_CONCAT(id) FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus; 的返回結果爲
+----------+------------------+
| locus    | GROUP_CONCAT(id) |
+----------+------------------+
| AB086827 | 1,2              |
| AF040764 | 23,24            |
+----------+------------------+

語句 SELECT locus,GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR '_') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;的返回結果爲
+----------+----------------------------------------------------------+
| locus    | GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR '_') |
+----------+----------------------------------------------------------+
| AB086827 | 2_1                                                      |
| AF040764 | 24_23                                                    |
+----------+----------------------------------------------------------+

語句SELECT locus,GROUP_CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;的返回結果爲
+----------+--------------------------------------------------------------------------+
| locus    | GROUP_CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') |
+----------+--------------------------------------------------------------------------+
| AB086827 | 2, Submitted (20-JUN-2002). 1, Unpublished                               |
| AF040764 | 24, Submitted (31-DEC-1997) . 23, Unpublished                            |
+----------+--------------------------------------------------------------------------+

1.允許對數據庫進行指定IP的遠程訪問連接:
	1.問題:無法對數據庫進行指定IP的遠程連接,只能使用localhost進行連接數據庫
	2.解決方法一:
		1.在系統自帶的 叫做mysql名稱的數據庫下的 user表,把host字段的值localhost 修改爲 %,意思即 允許任何IP地址訪問
		2.重啓MySQL服務

	3.解決方法二:修改root用戶的登錄權限,允許任何IP地址訪問
		1.可以使用mysql -uroot -p密碼進入mysql數據庫的情況下:
			mysql> use mysql
			mysql> update user set host = '%' where user = 'root'; 
			mysql> flush privileges
			然後重新啓動mysql服務就可以了
			(在管理員模式下的命令提示符窗口中 先執行 net  stop  mysql,然後執行 net  start  mysql)

		2.不能使用mysql -uroot -p密碼進入mysql數據庫的情況下:
  			需要先停止mysql服務,這裏分兩種情況,一種可以用service mysqld stop,另外一種是/etc/init.d/mysqld stop
			當提示mysql已停止後進行下一步操作 
			在終端命令行輸入:mysqld_safe --skip-grant-tables &  
			(其中 –skip-grant-tables 的意思是跳過授權表,通過此參數來跳過輸入密碼,後面跟得 & 符號是表示設置)
			輸入:mysql,也可以回車之後在輸入命令: mysql (登錄mysql系統)
			進入 mysql數據庫,然後通過語句修改密碼:
				mysql> use mysql
				mysql> update user set host = '%' where user = 'root'; 
				mysql> flush privileges
				mysql> exit;
				然後重新啓動mysql服務就可以了
				(在管理員模式下的命令提示符窗口中 先執行 net  stop  mysql,然後執行 net  start  mysql)

 
2.外鍵:
	1.多表約束:外鍵約束,用於多表之間保證數據的完整性
	2.外鍵:指向另外一張表的主鍵,外鍵的值一般也不能爲空,外鍵的值應爲 not  null 非空約束;
		 外鍵之所以要關聯主鍵,因爲主鍵是唯一併且非空的,根據主鍵就能確定一條唯一的記錄;
	    主表:被引入外鍵的表;
	    從表:引入外鍵的表;
	    注意:在MySQL中,存儲引擎InnoDB才支持事務和外鍵,因此需要保證存儲引擎爲InnoDB;
		  修改表的存儲引擎爲InnDB:ALTER TABLE 表名 ENGINE='InnoDB';

	3.添加外鍵約束的寫法:
		例子:
			1.A表 通過外鍵關聯 B表的主鍵:alter  table  A表  add  foreign  key(外鍵字段名)  references  B表(主鍵字段名)
			    不創建外鍵約束名的話,底層會自動創建一個外鍵約束名,也可以自定義一個任意名字的外鍵約束名
			2.修改外鍵爲not  null 非空約束:alter  table  A表  modify  外鍵字段名  int  not  null

3.一對一關係、一對多關係、多對多關係:
	1.一對一關係:一般會把兩張表合併爲一張表,需要情況下才會分拆爲兩張表的一對一關係;
		1.第一種創建方式:唯一外鍵對應
			兩張表中 其中一張表 設置外鍵,關聯指向另外一張表的主鍵,並且該外鍵必須設置爲 unique 唯一約束
		2.第二種創建方式:主鍵對應
			不需要創建外鍵,兩張表各自的主鍵 對應 對方的 主鍵,那麼要求 雙方的主鍵值 一一對應並且主鍵值相同
		3.一對一關係的優點和用處:
			可用於數據庫的優化:分表;
			在一張表中,把不常用的字段分離出來放到另外一張表中,此時這兩張表就是一對一的關係;
			可以達到減少正常查詢時的數據負擔,提高效率;				

	2.一對多關係:在多的一方的表中 創建外鍵字段 指向 一的一方的表中的 主鍵字段

	3.多對多關係:應使用 中間表(第三張表) 來存儲指向 多對多的兩張表的主鍵字段,中間表中會創建兩個字段均作爲外鍵,
		              兩個外鍵分別指向 多對多的兩張表各自的主鍵字段;

4.多表查詢之連接查詢:交叉連接、外連接、內連接、自關聯(自連接)、union、union  all
	1.多表查詢,如果沒有連接條件,則會產生笛卡爾積:
	    數學中定義:假設集合A={a,b},集合B={0,1,2},則兩個集合的笛卡爾積爲{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。
	    實際運行環境下,應避免使用全笛卡爾集。
	2.連接條件:
		在 on / where 子句中 寫入連接條件。
		當多個表中有重名列時,必須在列的名字前加上表名作爲前綴/或使用表的別名爲前綴。
		等值連接是連接操作中最常見的一種,通常是在存在主外鍵約束條件的多表上建立的,連接條件中的兩個字段通過等號建立等值關係。
		使用表的別名簡化了查詢,提高了查詢的性能。
		連接 n張表,至少需要 n-1個連接條件。

	2.交叉連接:查詢到的結果集數據是帶有笛卡爾積,因爲沒有使用連接條件進行關聯再進行條件查詢,所以纔會出現笛卡爾積的結果集數據
		1.select  *  from  表1  cross  join  表2
		2.select  *  from  表1, 表2	
  
	3.外連接:
		1.左外連接:left  outer  join ... on ... (outer 可以省略)
			          1.查的是左邊表的全部和兩張表的交集;
			             查詢出JOIN左邊表的全部數據查詢出來,JOIN右邊的表不匹配的數據使用NULL來填充數據;
			          2.select  *  from  表1  left  outer  join  表2  on  連接條件
			             首先獲取左邊表的全部數據,以左邊表爲標準,獲取兩張表的共有(交集)的數據;
			              如果左邊表中的 某數據沒有對應的 右表數據的話,那麼以NULL代替顯示爲 “左邊表中該數據對應的” 右表數據

		2.右外連接:right  outer  join ... on ... (outer 可以省略)
			          1.查的是右邊表的全部和兩張表的交集;
			             查詢出JOIN右邊表的全部數據查詢出來,JOIN左邊的表不匹配的數據使用NULL來填充數據;
			          2.select  *  from  表1  right  outer  join  表2  on  連接條件
			              首先獲取右邊表的全部數據,以右邊表爲標準,獲取兩張表的共有(交集)的數據;
			              如果右邊表中的 某數據沒有對應的 左表數據的話,那麼以NULL代替顯示爲 “右邊表中該數據對應的” 左表數據

	4.內連接:
		內連接只獲取出兩張表的共有(交集)的數據,也即查的是兩張表的交集  ;
		連接條件:表1.字段名1  =  表2.字段名2;
		顯式內連接 和 隱式內連接 查詢出的結果都是一樣的,僅是寫法不一樣;

		1.顯式內連接:使用了 inner  join ... on ... (inner 可以省略)
			               select  *  from  表1  inner  join  表2  on  連接條件
			注意:
				1.ON  table1.name  =  table1.name  相當於  USING(name)
				2.例子:
					SELECT e.empno, e.ename, d.dname  FROM  emp  e  JOIN  dept  d  ON  e.deptno  =  d.deptno
					SELECT e.empno, e.ename, d.dname  FROM  emp  e  JOIN  dept  d  USING(deptno)

		2.隱式內連接:沒有使用 inner  join ... on ...,而是改爲使用 where   
			               select  *  from  表1, 表2  where  連接條件

	5.自關聯(自連接):(自關聯(自連接) 可以使用 內連接 / 左外連接 / 右外連接)
		select   parent.字段, son.字段   from  table1  as  parent   inner  join  table1  as  son   on  parent.id  =  son.parent_id 
		select   parent.字段, son.字段   from  table1  as  parent  right  outer  join  table1  as  son   on  parent.id  =  son.parent_id
  		select   parent.字段, son.字段   from  table1  as  parent  left  outer  join  join  table1  as  son   on  parent.id  =  son.parent_id
		把多張表 的數據放到同一張表中,可以使用 自關聯;
		下面的需求都可以用到 自關聯:
			1.把 省表、市表、區表 都放到同一張表中:
				省數據的parent_id爲NULL,而表示市數據的parent_id等於表示省數據的id,以此類推。
			2.把 一級菜單、二級菜單、三級菜單 都放到同一張表中;			 
	 			一級菜單 的parent_id爲NULL,而二級菜單的parent_id 等於 一級菜單的id,以此類推。
			3.需求:查詢員工名稱和其對應經理的名稱 
				SELECT  e.empno, e.ename, m.ename  FROM emp e  LEFT JOIN  emp m  ON e.mgr = m.empno;

	6.UNION / UNION ALL:
		1.UNION / UNION ALL:
			JOIN是用於把表橫向連接,UNION/UNION ALL是用於把表縱向連接(一般用於做查詢的臨時表)
			UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。

		2.使用注意:
			1.UNION 內部的 SELECT 語句必須擁有相同數量的列。
	          		2.列也必須擁有兼容的數據類型。
			3.每條 SELECT 語句中的列的順序必須相同。
			4.UNION 結果集中的列名總是等於 UNION 中第一個 SELECT 語句中的列名
			5.UNION 操作符選取不同的值。如果允許重複的值,請使用 UNION ALL(性能高) 

		3.語法:
			SELECT column_name(s) FROM table_name1
			UNION|UNION ALL
			SELECT column_name(s) FROM table_name2

		4.在MYSQL 中實現FULL JOIN全連接,MYSQL中暫時不支持全連接,可以使用 “union + 左外連接 和 右外連接” 來完成 全連接的效果;
		    例子:查詢員工的編號,名稱和部門名稱
					SELECT empno,ename,dname FROM emp LEFT JOIN dept USING (deptno)
					UNION
					SELECT empno,ename,dname FROM emp RIGHT JOIN dept USING (deptno)

 					上面的寫法 等同於 下面的寫法:ON  table1.name  =  table1.name  相當於  USING(name)
					
					SELECT empno,ename,dname FROM emp LEFT JOIN dept  ON  emp.deptno=  dept.deptno
					UNION
					SELECT empno,ename,dname FROM emp RIGHT JOIN dept  ON  emp.deptno=  dept.deptno

5.多表查詢之子查詢:
	1.子查詢的意思:
		一條sql語句的查詢結果 作爲 另外一條sql語句 中的查詢條件,也即一個查詢語句條件需要依賴另一個查詢語句的結果;
		子查詢指的就是在一個查詢之中嵌套了其他的若干查詢,在使用select語句查詢數據時,有時候會遇到這樣的情況,
	   	在where查詢條件中的限制條件不是一個確定的值,而是一個來自於另一個查詢的結果。

	2.子查詢的用法:
		1.子查詢一般出現在FROM/JOIN子句中 或 WHERE子句中,即子查詢 可以作爲表數據 使用在 from / join後面,
		    或子查詢作爲 條件查詢數據 使用在where 後面;
		2.使用子查詢的注意事項:
			1.子查詢要用括號括起來 
			2.將子查詢放在比較運算符的右邊(增強可讀性)
			3.對單行子查詢使用單行運算符
			4.對多行子查詢使用多行運算符

	3.子查詢的分類,根據子查詢的結果分爲以下情況:
		1.單行單列的 子查詢 結果數據:只包含一個字段的查詢,返回的查詢結果也只包含一行數據, 看做是一個值,使用在WHERE之後 
		2.多行單列的 子查詢 結果數據:只包含了一個字段,返回多行查詢結果數據,看做是多個值,使用在WHERE之後 
		3.單行多列的 / 多行多列的 子查詢 結果數據:
			包含多個字段的返回,返回的查詢結果數據可能是單行或者多行,看做是臨時表,使用在FROM/JOIN之後 

	4.單行單列的 子查詢 結果數據:
 		1.子查詢返回一行一列記錄,看做是一個值,使用在WHERE之後;
		2.使用單行記錄比較運算符:=;>;>=;<;<=;<>
		3.例子:
			查詢大於公司平均工資的員工姓名
			SELECT ename,sal FROM emp WHERE sal >(SELECT AVG(sal) FROM emp)
			查詢出工資比MARTIN還要高的全部僱員信息
			SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename = 'MARTIN')

	5.多行單列的 子查詢 結果數據:
		1.返回多行查詢結果數據,看做是多個值
		2.使用多行比較運算符
     			1.IN:與列表中的任意一個值相等 ;where  字段名  IN (子查詢SQL)
     			2. ANY:與子查詢返回的任意一個值比較
				1.where  字段名  =  ANY:此時和IN操作符相同 
				2.where  字段名  > ANY:大於子查詢中最小的數據 
				3.where  字段名  < ANY:大於子查詢中最大的數據 
		3.ALL:與子查詢返回的每一個值比較
			1.where  字段名  > ALL:大於子查詢中最大的數據 
			2.where  字段名  < ALL:小於子查詢中最小的數據 
 
		4.帶 in 的 子查詢:
			select  *  from  表1  where  字段名1  in  (select 查詢出 多個字段值)
			例子:
				select  *  from  Class  where  id  in  (select  外鍵class_id  from  Student  where  ......)
				獲取出Student表中多個 “關聯Class表id的” 外鍵class_id,
				然後範圍查詢 “Class表的id  in  外鍵class_id” 獲取出 多行Class表數據;

		5.帶 any 的 子查詢:
			select  *  from  Class  where  id  >  any  (select 查詢出 多個字段值):大於任意一個值,即大於最小值
			表示只要Class 表中的id 大於 子查詢中多個值中的 任意一個值,那麼便成立,便可查詢出對應的數據;
			也即只要Class 表中的id 大於 子查詢中多個值中的 最小值,那麼便成立,便可查詢出對應的數據;
		
		6.帶 all 的 子查詢:
			select  *  from  Class  where  id  >  all (select 查詢出 多個字段值):大於全部多個值,即大於最大值
			表示只要Class 表中的id 大於 子查詢中全部的多個值,那麼便成立,便可查詢出對應的數據;
			也即只要Class 表中的id 大於 子查詢中多個值中的最大值,那麼便成立,便可查詢出對應的數據;

	6.單行多列的 / 多行多列的 子查詢 結果數據:
 		1.一般會把 單行多列的 / 多行多列的 子查詢 結果數據 當成一個臨時表,一般用在FROM/JOIN子句後面,
		    接着在臨時表上繼續查詢或者連接查詢;
		    注意:單行多列的 / 多行多列的 子查詢 結果數據 必須要設置一個臨時表名;
		2.例子:查詢出每個部門的編號、部門名稱、部門人數、部門平均工資:
			1.可以先把每一個部門的編號、部門總人數、部門平均工資先查詢出來:
				SELECT deptno dno,COUNT(empno) count ,AVG(sal) avg  FROM emp GROUP BY dno
			2.再和dept表聯合查詢部門名稱:
				SELECT  dept.deptno,temp.count,temp.avg  FROM dept JOIN
 				(SELECT deptno dno,COUNT(empno) count ,AVG(sal) avg  FROM emp GROUP BY dno) temp 
				ON dept.deptno = temp.dno
 

	7.帶 exists 的 子查詢:
		1.select  *  from  Class  where  exists  (select 是否查詢出數據) 
		   只要子查詢的sql語句查詢出數據,那麼exists就判斷爲true,那麼就執行 子查詢外的sql語句;
		   如果子查詢的sql語句查詢不出任何數據的話,那麼exists就判斷爲false,那麼就不會執行 子查詢外的sql語句。

		2.select  *  from  Class  where  ......  and / or  exists  (select 是否查詢出數據)  group  by  ......
	 	    使用and:當exists 爲true(子查詢select 查詢出數據) 時,纔會執行 子查詢外的sql語句;
		    使用or:不管exists 是否爲true,即不管子查詢select 是否查詢出數據,只要or前面的條件爲true,那麼都會執行 子查詢外的sql語句;
  
	8.注意事項:
		1.可以多表更新:(sqlserver不允許多表更新)
			1.UPDATE  table1,  table2   SET  columnName = value [, column = value] …  [WHERE  condition]
			2.UPDATE  table1, (select ... from ...)  別名  SET  columnName = value [, column = value] …  [WHERE  condition]
			    “select ... from ...”可以作爲臨時表,使用上別名 	
			2.(mysql是不允許)update更新的表,不能用於 set子句 或 where子句的 子查詢中,
			      即子查詢中用到的表 不能和 update更新的表 是一樣;

6.事務:
	1.數據庫的事務併發問題:
		1.存在五種問題:髒讀、不可重複讀、幻讀、第一類丟失更新、第二類丟失更新。 
		    爲了解決上述的問題,我們提出了隔離級別的概念,不同的隔離級別可以處理的併發問題是不一樣的;
		    使用不同的隔離級別就可以阻止自己所期望的併發問題;

		2.使用鎖機制來解決事務併發問題:
			1.悲觀鎖:SELECT ....... FOR  UPDATE;
			2.樂觀鎖:使用版本控制

	2.事務的 開啓、提交、回滾:
		1.開啓事務:start  transaction
		2.提交事務:commit
		3.回滾事務:rollback
		4.MySQL的事務一旦提交之後是無法回滾的,而Oracle的事務在提交之後都還是可以回滾的,
		   因爲Oracle提交的數據還會緩存一下後纔會保存到本地;

	3.事務的 特點:原子性、一致性、隔離性、持久性
		1.原子性:事務的不可分割,組成事務的各個邏輯單元不可分割
		2.一致性:事務執行的前後,數據完整性保持一致
		3.隔離性:事務執行不應該受到其他事務的干擾
		4.持久性:事務一旦結束,數據就持久化到數據庫中
	
	4.事務的隔離級別:
		1.MySQL默認的隔離級別:repeatable  read 避免 髒讀、不可重複讀,但是 虛讀 有可能發生
			1.修改更新、讀取查詢 操作都上鎖了,因此在一個事務中 是無法讀取到 別的事務 修改並提交之後的 新數據,
			    所以叫做避免了 不可重複讀,即在一個事務中只能讀取到當前事務中(修改/提交之後)的數據,
			    是無法讀取到別的事務修改提交後的新數據,不同事務之間是完全隔離的;
			2.即使修改更新、讀取查詢 操作都上鎖了,不同事務之間依然可以併發修改同一數據,當一個事務修改了同一數據並提交之後,
			    另一事務也接着也修改 同一數據並提交,最終該同一數據照樣可以被修改爲最新的更新值。

		2.Oracle默認的隔離級別:read  committed 避免 髒讀,但是 不可重複讀、虛讀是有可能發生
			1.修改更新操作 上鎖了,但是讀取查詢操作沒有上鎖,因此在一個事務中 是可以讀取到 別的事務 修改並提交之後的 新數據,
			     所以叫做 沒有避免 不可重複讀,即在一個事務中可以讀取到別的事務中修改/提交之後 的數據,
			     因爲即使是不同事務之間的讀取查詢操作是沒有上鎖的,所以性能比較高;
			2.即使修改更新上鎖了,讀取查詢操作沒有上鎖,不同事務之間依然可以併發修改同一數據,
			     當一個事務修改了同一數據並提交之後,另一事務也接着也修改 同一數據並提交,
			     最終該同一數據照樣可以被修改爲最新的更新值。

		3.最高的隔離級別serializable(串行化):
			串行化:多個事務排成隊列,排隊執行,每個事務逐一執行,一個事務執行結束了,才輪到下一個事務開始執行;
			serializable 不允許併發,每個事務都只能按順序逐一執行,一個事務結束了才輪到下一個事務執行,因此效率也是最低;
			比如說:有兩個客戶端 同時對同一張表 進行操作時 都開啓了事務,那麼客戶端A 正在操作(插入/修改)該表中的數據時,
				  而客戶端B 執行select查詢時 會一直阻塞等待 客戶端A 開啓的事務 提交數據之後,客戶端B 才能獲取到查詢數據;
				  也即說明事務不允許出現併發,客戶端B 需要等待客戶端A 的事務執行完成以後,纔會執行客戶端B 的事務,
				  當 客戶端A的事務結束(提交或者回滾),那麼客戶端B 馬上就會出現查詢數據結果。
 
		4.隔離級別的 安全性從高到低,但是效率從低到高:serializable ----> repeatable  read ----> read  committed ----> read  uncommitted
			1.read uncommitted:髒讀、不可重複讀、虛讀 都有可能發生
			2.read committed:避免 髒讀,但是 不可重複讀、虛讀是有可能發生
			3.repeatable read:避免 髒讀、不可重複讀,但是 虛讀 有可能發生。
			4.serializable:避免 髒讀、不可重複讀、虛讀。
 
		5.查看當前的隔離級別:select  @@tx_isolation
		6.設置事務的隔離級別:set  session  transaction  isolation  level  隔離級別的英文名 
					set  session  transaction  isolation  level  serializable/ repeatable  read/read  committed/read  uncommitted
 
		7.髒讀:一個事務 讀到 別的事務 沒有提交的數據;
			不同之間的事務應該是完全隔離的,所以一個事務 不應該 讀到 別的事務 沒有提交的數據
		8.不可重複讀:一個事務 讀到 別的事務 已經提交了的update的數據;
			               不同之間的事務應該是完全隔離的,所以一個事務 不應該 讀到 別的事務 已經提交了的update的數據;
			               在同一個事務中,多次的查詢結果都應是一致的;
		9.虛讀/幻讀:一個事務 讀到 別的事務 已經提交了的insert的數據;
			            不同之間的事務應該是完全隔離的,所以一個事務 不應該 讀到 別的事務 已經提交了的insert的數據;
			            在同一個事務中,多次的查詢結果都應是一致的;

	5.在數據庫中,所謂事務是指一組邏輯操作單元,使數據從一種狀態變換到另一種狀態。
		1.爲確保數據庫中數據的一致性,數據的操縱應當是離散的成組的邏輯單元:
		    當它全部完成時,數據的一致性可以保持,而當這個單元中的一部分操作失敗,整個事務應全部視爲錯誤,
		    所有從起始點以後的操作應全部回退到開始狀態。 
	    	2.事務的操作:
		    先定義開始一個事務,然後對數據作修改操作,這時如果提交(COMMIT),這些修改就永久地保存下來,
		    如果回退(ROLLBACK),數據庫管理系統將放棄您所作的所有修改而回到開始事務時的狀態。
	    	3.事務的ACID:
			1. 原子性(Atomicity):原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。 
			2. 一致性(Consistency):事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。(數據不被破壞)
			3. 隔離性(Isolation):事務的隔離性是指一個事務的執行不能被其他事務干擾,
				               	               即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾,
				               	               每一個事務都存在一個事務空間,彼此不干擾。
			4. 持久性(Durability):持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,
						 接下來的其他操作和數據庫故障 不應該對其有任何影響。

	    	4.事務控制的語言:
			begin:開啓一個事務,開啓一個新的事務空間 
			commit:提交事務 
			rollback:回滾事務 

		5.COMMIT和 ROLLBACK可以顯示的控制事務。
			好處:
				1.保證數據一致性,修改過的數據在沒有提交之前是不能被其他用戶看到的。
				2.在數據永久性生效前重新查看修改的數據
				3.將相關操作組織在一起,一個事務中相關的數據改變或者都成功,或者都失敗。

7.重置MySQL的密碼:
	1.第一步:停止MySQL的服務:命令行 sevices.msc  啓動服務界面 手動停止服務
	2.第二步:在cmd下啓動MySQL服務:輸入 mysql --skip-grant-tables ,不需要權限認證的啓動
	3.第三步:重新開啓cmd的命令行,然後登錄MySQL,不需要輸入密碼
	4.第四步:修改root的密碼
			use  mysql;
			update  user  set  password = password('新密碼') where user = 'root';
	5.第五步:結束mysqld的進程:執行 net  stop  mysql
	6.第六步:重新啓動MySQL的服務:執行 net  start  mysql

8.數據庫的備份和還原:
	1.數據庫的備份:
		1.第一步:打開cmd的命令行窗口(一定要注意這個不是在mysql命令下,若命令位置不對,會報1064(42000)錯誤);
			      輸入 mysqldump  -u  root  -p  數據庫名  >  C:/數據庫名.sql  (表和表裏面的信息反編譯成sql語句)
	
	2.數據庫的還原:
		2.第一種還原方式:
			1.第一步:在數據庫服務器內部創建數據庫:create  database  數據庫名;
			2.第二步:在命令行窗口輸入mysql  -u  root  -p  數據庫名  <  C:/數據庫名.sql(一定要注意這個不是在mysql命令下)

		3.第二種還原方式:
			1.第一步:在數據庫服務器內部創建數據庫:create  database  數據庫名;
			2.第二步:切換到該數據庫使用,然後使用source命令還原數據庫數據
					use  數據庫名;
					source  C:/數據庫名.sql;



等值連接:SELECT * FROM 表A INNER JOIN 表B ON 表A.字段名 = 表B.字段名


SELECT * FROM 表A FULL [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名


SELECT * FROM 表A LEFT [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名


SELECT * FROM 表A RIGHT [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名

SELECT * FROM 表A RIGHT [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名

SELECT * FROM 表A RIGHT [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名 WHERE 表A.字段名 IS NULL

UNION 與 UNION ALL

笛卡爾乘積:cross join

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章