mysql學習之旅_1
Mysql
php階段將資料庫分為三個階 基礎階段: mysql資料庫的基本操作(增刪改查),以及一些高階操作(檢視,觸發器,函式,儲存過程等),PHP操作沒有sql資料庫。 優化階段: 如何提高資料庫效率,如索引,分表等。 部署階段: 如何搭建真實的系統環境,如服務叢集,負載均衡。
資料庫基礎 什麼是資料庫: 資料庫:database ,儲存資料的倉庫(高效的儲存和處理資料庫的介質如磁碟、記憶體) 資料庫分類: 1,關係型資料庫:(sql型) 2,非關係型資料庫(nomysql型)not only 不同資料卡產品: 關係型資料庫:大型:Oracle ,DB2 中型:SQLserver,Mysql 小型:access 非關係型資料庫:mencahed,moogodb,redis2 資料庫的區別->兩種陣營 關係型database:安全(儲存在磁碟,不會丟失),浪費空間。 非關係型資料庫:效率高(不夠安全) 關係型資料庫: 1,什麼是關係型資料庫: 建立在關係模型上的資料庫(數學模式) 關係模型:建立在關係上的模型,三個方面。 1,資料結構:資料儲存問題,二維表的行列結構 2,Sql指令集合:sql語句。 3,完整性約束:表內資料約束,表與表之間的約束。 2,關係型資料庫的設計: 關係型資料庫:從需要儲存的資料需求分析,如果是一類資料(實體)->設計成二維表->表頭(欄位名field)和資料部分(實際儲存單元); 二維表:行與列, 例: 表頭 欄位1 欄位2 欄位3 資料單元 資料1 資料2 資料3
實際案例:教師負責講學,教學生,在教室。 1,找出實體。教師表,學生表,教室表。 2,找出實體資料資訊: (教師)姓名,性別,年齡,工資 (學生)姓名,性別,年齡,學號 (班級)班級編號,教室號 3,關係型資料庫:維護實體內部、實體與實體之間的聯絡。 1,實體內部的聯絡:每個學生都有姓名、性別、學科、學號。
學生表
姓名 性別 學號 學科 班名 張三 男 001 軟體工程 軟體工程001 小強 女 001 機械工程 機械工程001
第二行所有欄位:都是在描述張三這個學生(內部聯絡)第二列只能是性別(內部約束)。
關係型資料庫特點之一:如果表對應的某個欄位沒有值(資料),但是系統依然要分配儲存空間;關係型資料庫比較浪費空間。
實體與實體之間的聯絡:每個學生肯定屬於某個班級,每個班級肯定有多個學生。 班名 教室編號 軟體工程001 001 機械工程001 002
班級實體與學生實體之間的聯絡:實體與實體之間的聯絡
3,關鍵字說明: 資料庫:database 資料庫系統:DBS (database system):虛擬系統,將多種內容關聯起來的稱呼 DBS=DBMS+DB DBMS:database mangerment system資料庫管理系統,專門管理資料庫。 DBA:database Administrator 資料庫管理員。
行/記錄:row/record本質是一個東西->表中的一個記錄,行是從結構角度出發,記錄從資料角度出發。 列/欄位 column/filed,本質是一個東西。
SQL: Structured Query language(結構化查詢語言)資料庫以查詢為主,98%都是查詢操作。 SQL分為三個部分: DDL:data Definition Language 資料定義語言–>用來維護儲存資料的結構(資料庫,表) 代表指令:create ,drop ,alter DML:data manipulation Language 資料庫操作語言–>用來對資料進行操作(資料表中的內容) 代表指令:insert delete updata等其中DML內部又進行分類:DQL(database Query Language)資料查詢語言,如select。 DCL:data contral Language 資料控制語言–>主要負責許可權的管理(使用者) 代表指令:grant ,revoke等。
SQL簡介: Sql是關係型資料庫的操作指令 Sql是一種約束,但不強制(類似玩w3c組織)如Oracle,mysql內部有細微的區別。
Mysql: Mysql資料庫是一種c/s結構,客戶端/服務端若想要訪問伺服器必須通過客戶端(伺服器一直執行,客戶端在需要的時候執行),
互動方式 1,客戶端連線認證:連線伺服器認證身份 2,傳送sql指令 3,伺服器接受伺服器指令,處理sql指令返回操作結果。 4,客戶端接受操作結果,顯示結果。 5,斷開連線(釋放資源,伺服器併發限制)。
Mysql伺服器物件 沒有辦法完全理解伺服器內部的內容: 只能粗略的分析資料庫伺服器內部結構 將mysql資料庫分為四層: 系統(DBMS)->資料庫(BD)->資料表(table)->欄位(filed)
SQL基本操作: 基本操作:CRUD 將sql的基本操作根據物件分為三類 1,庫操作2,表操作3,資料操作 庫操作: 資料庫的增刪改查。 新增資料庫:create database 庫名 [庫選項]
庫選項:約束資料庫,分為兩個選項。 字符集的設定:charset /character set +具體字符集(資料儲存的編碼格式,一般兩種格式GBK和utf8) 校對集設定:collate +具體校對集(資料庫比較規則) – 雙中下劃線註釋(單行註釋,也可以用#) 其中資料庫不能用關鍵字(已經被使用的字元或保留字(將來可能會用到))。
檢視資料庫: Show databases;
檢視指定部分資料庫:模糊查詢 Show databases like ‘patten’;–paatten是匹配模式 %:表示是匹配模式 _:表示匹配單個字元;
檢視資料庫建立語句: Show create database 資料庫名[庫選項];
更新資料庫: 資料庫名字不可以修改; 資料庫的修改僅限於庫選項:字符集和校對集(校對集依賴於字符集); Alter database 資料庫名 [庫選項]; Charset /character set [=] 字符集; Collate [=] 校對集; 刪除資料庫: 所有操作中刪除最簡單; Drop database 資料庫名; 當刪除資料庫語句執行以後發生了什麼? 1,在資料庫顳部看不見對呀資料庫。 2,對應資料庫儲存資料夾內資料庫名字對應的資料夾表也被刪除。 注意:不要隨便刪除資料庫
表操作: 表與欄位(filed)密不可分 新增資料表: Create table 表名(欄位名1 資料型別1, 欄位名1 資料型別1 )[表選項] 表選項:控制表的選項 字符集:sharacter set /character 具體字符集; 校對集:collate 具體校對集; 儲存引擎:engine 具體的儲存引擎(innodb和myisam); 進入資料庫環境 use 資料庫名稱
當建立表的sql指令執行以後發生了什麼? 1,資料庫下存在相應的表, 2,在資料庫對應的資料夾下會產生對應的表結構檔案。 檢視資料表: 資料庫能檢視的方式,表都能檢視。 檢視所有表: Show tables: 檢視部分表: 模糊匹配:show tables like ‘patten’; 查看錶的建立語句: Show create table 表名; 查看錶結構: Desc class; Describe class; Show colums from class; 修改資料表: 倆部分,修改表本身,修改欄位 Rename table 老表名 to 新表名; 修改表選項:字符集 Alter table 表名,表選項 值;
修改欄位: 欄位的操作很多新增、修改、修改、重名、刪除。 新增欄位: Alter table 表名 add 欄位名 資料型別 [列熟悉][位置]; 位置:欄位名可以存放在表中任何位置 First:第一位置。 Alter:在哪個欄位之後,alter 欄位名;預設在最後一個欄位。
修改欄位: 通常是修改屬性或資料型別 Alter table 表名 modify 欄位名 資料型別[屬性][位置]; 重新命名欄位: Alter table 表名 change 舊欄位 新欄位 資料型別 [屬性][位置]; 刪除欄位: Alter table 表名 drop 欄位名; 刪除資料表: Drop table 表名1 表2–一次性多張
當刪除資料表指令以後發生了什麼? 1,表空間沒有指定表(資料沒有了); 2,資料庫對應的資料夾下對應的檔案(與儲存引擎有關)也會被刪除 注意:刪除有風險,操作不可逆。 資料操作: 新增資料(兩種) 方案1------給全欄位插入資料,不需要指定列表:需要資料的值與表中設計欄位出現順序一致 Insert into 表名 values(); 方案2------給部分欄位插入資料,需要選定欄位列表,欄位列表順序與欄位順序一致; 但是值列表順序必須與選定欄位順序一致 Insert into 表名 (欄位列表) values ([值列表], [值列表]); 檢視資料 Select */欄位列表 from 表名[while 條件]; 更新資料 Update 表名 set 欄位 =值[while 條件]; 刪除資料:不可逆 Delete from表名 [while 條件] 中文資料問題: 中文資料問題本質就說字符集問題, 計算機只識別二進位制,人類識別符號;需要友誼個二進位制與字元對應關係(字符集)。 報錯:伺服器沒有識別對應的四個位元組。 伺服器認為的資料是utf—8,一個漢字有三個位元組,讀取三個位元組轉換成漢字(失敗),剩餘的再讀三個位元組,最終失敗!
所有資料庫伺服器認為(表現)的一些特徵都是通過伺服器端的變數來儲存,系統先讀取自己的變數,看看應該怎麼表現。 Show viriables like ‘character_set %’;(檢視字符集);對外處理預設字符集
基本上伺服器是萬能的,什麼字符集都能識別。問題的根源:客戶端只能識別GBK而伺服器是utf-8,矛盾產生。 解決方案1: 改變伺服器。預設字符集為GBK Set character_set_client =GBK; 注意:資料的來源是伺服器,解析資料是客戶端(客戶端只識別GBK;兩個位元組一個漢字);但伺服器給的資料卻是utf8,三個位元組一個漢字,亂碼!!!!!! 解決方案2: 修改伺服器給客戶端的資料資料集為GBK Set character_set_result=GBK; Set 變數=值 ;修改只會是會話級別(當前客戶端:當次連線有效:關閉失效) 快捷方式: 設定伺服器對客戶端的字符集的認識: Set names 字符集; 例:set names gbk; ==>cheracter_set_client ==>character_set_result; ==>character_set_connection; Connection: 連線層;字符集中間者統一了效率更高: 校對集問題: 校對集:資料比較的方式(三種方式) _bin:binary;二進位制比較取出二進位制位,一位一位進行比較,區分大小寫。 _ci:case sensitive; 大小寫敏感,區分大小寫; _ci:case insensitive; 大小寫不敏感。不區分大小寫。 檢查資料庫支援的校對集 Show collation; 對比:使用utf_8的_bin和_ci來驗證不同校對集的效果。 校對集:必須在沒有資料之間宣告好。 Web亂碼問題: 動態網站:部分構成; 瀏覽器:appache 伺服器(php)資料庫伺服器 三個部分都有自己的字符集;資料在三個部分之間傳遞很容易產生亂碼; 如何解決亂碼問題: 統一編碼(三碼合一); 事實上不可能:瀏覽器使用者管路(不能控制) 但是必須解決這些問題
,
回顧 資料庫基本知識:關係型資料庫與非關係型資料庫 關係型資料庫:安全(磁碟) 非關係型資料庫:高效(記憶體) 關係型資料庫:建立在關係模型上的資料庫, 資料結構:二維表(浪費空間) 資料庫操作指令:sql(DDL,DML,DCL) 完整性約束:表內和表之間(實體) Mysql關係型資料庫: C/S結構(直接認證傳送sql指令,伺服器處理指令返回結果,客戶端接受結果,分析結果) Mysql伺服器物件:DBMS----->DATABASE------->TABLE------>FIELD 資料庫基本操作:庫操作,表操作和資料操作。 字符集問題: 中文資料問題 1,改變伺服器接受資料字符集character_set_client 2,改變伺服器返回資料字符集character_set_result 3,快捷方式:set names 字符集; 亂碼問題: 瀏覽器解析:php處理 資料庫處理 校對集問題: 比較規則:_bin二進位制,_cs,_ci大小寫 演算法:快速排序。 資料型別: 列型別: 所謂資料型別:對資料進行統一分類 從系統資料角度出發就是為了使用統一方式進行管理 更好的利用有限的空間 Sql將資料型別分為三類: 數值型別,字串型別,時間日期型。
數值型: 數值型資料:都是資料,系統將資料分為整數型和小數型 整數型: 存放的都是資料 在sql因為要考慮節省磁碟 Tingint :迷你整型,使用一個儲存位元組(常用),最多狀態有256種 Smallint: 小整型,使用倆個位元組,表示狀態最多有65535種 Mediunint:中整型,使用三個位元組儲存 Int:表準整型,使用四個位元組儲存(常用) Bigint :大整型,使用八個位元組儲存。
在sql中資料庫全部都是預設有符號的;分正負,使用無符號資料:給約定的資料型別限定 Int unsigned --無符號,從零開始。 查看錶結構的時候,發現每個欄位的資料型別之後都會帶一個括號,裡面有指定數值 顯示寬度:資料最終顯示的位數(包含符號)如-123是四位,253是三位, 顯示寬度:沒什麼特別意義只是預設告訴使用者顯示的形式而已。實際上使用者可以控制,不會改變資料的實際大小。 顯示寬度的意義:在於當資料不夠顯示寬度的時候,會自動讓資料變成對應的顯示寬度: 通常需要搭配一個前導0來增加寬度,不改變值的大小:zerofill(零填充) 零填充的意義(顯示寬度):保證資料格式。 小數型: 帶小數點或者範圍超過整型的數值型別。 Sql中將小數型分為倆種:浮點型和定點型 浮點型:小數點浮動,精度有限,會丟失精度。 定點型:小數點固定,精度有限,不會丟失精度。
浮點型: 浮點型資料是一種精度型資料:因為超出規定範圍之後會丟失精度(四捨五入)。 浮點型分為倆種:float:單精度,佔用四個位元組儲存資料,大概七位。 Double:雙精度,佔用八個位元組儲存資料,大概十五位左右。 建立浮點數表:浮點的使用方式:直接float。 表示沒有小數部分;float(M,D)M表示總長度,D表示小數部分長度,整數部分長度為(M-1)。 浮點型資料的插入:整數部分不能超過長度,但是小數部分可以超過長度(系統會自動四捨五入)結果:浮點數一定會進行四捨五入(超出精度範圍)。 浮點數如果是因為系統進位導致整數部分超出指定長度:那麼系統也會允許成立。
定點型: 絕對的保持整數部分不會被四捨五入(不會丟失精度),小數部分有可能丟失(理論上小數部分也不會丟失精度)
浮點數如果進位導致長度溢位,沒有問題。但是定點數不行、
時間日期型: Datetime:時間日期,格式是YYYY-MM-DD HH:ii:ss Date :日期就是datetime的date部分 Time:時間段,指定某個區間之間,時間到時間 Timestamp:時間戳,是從1970開始的格式與datatime一致, Year:年份,兩種格式,year(2)。 插入資料: 時間time可以說負數,year可以使用2位數插入,也可以使用四位數。 Timestamp欄位:只要是當前所在記錄別更新,該欄位一定會自動更新成當前時間。
網站以php位實現主要操作物件,php有非常強大的日期處理函式:date,只需要一個時間戳就可以轉換成任意型別函式的時間:以php為主的時候,都是在資料庫使用時間戳(整型)來儲存時間。 字串型別: 在sql中將字串分為了6類 Char ,varchar,text,blob,set和enum Char:定長字串 定長字串。磁碟在定義結果的時候就已經確定了最終資料的儲存長度。 Char[L]:L代表length,可以儲存長度,單位為字元最大長度值為255 例:char[4]在utf8環境下需要43=12個位元組 Varchar:變長字串 Varchar在分配空間長度的時候,按照最大空間分配,但是實際上最終用了多少是根據具體的資料來確定, Varchar(L):L代表字元長度理論上長度65536個字元 但是會多1到2個位元組來確定儲存的實際長度 例:varchar(10)確實存了十個漢字,在utf8的環境下103+1=31位元組
如何選擇定長還是變成字串? 定長的磁碟空間比較浪費空間,但是效率高; 變長的磁碟空間比較節省但是,效率低; 如果資料基本上確定長度一樣,就是定長如果資料不能確定長度(不同資料有變化)
文字字串: 如果資料量特別大,通常超過255個字元,就會使用文字字串,文字字串會根據儲存資料的格式進行分類:text(文字儲存)和blob(二進位制資料,二進位制儲存路徑) 列舉字串:enum 列舉:enum,事先將可能出現的結構都設計好,實際上就是儲存資料必須是規定好的資料中的一個。 列舉使用方式 定義:enum(可能出現的元素列表) 如:enum(‘女’,’男’,’人妖’,’保密’,); 使用:儲存資料,只能儲存上面定義好的資料 例:建立列舉表,create table my_enum( Gender enum(‘男’,’女’,’人妖’) character utf8 加入資料;作用之一就是規範資料格式 資料只能是規定資料中的一個 Insert into my_enum values(‘男’),(‘人妖’); 作用之二節省空間(列舉 別名 單選框)(儲存的是數值)
在mysql中系統也是自動轉換資料格式的, 證明欄位儲存的是數值:將取出來的+0 就可以判斷出原來的資料到底是字串還是數值,如果是字串結果為0,否則為其他值。 例:select gender+0,gender from My_enum; 找出列舉元素的規律,按照元素出現順序從1開始編寫 列舉原理:列舉在進行資料規範的時候,系統會自動建立一個數值與列舉元素的對應關係(關係放在日誌中)然後在進行資料插入的時候,系統自動將字串轉換成對應的數字儲存,然後進行資料提取的時候,系統自動將數值轉換成對應的字串顯示。 集合字串: 集合跟列舉很類似:實際儲存的是數值而不是字串(集合是多選) 例:create table my_set (hobby set (‘籃球’,’足球’,’乒乓球’))charset utf8; 插入資料:可以使用多元素字串進行組合,也可以數值。 例:insert into my_set values (‘足球’) Insert into my_set values(2)
集合中:每一個元素對應一個二進位制位,被選中為一,沒有則為零,最後方向反過來 例:110------>011=3 Select hobby +0 ,hobby from my_set; 集合元素的順序沒有關係,最終系統會匹配順序; 集合的強大功能在於能夠規範資料和節省空間。 Php也可以規範資料但是對於php來說效率優先;而且資料的維護可以通過數值進行增加php的維護成本;php根本沒有辦法判斷資料在資料庫的形式。
MySql記錄長度 Mysql規定:任何一條記錄最長不能超過65535個位元組(varchar永遠達不到理論值) Varchar實際儲存長度能達到多少呢,看字符集 在utf8下varchar的實際頂配varchar(21844)21844個字元-----218443+2=65532+2=65534 Gbk下實際頂配varchar(32766)32766個字元 ------327662+2=65532+2=65534 Mysql記錄中如果任何一個欄位允許為空,那麼系統會自動從整個記錄中保留一個位元組儲存在null(若想釋放null所佔用的位元組,必須保證所有欄位不為空)
Mysql中text文字字串,不佔用記錄長度;額外儲存,但是text文字字串也是記錄的一部分一定需要佔據部分長度:10位元組(保留資料的地址以及長度) 列屬性: 列屬性:真正約束欄位的是資料型別,但是資料型別的約束很單一,需要一些額外的約束來保證資料的完整性
列屬性:null/not null Default Primary key Unque key Auto_increment Comment 空屬性:null Null(預設的和not null不為空)雖然是預設的,資料基本上都是欄位為空,但是實際上真正開發的時候,盡肯能地保證所有的資料都不為空;空資料沒有意義,空資料不能參加運算。 列描述:comment 沒有實際意義,專門用來描述欄位,會根據表的建立語句儲存(用來給dba)瞭解的。 例:comment’姓名’;
預設值:default 某種資料會經常出現在某個具體的值 想要使用某個預設值,可以不一定指定列表,不使用欄位列表,可以使用default關鍵字代替值 例:insert into my_default values(‘張三’,18,default); 回顧 欄位型別(列型別):數值型,時間日期型,字串型別 數值型:整型,小數型(浮點與定點) 時間日期型:datetime,time,datetimestamp,year 字串型別:定長,變成, 文字字串(text和blob) 列舉與集合 Mysql記錄長度:65535個位元組 Null佔一個位元組 text文字不佔用記錄長度,本身十個位元組 欄位屬性:空屬性,列描述,預設值 欄位屬性: 主鍵,唯一鍵,自增長。 主鍵: Primary key 主要的鍵,一張表只能有一個欄位能使用對應的鍵,用來唯一約束該欄位裡面的資料不能重複,稱之為主見。 一張表最多隻有一個主鍵。 增加主鍵: Sql操作當中有很多方式給表增加主鍵,大體上有三種 方案一: 建立表的時候,直接加在欄位之後跟primary key 例:name varcahr(20) primary key; 方案二: 複合主鍵 方案三: 當表已經建立好之後,再次額外追加主鍵,通過修改表字段的屬性,也可以直接追加 Alter table 表名 add primary key (欄位列表) ; 前提是:欄位名不重複; 主鍵約束: 主鍵定義的欄位中不允許重複;一旦重複資料操作失敗(改,增) 更改主鍵&刪除主鍵 Alter table 表名 drop primary 主鍵分類: 在實際建立表的過程中,很少使用真業務資料作為主鍵欄位(業務主鍵) 大部分使用邏輯性欄位(欄位沒有業務含義)將這種欄位稱之為邏輯主鍵。 自動增長: 自增長: 定義欄位給的是預設值,不給值為null,會自動被系統觸發,系統會從以前欄位已有的最大值進行+1操作得到行的不同的欄位。 自增長通常與主鍵搭配 特點: auto_increment 1,任何一個欄位要做自增長必須前提是本身是一個索引(key一欄有值) 2,自增長欄位必須死數字(int 整型) 3,一張表最多隻有一個自增長。 例:ID int primary key auto_increment comment’自動增長’; 自增長得使用 當自增長被給定的值為null 或者預設值的時候會自動增長 自增長如果對應的欄位輸入了值,那麼自增長失效 下一次還是能夠正確的自增長(最大值+1) 修改自增長: 自增長如果涉及到欄位改變,必須先刪除自增長(一張表只能有一個自增長)。 修改當前自增長已經存在的值,修改只能比當前已有的自增長的最大值大,不能為null。 Alter table 表名 atuo_increment=值 思考?為什麼自增長都是從一開始為什麼每次都是自增長一呢 所有系統的實現(如字符集,校對集)都是由系統內部變數控制的,檢視自增長對應的變數 Show variables like ‘auto_increment’;
可以修改變數實現不同的效果;修改是對整個資料而不是單張表(修改只是會話級) Set auto_incretment_increment=值—自增值 刪除自增長: 自增長是欄位的屬性,通過modify來進行修改(保證欄位沒有auto_increment) Alter table 表名 modify 欄位型別; 唯一鍵: 一張表往往有很多欄位需要具有唯一性,資料不能重複;但是一張表只能有一個主鍵。唯一鍵(unque key)就可以解決表中有很多欄位需要唯一性約束。 本質與主鍵一致,唯一鍵允許自動為空(空欄位不參與唯一性比較) 增加唯一鍵(三種) 方案一: 在建立表的時候欄位後直接跟unque/unque key 例:name char(10) unque; 方案二: 在所有欄位之後自動增加unque key(欄位列表)—複合唯一鍵 Unque key (name); 方案三: 在建立表之後增加唯一鍵 Alter table 表名 add unque key (欄位); 唯一鍵約束 唯一鍵與主鍵本質相同,唯一鍵區別就是唯一鍵預設允許為空,而且是多個為空 更新唯一鍵和刪除唯一鍵: 先刪除後新增(唯一鍵可以有多個) Alter table 表名 drop index 索引名字 索引: 幾乎所有的索引都建立在欄位之上。 索引:系統根據某種演算法將已有的資料(未來可能增加的資料),單獨建立一個檔案,檔案能夠實現快速匹配資料並且能夠快速地找到對應表中的記錄 意義: 1,提升查詢資料的效率 2,約束資料的有效性(唯一性等) 增加索引的前提條件:索引本身會產生索引檔案(有時候可能比資料檔案還大)會非常耗費磁碟空間 如果某個欄位作為查詢條件經常使用你們可以使用索引(一定會想辦法增加) Mysql中提供了多種索引: 1、主鍵索引 2、唯一索引 3、全文索引 4、普通索引 全文索引: 針對文章內部關鍵字進行索引, 全文索引最大的問題:在於如何確定關鍵字 英文很容易:英文單詞與單詞之間有空格,中文很難,沒有空格,而中文可以多種隨意組合(分詞:spinx) 關係 將實體與實體的關係,反應到最終資料表的設計上來,將關係分為三種,一對多,多對多,多對多。 所有關係都是表與表之間的關係。 一對一: 一張表的一條記錄一定只對應另外一張表的一條記錄,反之亦然。 例 Id 姓名 性別 年齡 電話號碼 1 張三 男 23 13320848263
一對多 一張表中有一條記錄,對應另一張表多條記錄但是反過來,另一張表的一條記錄只能對應這張表的一條記錄。 例母親與孩子的關係 多對多 一張表中的一條記錄對應另外一張表的多條記錄,同時另一張表的一條記錄對應另外一張表的多條記錄。 正規化 Normal format 是一找種離散型數學中的知識,為解決資料儲存的與優化問題, 資料儲存以後,凡是能夠通過關係找出來的資料,堅決不在重複儲存:終極目標是減少資料的冗餘。 正規化是一種分層的結構規範,分為六層,每一層都比上一層嚴。若要滿足下一正規化,前提是滿足上一層正規化。 六層正規化:1NF,2NF,3NF.4NF,5NF,6NF最高 Mysql屬於關係型資料庫有空間浪費:致力於節省儲存空間,與正規化所解決的問題不謀而活:在設計資料庫,會利用正規化來指導設計,但是資料不單是解決空間問題,要保護效率問題,正規化只為解決空間問題,所以資料庫的設計又不可能完全按照正規化要求實現,一般只有前三種正規化需求滿足。 正規化在資料庫中有指導意義:但是不強制規範。 第一正規化:1NF 在設計表儲存資料的時候,如果表中設計的欄位儲存的資料,再取出來的使用之前還需要額外的處理(拆分)那麼說表的設計不滿足第一正規化=>第一正規化要求欄位的資料具有原子性=>不可再分。 第二正規化:2NF 再資料表設計過程中,如果有複合主鍵(多欄位主鍵),且表中有欄位並不是由整個主鍵來確定,而是依靠主鍵的某個欄位(主鍵的一部分)=>存在欄位約束主鍵的部分問題,稱之為部分依賴=>第二正規化就是要解決表中不允許出現部分依賴。 取消複合主鍵,使用邏輯主鍵。 第三正規化:3NF 要滿足第三正規化,必須滿足第二正規化。 第三正規化:理論上講,y應該一張表中所有欄位都應該有直接依賴主鍵(邏輯主鍵代表業務主鍵),如果表設計中存在一個欄位,並不直接依賴主鍵而是通過某個非主鍵欄位依賴,最終實現依賴主鍵。把這種不是直接依賴主鍵而是依賴非主鍵欄位的依賴關係稱之為依賴傳遞
逆規範化 磁碟利用率與效率的對抗,有時候再設計表的時候如果一張表中有就幾個欄位需要從別的表中去獲取資訊,理論上講的確可以獲得想要的資料,但是效率低一點,會刻意的在某些表中,不去儲存外表的主鍵(邏輯主鍵)而是直接儲存想要的資料資訊這樣一來在查詢資料的時候,一張表可以直接提供資料,而不需要多表查詢(效率低)。 資料的高階操作: 資料的操作:增刪查改。 高階新增資料 Insert into 表名(欄位列表) values (值列表); 在資料插入的時候,假設主鍵對應的值已經存在,插入一定會失敗。 主鍵衝突: 當主鍵存在衝突的時候(Duplicate key) 可以選擇性進行處理:更新和替換 高階操作更新: Insert into 表名 [field主鍵] values (值列表) on duplicate key update 欄位=新值; 主鍵衝突例子:insert into my_sql values (‘php’,’B101’); 更新:insert into my_sql values (‘php’,B101’) on duplicate key update room =’B102’;
替換 Replace into 表名[欄位主鍵] values (值列表) 例:replace into my_sql values (‘Java’,’102’); 蠕蟲複製: 蠕蟲複製:從已有的資料表中獲取資料,然後將資料又進行新增操作,資料成部的增加。 表建立高階操作:從已有表建立新表(複製表結構) Create table 表名 like 資料庫.表名; 蠕蟲複製:先查出資料,然後再將查出的資料新增n遍 Insert into 表名(欄位) select 欄位列表/* from 資料表名;; 蠕蟲複製的意義: 1,從已有表拷貝資料到新表中 2,可以迅速讓表中資料膨脹到一定的數量級;測試表的壓極效率; 高階更新資料 Update Update 表名 set 欄位 =值[where條件]; 高階新增語法 Update 表名 set 欄位 =值[where條件][limit 更新數量]; 例:update my_copy set name =’c’ where name =’a’ limit =3; 刪除資料與更新類似 Delete from表名 [where條件][limit 數量]; 例:delete from my_copy where name =’a’ limit=3; 刪除:如果表中存在主鍵自增長,那麼當刪除之後自增長不會還原。 思路:資料的刪除是不會改變表結構,只能刪除表後重建 Truncate 表名; 先刪除改變後新增改變 清空表,重置自增長。 查詢資料 Select 欄位列表/* from表名 [where條件]; 完整語法: Select [select選項] 欄位列表 [欄位別名] /* from資料來源 [where條件子句] [group by 子句] [ having 子句] [order by 子句] [limit 子句];
select選項 Select對查詢出來的結果處理方式 All:預設的保留所有結果。 Distinct:去重,查出來的結果,將重複的結構去除(所有欄位相同)。 欄位別名 當資料查詢出來以後,有時候名字不一定就滿足需求(多表查詢的時候,會有同名的欄位) 就需要對欄位名進行重新命名:別名:欄位名 [as] 別名; 資料來源 資料來源:資料的來源,關係型資料庫的來源都是資料表,本質上可以保證資料類似二維表,最終都可以作為資料來源, 資料來源分為多種:單標資料來源,多表資料來源,查詢語句。 單標資料來源 Select * from 表名; 多表資料來源 Select *from 表名1,表名2…; 從一張表中取出一條記錄,去另外一張表中匹配所有記錄,而且全部保留(記錄數和欄位數),將這種結果稱之為笛卡爾積(交叉連線) 笛卡爾積沒什麼用,應該儘量避免。 子查詢 資料的來源是一條查詢語句(查詢語句結果是二維表) Select * from (select 語句) as 表名; Where 子句 Where 子句,用來判斷資料,篩選資料, Where子句會返回結果:0/1;true/false 判斷條件:運算子:<,>,<=,>=,!=,<>,like between and ,notin/in 邏輯運算子:&&(and),or where原理 Where 是唯一一個直接從磁碟讀取資料的時候就開始判斷的條件,從磁碟取出一條記錄,開始進行where 判斷,成立儲存到記憶體,失敗則放棄 條件查詢 要求找: Group by 子句 分組 根據某個欄位分組(同為一組) 基本語法:group by 欄位名 意義:統計資料(按分組欄位進行陣列統計) SQL提供了一系列統計函式 Count©:統計分組後記錄數,每組多少記錄。 Max():最大值 MIn():最小值 Avg():平均數 Sum():求和 Count函式:裡面可以使用兩種引數,*代表統計記錄 欄位名代表統計對應欄位(null不統計) 分組會自動排序,根據分組欄位:預設排序 Group by 欄位[desc/asc] ;多分組結果然後合併之後的整個結果進行排序; 多欄位分組:先根據一個欄位進行分組,然後對分組厚度結果按照其他欄位進行分組。 有一個函式:可以對分組結果中的某個欄位進行字串連線(保留該欄位所有的欄位): Group _concat(欄位) 回溯統計:with rollup :任何一個分組後都會有一個小組,最後都需要向上級分組進行彙報統計:根據當前分組欄位,回溯統計的時候會將分組欄位置空 多欄位回溯:考慮第一層分組會有此回溯:第二次分組要看第一層分組的組數,組數是多少回溯就是多少,然後加上第一層 Having子句 與where 子句一樣;進行條件判斷的,where是對磁碟資料進行判斷,進入到記憶體以後經常分組操作,分組結果就需要having 來處理。 Having 能做where能做的幾乎所有事情,但是where不能做having能做的很多事情。 1)分組統計的結果就是或者是說統計函式都只有having 能夠使用 2)Having 能夠使用做的別名,where不能=>where是從磁碟讀取資料,而名字可能是欄位進入到記憶體後產生的。 Order by子句 Order by子句:排序,根據某個欄位進行升序或者降序,排序依賴校對集。 基本語法:order by 欄位名 [asc/desc] Asc:是升序(預設的) Desc:降序 排序可以進行多欄位排序:先根據某個欄位進行排序然後排序好內部。再按照某個資料進行排序。
Limit子句 Limit 子句是限制結果的語句,限制數量 Limit有兩種使用方式 方案1:只用來限制長度(資料量) Limit 資料量; 方案2: 限制起始位置,限制數量:limit 起始位置,長度 主要用來實現資料的分頁:為當前使用者節省時間提高伺服器的響應效率,減少資源的浪費。 對於使用者來講:可以點選的分頁按鈕1,2,3,4 對於伺服器來講:根據使用者選擇的頁碼來獲取不同的資料:limit offset, Length; Length:每頁顯示的資料量,基本不變; Offset: offset=(頁碼-1)*每頁顯示量。