回顧
數(shù)據(jù)庫基礎知識:關系型數(shù)據(jù)庫(磁盤)和非關系型數(shù)據(jù)庫(內存)
關系型數(shù)據(jù)庫:建立在關系模型上的數(shù)據(jù)庫
數(shù)據(jù)結構:二維表(比較浪費空間)
操作數(shù)據(jù)的指令集合:SQL(DDL, DML[DQL], DCL)
完整性約束:表內和表之間(實體)
Mysql關系型數(shù)據(jù)庫:c/s結構軟件(連接認證, 發(fā)送SQL指令, 服務器處理指令返回結果, 客戶端接收結果解析結果)
Mysq服務端對象:DBMS -> Database -> Table -> fields
SQL基本操作:庫操作,表操作(字段),數(shù)據(jù)操作
字符集問題:中文數(shù)據(jù)問題
改變服務器接收數(shù)據(jù)的字符集:character_set_client
改變服務器返回數(shù)據(jù)的字符集:character_set_results
快捷方式:set names 字符集(三件事情)
校對集問題:比較規(guī)則:_bin,_cs,_ci(利用排序實現(xiàn))
web亂碼問題:瀏覽器解析,php處理(本地文件),數(shù)據(jù)庫處理
數(shù)據(jù)類型(列類型)
所謂的數(shù)據(jù)類型:對數(shù)據(jù)進行統(tǒng)一的分類,從系統(tǒng)的角度出發(fā)為了能夠使用統(tǒng)一的方式進行管理:更好的利用有限的空間
SQL中將數(shù)據(jù)類型分成了三大類:數(shù)值類型、字符串類型和時間日期類型
數(shù)值型:
數(shù)據(jù)型數(shù)據(jù):都是數(shù)值
系統(tǒng)將數(shù)值型分為整數(shù)型和小數(shù)型
整數(shù)型:
存放整型數(shù)據(jù):在SQL中因為更多要考慮如何節(jié)省磁盤空間,所以系統(tǒng)將整型又細分成了5類:
Tinyint:迷你整型,使用一個字節(jié)存儲,表示的狀態(tài)最多為256中(常用)
Smallint:小整型,使用2個字節(jié)存儲,表示的狀態(tài)最多為65536種
Mediumint:中整型,使用3個字節(jié)存儲
Int:標準整型,使用4個字節(jié)存儲(常用)
Bigint:大整型,使用8個字節(jié)存儲
創(chuàng)建一張整型表:
插入數(shù)據(jù):只能插入整型,只能插入范圍內的整型
SQL中的數(shù)據(jù)類型全部都是默認有符號:分正負
有時候需要使用無符號數(shù)據(jù):需要給數(shù)據(jù)類型限定:int unsigned,無符號:從0開始
給表增加一個無符號類型;
數(shù)據(jù)的插入
查看表結構的時候,發(fā)現(xiàn)每個字段的數(shù)據(jù)類型之后都會自帶一個括號,里面有指定的數(shù)字
顯示寬度:沒有特別的含義,只是默認的告訴用戶可以顯示的形式而已:實際上用戶是可以控制的,這種控制不會改變數(shù)據(jù)本身的大小
顯示寬度的意義:在于當數(shù)據(jù)不夠顯示寬度的時候,會自動讓數(shù)據(jù)變成對應的顯示寬度:通常需要搭配一個前導0來增加寬度,不改變值大小:zerofill(零填充):零填充導致數(shù)值自動變成無符號
零填充+顯示效果
零填充的意義(顯示寬度):保證數(shù)據(jù)格式
小數(shù)型
小數(shù)型:帶有小數(shù)點或者范圍超出整型的數(shù)值類型。
SQL中:將小數(shù)型細分為兩種:浮點型和定點型
浮點型:小數(shù)點浮動,精度有限,而且丟失精度
定點型:小數(shù)點固定,精度固定,不會丟失精度
浮點型
浮點型數(shù)據(jù)是一種精度型數(shù)據(jù):因為超出指定范圍之后,會丟失精度(自動四舍五入)
浮點型:理論分為兩種精度
Float:單精度,占用4個字節(jié)存儲數(shù)據(jù),精度范圍大概為7位左右
Double:雙精度,占用8個字節(jié)存儲數(shù)據(jù),精度范圍大概為15位左右
創(chuàng)建浮點數(shù)表:浮點的使用方式:直接float表示沒有小數(shù)部分,float(M, D)M代表總長度,D代表小數(shù)部分長度
插入數(shù)據(jù):可以是直接小數(shù),也可以是科學計數(shù)法
浮點數(shù)數(shù)據(jù)的插入:整型部分是不能超出長度的,但是小數(shù)部分可以超出長度(系統(tǒng)會自動四舍五入)
結果:浮點數(shù)一定會進行四舍五入(超出精度范圍):浮點數(shù)如果是因為系統(tǒng)進位導致整數(shù)部分超出指定長度,那么系統(tǒng)也會允許成立
定點型
定點型:絕對的保證整數(shù)部分不會被四舍五入(不會丟失精度),小數(shù)部分有可能(理論上小數(shù)部分也不會丟失精度)
創(chuàng)建定點數(shù)表,增加一個浮點數(shù)作為對比
插入數(shù)據(jù):定點數(shù)的整數(shù)部分一定不能超過長度(進位不可以),小數(shù)部分長度可以隨意超出(系統(tǒng)自動四舍五入)
浮點數(shù)如果進位導致長度溢出沒有問題,但是定點數(shù)不行
查看數(shù)據(jù)效果:
時間日期類型
Datetime:時間日期,格式是YYYY-mm-dd HH:ii:ss,表示的范圍是從1000到9999年,有0值,0000-00-00 00:00:00
Date:日期,就是datetime中的date部分
Time:時間(段),指定的某個區(qū)間之間,-時間到+時間
Timestamp:時間戳,并不是時間戳,只是從1970年開始的YYYY-mm-dd HH:ii:ss格式與datetime完全一致
Year:年份,兩種形式y(tǒng)ear(2)和year(4):1901—2155
創(chuàng)建時間日期表:
插入數(shù)據(jù):時間time可以是負數(shù),而且可以是很大的負數(shù),year可以使用2位數(shù)插入,也可以使用4位數(shù)
timestamp字段:只要當前所在的記錄被更新,該字段一定 會自動更新成當前時間
網(wǎng)站是以PHP為實現(xiàn)的主要操作對象:PHP中有非常強大的時間日期處理函數(shù):date,只需要一個時間戳
就可以轉換成任意類型的時間:以PHP為主的時候,都是在數(shù)據(jù)庫使用時間戳(整型)來存儲時間
字符串類型
在SQL中,將字符串類型分成了6類:char,varchar,text,blob,enum和set
定長字符串
定長字符串:char,磁盤(二維表)在定義結構的時候,就已經(jīng)確定了最終數(shù)據(jù)的存儲長度。
Char(L):L代表length,可以存儲的長度,單位為字符,最大長度值為255.
Char(4):在utf8環(huán)境下,需要4*3=12個字節(jié)。
變長字符串
變長字符串:varchar,在分配空間的時候,按照最大的空間分配:但是實際上最終用了多少,是根據(jù)
具體的數(shù)據(jù)來確定。
Varchar(L):L表示字符長度,理論長度是65536個字符,但是會多出1到2個字節(jié)來確定存儲的實際長度。
但是實際上如果長度超過255,既不用定長也不用變長,使用字符串text。
Varchar(10):的確存了10個漢字,utf8環(huán)境,10*3+1=31個字節(jié),小于255多出一個字節(jié),大于255多出兩個字節(jié)。
實際存儲長度 | Char(4) | Varchar(4) | Char占用字節(jié) | Varchar占用字節(jié) |
---|---|---|---|---|
ABCD | ABCD | ABCD | 4 * 3 = 12 | 4 * 3 + 1 = 13 |
A | A | A | 4 * 3 = 12 | 1 * 3 + 1 = 4 |
ABCDE | × | × | 數(shù)據(jù)超過長度 | 數(shù)據(jù)超過長度 |
定長與變長的存儲實際空間(utf8)
實際存儲長度 | Char(4) | Varchar(4) | Char占用字節(jié) | Varchar占用字節(jié) |
---|---|---|---|---|
ABCD | ABCD | ABCD | 4 * 3 = 12 | 4 * 3 + 1 = 13 |
A | A | A | 4 * 3 = 12 | 1 * 3 + 1 = 4 |
ABCDE | × | × | 數(shù)據(jù)超過長度 | 數(shù)據(jù)超過長度 |
如何選擇定長或者變長字符串呢?
定長的磁盤空間比較浪費,但是效率高:如果數(shù)據(jù)基本上確定長度都一樣,就是使用定長,
如 身份證、手機號碼
變長的磁盤空間比較節(jié)省,但是效率低:如果數(shù)據(jù)不能確定長度(不同數(shù)據(jù)有變化),如姓名、地址
文本字符串
如果數(shù)據(jù)量非常大,通常說超過255個字符串就會使用文本字符串
文本字符串根據(jù)存儲的數(shù)據(jù)的格式進行分類:text和blob
text:存儲文字(二進制數(shù)據(jù)實際上都是存儲路徑)
blob:存儲二進制數(shù)據(jù)(通常不用)
枚舉
枚舉:enum,事先將所有可能出現(xiàn)的結果都設計好,實際上存儲的數(shù)據(jù)必須是規(guī)定好的數(shù)據(jù)中的一個
枚舉的使用方式
定義:enum(可能出現(xiàn)的元素列表); 如enum('男', '女', '保密')
使用:存儲數(shù)據(jù),只能存儲上面定義好的數(shù)據(jù)
創(chuàng)建枚舉表
加入數(shù)據(jù):作用之一:規(guī)范數(shù)據(jù)格式:數(shù)據(jù)只能是規(guī)定數(shù)據(jù)中的其中一個
作用之二:節(jié)省存儲空間(枚舉通常有一個別名:單選框),枚舉實際存儲的是數(shù)值而不是字符串本身
在mysql中,系統(tǒng)也是自動轉換數(shù)據(jù)格式的:而且基本與PHP一樣(尤其是字符串轉數(shù)字)
證明字段存儲的數(shù)據(jù)是數(shù)值:將數(shù)據(jù)取出來+0就可以判斷出原來的數(shù)據(jù)存的到底是字符串還是數(shù)值:如果
是字符串最終結果永遠為0,否則就是其他值
找出了枚舉元素的實際規(guī)律,按照元素出現(xiàn)的順序,從1開始編號
枚舉原理:枚舉在進行數(shù)據(jù)規(guī)范的時候(定義的時候),系統(tǒng)會自動建立一個數(shù)字與枚舉元素的對應關系(關系放到日志中):
然后在進行數(shù)據(jù)插入的時候,系統(tǒng)自動將字符串轉換成對應的數(shù)字存儲,然后在進行數(shù)據(jù)提取的時候,系統(tǒng)自動將數(shù)值轉換成
對應的字符串顯示。
因為枚舉實際存儲的是數(shù)值,所以可以直接插入數(shù)值
集合字符串
集合跟枚舉很類似:實際存儲的是數(shù)值,而不是字符串(集合是多選)
集合使用方式:
定義:set(元素列表)
使用:可以使用元素列表中的元素(多個),使用逗號分隔
創(chuàng)建集合表
插入數(shù)據(jù):可以使用多個元素字符串組合,也可以直接插入數(shù)值
查看數(shù)據(jù):數(shù)據(jù) + 0查看
集合中:每一個元素都是對應一個二進制位,被選中為1,沒有則為0,最后反過來。
集合中的順序沒有關系:最終系統(tǒng)都會去匹配順序
集合的強大在于能夠規(guī)范數(shù)據(jù)和節(jié)省空間:PHP也可以規(guī)范數(shù)據(jù),但是對于PHP來說效率優(yōu)先,
而且數(shù)據(jù)的維護可以通過數(shù)字進行,增加PHP的維護成本:PHP根本沒有辦法判斷數(shù)據(jù)在數(shù)據(jù)庫
的形式。
Mysql記錄長度
Mysql中規(guī)定: 任何一條記錄最長不能超過65535個字節(jié)。(varchar永遠達不到理論值)。
varchar的實際存儲長度能達到多少呢?看字符集編碼。
utf8下varchar的實際頂配:21844字符
gbk下varchar的實際頂配:32766字符
想利用完整個65535字節(jié)長度:增加一個tinyint字段即可。
mysql記錄中,如果有任何一個字段允許為空,那么系統(tǒng)會自動從整個記錄中保留一個字節(jié)來存儲NULL
若想釋放NULL所占用的字節(jié):必須保證所有的字段都不允許為空
Mysql中text文本字符串,不占用記錄長度:額外存儲。但是text文本字符串也是屬于記錄的一部分
一定需要占據(jù)記錄中的部分長度:10個字節(jié)。(保存數(shù)據(jù)的地址和長度)
列屬性
列屬性:真正約束字段的是數(shù)據(jù)類型,但是數(shù)據(jù)類型的約束很單一。需要有一些額外的約束,
來更加保證數(shù)據(jù)的合法性。
列屬性有很多:NULL/NOT NULL,default,Primary key,unique key, auto_increment,comment
空屬性
兩個值:NULL(默認的)和NOT NULL(不為空)
雖然是默認的,數(shù)據(jù)庫基本都是字段為空,但是實際上在真實開發(fā)的時候,盡可能的要保證
所有的數(shù)據(jù)都不應該為空:空數(shù)據(jù)沒有意義;空數(shù)據(jù)沒有辦法參與運算。
創(chuàng)建一個實際案例表:班級表(名字,教室)
列描述
列描述:comment,描述,沒有實際含義:是專門用來描述字段,會根據(jù)表創(chuàng)建語句保存:
用來給程序員(數(shù)據(jù)庫管理員)來了解的。
默認值
默認值:某一種數(shù)據(jù)會經(jīng)常性的出現(xiàn)某個具體的值,可以在一開始就指定好。
在需要真實數(shù)據(jù)的時候,用戶可以選擇性的使用默認值。
默認值的生效:插入數(shù)據(jù)的時候不設置即可
想要使用默認值,可以不一定去指定這個列表,故意不使用字段列表:可以使用default關鍵字代替值