數據庫基礎知識: 關係型數據庫(磁盤)和非關係型數據庫(內存)mysql
關係型數據庫: 創建在關係模型上的數據庫web
數據結構: 二維表(比較浪費空間)算法
操做數據的指令集合: SQL(DDL,DML[DQL]和DCL)sql
完整性約束: 表內和表之間(實體)數據庫
Mysql關係型數據庫: c/s結構軟件(鏈接認證, 發送SQL指令, 服務器處理指令返回結果,客戶端接收結果解析結果)瀏覽器
Mysql服務端對象: DBMS -> Database -> Table -> fields服務器
SQL基本操做: 庫操做, 表操做(字段)和數據操做數據結構
字符集問題: 中文數據問題ide
改變服務器接收數據的字符集: character_set_client函數
改變服務器返回數據的字符集: character_set_results
快捷方式: set names 字符集(三件事情)
web亂碼問題: 瀏覽器解析, PHP處理(本地文件), 數據庫處理
校對集問題: 比較規則: _bin, _cs和_ci, 利用排序(order by)
算法: 快速排序(遞歸)
--default-character-set=latin1 -- latin1一個字符對應一個字節
所謂的數據類型: 對數據進行統一的分類, 從系統的角度出發爲了可以使用統一的方式進行管理: 更好的利用有限的空間.
SQL中將數據類型分紅了三大類: 數值類型, 字符串類型和時間日期類型
數值型數據: 都是數值
系統將數值型分爲整數型和小數型.
存放整型數據: 在SQL中由於更多要考慮如何節省磁盤空間, 因此係統將整型又細分紅了5類:
Tinyint: 迷你整型,使用一個字節存儲, 表示的狀態最多爲256種(經常使用)
Smallint: 小整型,使用2個字節存儲,表示的狀態最多爲65536種
Mediumint: 中整型, 使用3個字節存儲
Int: 標準整型, 使用4個字節存儲(經常使用)
Bigint: 大整型,使用8個字節存儲
建立一張整形表
插入數據: 只能插入整型, 只能插入範圍內的整型
SQL中的數值類型所有都是默認有符號: 分正負
有時候須要使用無符號數據: 須要給數據類型限定: int unsigned; -- 無符號: 從0開始
數據的插入
查看錶結構的時候,發現每一個字段的數據類型以後都會自帶一個括號,裏面有指定的數字
顯示寬度: 沒有特別的含義, 只是默認的告訴用戶能夠顯示的形式而已: 世界上用戶是能夠控制的,這種控制不會改變數據自己的大小.
顯示寬度的意義: 在於當數據不夠顯示寬度的時候,會自動讓數據變成對應的顯示寬度: 一般須要搭配一個前導0來增長寬度, 不改變值大小: zerofill(零填充): 零填充會致使數值自動變成無符號
零填充+顯示寬度的效果
零填充的意義(顯示寬度): 保證數據格式
小數型: 帶有小數點或者範圍超出整型的數值類型.
SQL中: 將小數型細分紅兩種: 浮點型和定點型
浮點型: 小數點浮動, 精度有限,並且會丟失精度
定點型: 小數點固定, 精度固定, 不會丟失精度
浮點型
浮點型數據是一種精度型數據: 由於超出指定範圍以後, 會丟失精度(自動四捨五入)
浮點型: 理論分爲兩種精度
Float: 單精度, 佔用4個字節存儲數據, 精度範圍大概爲7位左右
Double: 雙精度,佔用8個字節存儲數據, 精度方位大概爲15位左右
建立浮點數表: 浮點的使用方式: 直接float表示沒有小數部分; float(M,D): M表明總長度,D表明小數部分長度, 整數部分長度爲M-D
插入數據: 能夠是直接小數,也能夠是科學計數法
浮點型數據的插入: 整型部分是不能超出長度的,可是小數部分能夠超出長度(系統會自動四捨五入)
結果: 浮點數必定會進行四捨五入(超出精度範圍): 浮點數若是是由於系統進位致使整數部分超出指定的長度,那麼系統也容許成立.
定點型
定點型: 絕對的保證整數部分不會被四捨五入(不會丟失精度),小數部分有可能(理論小數部分也不會丟失精度)
建立定點數表: 以浮點數做爲對比
插入數據: 定點數的整數部分必定不能超出長度(進位不能夠),小數部分的長度能夠隨意超出(系統自動四捨五入)
浮點數若是進位致使長度溢出沒有問題,可是定點數不行
查看數據效果
Datetime: 時間日期, 格式是YYYY-mm-dd HH:ii:ss,表示的範圍是從1000到9999年,有0值: 0000-00-00 00:00:00
Date: 日期,就是datetime中的date部分
Time: 時間(段), 指定的某個區間之間, -時間到+時間
Timestamp: 時間戳, 並非時間戳,只是從1970年開始的YYYY-mm-dd HH:ii:ss格式與datetime徹底一致
Year: 年份,兩種形式, year(2)和year(4): 1901-2156
建立時間日期表
插入數據: 時間time能夠是負數,並且能夠是很大的負數, year可使用2位數插入,也可使用4位數
Timestamp字段: 只要當前所在的記錄被更新, 該字段必定會自動更新成當前時間
網站是以PHP爲實現的主要操做對象: PHP中有很是強大的時間日期處理函數: date,只須要一個時間戳就能夠轉換成任意類型的時間: 以PHP爲主的時候, 都是在數據庫使用時間戳(整型)來存儲時間.
在SQL中,將字符串類型分紅了6類: char,varchar,text , blob, enum和set
定長字符串: char, 磁盤(二維表)在定義結構的時候,就已經肯定了最終數據的存儲長度.
Char(L): L表明length, 能夠存儲的長度, 單位爲字符, 最大長度值能夠爲255.
Char(4): 在UTF8 環境下,須要4 * 3 = 12個字節
變長字符串: varchar, 在分配空間的時候, 按照最大的空間分配: 可是實際上最終用了多少,是根據具體的數據來肯定.
Varchar(L): L表示字符長度 理論長度是65536個字符, 可是會多處1到2個字節來肯定存儲的實際長度: 可是實際上若是長度超過255,既不用定長也不用變長, 使用文本字符串text
Varchar(10): 的確存了10個漢字, utf8環境, 10 * 3 + 1 = 31(bytes)
存儲了3個漢字: 3 * 3 + 1 = 10(bytes)
定長與變長的存儲實際空間(UTF8)
實際存儲數據 |
Char(4) |
Varchar(4) |
Char佔用字節 |
Varchar(佔用字節) |
ABCD |
ABCD |
ABCD |
4 * 3 = 12 |
4 * 3 + 1 = 13 |
A |
A |
A |
4 * 3 = 12 |
1 * 3 + 1 = 4 |
ABCDE |
數據超過長度 |
數據超過長度 |
如何選擇定長或者是變長字符串呢?
定長的磁盤空間比較浪費, 可是效率高: 若是數據基本上肯定長度都同樣, 就是使用定長, 如身份證, 電話號碼, 手機號碼等
變長的磁盤空間比較節省, 可是效率低: 若是數據不能肯定長度(不一樣數據有變化), 如姓名, 地址等
若是數據量很是大, 一般說超過255個字符就會使用文本字符串
文本字符串根據存儲的數據的格式進行分類: text和blob
Text: 存儲文字(二進制數據,實際上都是存儲路徑)
Blob: 存儲二進制數據(一般不用)
枚舉: enum, 事先將全部可能出現的結果都設計好, 實際上存儲的數據必須是規定好的數據中的一個.
枚舉的使用方式
定義: enum(可能出現的元素列表); //如enum('男','女','不男不女','妖','保密');
使用: 存儲數據,只能存儲上面定義好的數據
建立枚舉表
加入數據: 做用之一: 規範數據格式: 數據只能是規定的數據中的其中一個
做用之二: 節省存儲空間(枚舉一般有一個別名: 單選框): 枚舉實際存儲的是數值而不是字符串自己.
在mysql中,系統也是自動轉換數據格式的: 並且基本與PHP同樣(尤爲是字符串轉數字)
證實字段存儲的數據是數值: 將數據取出來 + 0 就能夠判斷出原來的數據存的究竟是字符串仍是數值: 若是是字符串最終結果永遠爲0, 不然就是其餘值.
找出了枚舉元素的實際規律: 按照元素出現的順序, 從1開始編號
枚舉原理: 枚舉在進行數據規範的時候(定義的時候),系統會自動創建一個數字與枚舉元素的對應關係(關係放到日誌中): 而後在進行數據插入的時候,系統自動將字符轉換成對應的數字存儲, 而後在進行數據提取的時候, 系統自動將數值轉換成對應的字符串顯示.
由於枚舉實際存儲的是數值,因此能夠直接插入數值.
集合跟枚舉很相似: 實際存儲的是數值,而不是字符串(集合是多選)
集合使用方式:
定義: Set(元素列表)
使用: 可使用元素列表中的元素(多個), 使用逗號分隔
建立集合表
插入數據: 可使用多個元素字符串組合, 也能夠直接插入數值
查看數據: 數值 + 數據查看
集合中沒一個元素都是對應一個對應二進制位
集合中元素的順序沒有關係: 最終系統都會去匹配順序
集合的強大在於可以規範數據和節省空間: PHP也能夠規範數據, 可是對於PHP來講效率優先, 並且數據的維護能夠經過數字進行, 增長PHP的維護成本: PHP根本沒有辦法判斷數據在數據庫的形式.
Mysql中規定: 任何一條記錄最長不能超過65535個字節.(varchar永遠達不到理論值)
Varchar的實際存儲長度能達到多少呢? 看字符集編碼.
Utf8 下varchar的實際頂配: 21844字符
GBK下的varchar的實際頂配: 32766字符
想用完整個65535個字節長度: 增長一個tinyint字段便可
Mysql記錄中: 若是有任何一個字段容許爲空,那麼系統會自動從整個記錄中保留一個字節來存儲NULL(若想釋放NULL所佔用的字節: 必須保證全部的字段都不容許爲空)
Mysql中text文本字符串,不佔用記錄長度: 額外存儲. 可是text文本字符串也是屬於記錄的一部分: 必定須要佔據記錄中的部分長度: 10個字節(保存數據的地址以及長度).
列屬性: 真正約束字段的是數據類型, 可是數據類型的約束很單一. 須要有一些額外的約束, 來更加保證數據的合法性.
列屬性有不少: NULL/NOT NULL, default, Primary key, unique key, auto_increment,comment
兩個值: NULL(默認的)和NOT NULL(不爲空)
雖然默認的, 數據庫基本都是字段爲空, 可是實際上在真實開發的時候, 儘量的要保證全部的數據都不該該爲空: 空數據沒有意義; 空數據沒有辦法參與運算.
建立一個實際案例表: 班級表(名字,教室)
列描述: comment, 描述, 沒有實際含義: 是專門用來描述字段,會根據表建立語句保存: 用來給程序猿(數據庫管理員)來進行了解的.
默認值: 某一種數據會常常性的出現某個具體的值, 能夠在一開始就指定好: 在須要真實數據的時候,用戶能夠選擇性的使用默認值.
默認值關鍵字: default
默認值的生效: 使用, 在數據進行插入的時候,不給改字段賦值
想要使用默認值,能夠不必定去指定列表,故意不使用字段列表: 可使用default關鍵字代替值
-- 建立整型表 create table my_int( int_1 tinyint, int_2 smallint, int_3 int, int_4 bigint )charset utf8; -- 插入數據 insert into my_int values(100,100,100,100); -- 有效數據 insert into my_int values('a','b','199','f'); -- 無效數據: 類型限定 insert into my_int values(255,10000,100000,1000000); -- 錯誤: 超出範圍 -- 給表增長一個無符號類型 alter table my_int add int_5 tinyint unsigned; -- 無符號類型 -- 插入數據 insert into my_int values(127,1000,10000,1000000,255); alter table my_int add int_6 tinyint(1) unsigned;-- 指定顯示寬度爲1; insert into my_int values(127,0,0,0,255,255); alter table my_int add int_7 tinyint(2) zerofill; -- 顯示寬度爲2,0填充 insert into my_int values(1,1,1,1,1,1,1); insert into my_int values(100,100,100,100,100,100,100); -- 浮點數表 create table my_float( f1 float, f2 float(10,2), -- 10位在精度範圍以外 f3 float(6,2) -- 6位在精度範圍以內 )charset utf8; -- 插入數據 insert into my_float values(1000.10,1000.10,1000.10); -- 符合條件 insert into my_float values(1234567890,12345678.90,1234.56); -- 符合條件 insert into my_float values(3e38,3.01e7,1234.56); -- 符合條件 insert into my_float values(9999999999,99999999.99,9999.99); -- 最大值 -- 超出長度插入數據 insert into my_float values(123456,1234.123456768,123.9876543); -- 小數部分OK insert into my_float values(123456,1234.12,12345.56); -- 整數部分超出 -- 建立定點數表 create table my_decimal( f1 float(10,2), d1 decimal(10,2) )charset utf8; -- 插入數據 insert into my_decimal values(12345678.90,12345678.90); -- 有效數據 insert into my_decimal values(1234.123456,1234.1234356); -- 小數部分超出:ok insert into my_decimal values(99999999.99,99999999.99); -- 沒有問題 insert into my_decimal values(99999999.99,99999999.999); -- 進位超出範圍 -- 建立時間日期表 create table my_date( d1 datetime, d2 date, d3 time, d4 timestamp, d5 year )charset utf8; -- 插入數據 insert into my_date values('2015-9-28 11:50:36','2015-9-28','11:50:54','2015-9-28 11:51:08',2015); -- 時間使用負數 insert into my_date values('2015-9-28 11:50:36','2015-9-28','-11:50:54','2015-9-28 11:51:08',2015); insert into my_date values('2015-9-28 11:50:36','2015-9-28','-211:50:54','2015-9-28 11:51:08',2015); insert into my_date values('2015-9-28 11:50:36','2015-9-28','-2 11:50:54','2015-9-28 11:51:08',2015); -- -2過去2天:48 -- year可使用2位或者4位 insert into my_date values('2015-9-28 11:50:36','2015-9-28','11:50:54','2015-9-28 11:51:08',69); insert into my_date values('2015-9-28 11:50:36','2015-9-28','11:50:54','2015-9-28 11:51:08',70); -- timestamp: 修改記錄 update my_date set d1 = '2015-9-28 11:55:45' where d5 = 2069; -- 建立枚舉表 create table my_enum( gender enum('男','女','保密') )charset utf8; -- 插入數據 insert into my_enum values('男'),('保密'); -- 有效數據 -- 錯誤數據 insert into my_enum values('male'); -- 錯誤: 沒有該元素 -- 將字段結果取出來進行+0運算 select gender + 0, gender from my_enum; -- 數值插入枚舉元素 insert into my_enum values(1),(2); -- 建立集合表 create table my_set( hobby set('籃球','足球','乒乓球','羽毛球','排球','檯球','網球','棒球') -- 足球 檯球 網球 -- 集合中: 每個元素都是對應一個二進制位,被選中爲1,沒有則爲0: 最後反過來 -- 0 1 0 0 0 1 1 0 -- 反過來 01100010 = 98 )charset utf8; -- 插入數據 insert into my_set values('足球,檯球,網球'); insert into my_set values(3); -- 查看集合數據 select hobby + 0, hobby from my_set; -- 98轉成二進制 = 64 + 32 + 2 = 01100010 -- 顛倒元素出現的順序 insert into my_set values('網球,檯球,足球'); -- 求出varchar在utf8和GBK下的實際最大值 create table my_utf8( name varchar(21844) -- 21844 * 3 + 2 = 65532 + 2 = 65534 )charset utf8; create table my_gbk( name varchar(32766) -- 32766 * 2 + 2 = 65532 + 2 = 65534 )charset gbk; create table my_utf81( age tinyint, -- 1 name varchar(21844) -- 21844 * 3 + 2 = 65532 + 2 = 65534 )charset utf8; create table my_gbk1( age tinyint, -- 1 name varchar(32766) -- 32766 * 2 + 2 = 65532 + 2 = 65534 )charset gbk; -- 釋放NULL create table my_utf82( age tinyint not null, -- 1 name varchar(21844) not null -- 21844 * 3 + 2 = 65532 + 2 = 65534 )charset utf8; create table my_gbk2( age tinyint not null, -- 1 name varchar(32766) not null -- 32766 * 2 + 2 = 65532 + 2 = 65534 )charset gbk; -- text佔用十個字節長度 create table my_text( name varchar(21841) not null, -- 21841 * 3 + 2 = 65523 + 2 = 65525 content text not null -- 10 )charset utf8; -- 建立班級表 create table my_class( name varchar(20) not null, room varchar(20) null -- 表明容許爲空: 不寫默認就是容許爲空 )charset utf8; -- 建立表 create table my_teacher( name varchar(20) not null comment '姓名', money decimal(10,2) not null comment '工資' )charset utf8; -- 默認值 create table my_default( name varchar(20) not null, age tinyint unsigned default 0, gender enum('男','女','保密') default '男' )charset utf8; -- 插入數據 insert into my_default (name) values('高強'); insert into my_default values('範立峯',18,default);