MySQL學習筆記(二)
-- 回顧
數據庫基礎知識:
關系型數據庫(磁盤),建立在關系模型上的數據庫,數據結構(二維表),浪費空間。
操作數據的指令集合:SQL(DDL,DML[DQL]和DCL)
完整性約束:表內和表之間(實體)
mysql 關系型數據庫:c/s結構軟件(連接認證,發送SQL指令,服務器處理指令返回結果,客戶端接收結果解析結果)
mysql服務端對象:DBMS->Datebase->Table->fields
sql 基本操作:庫操作,表操作(字段)和數據操作
字符集問題:中文數據問題
改變服務器接收數據的字符集:chatacter_set_client
改變服務器返回數據的字符集:
快捷方式:set names 字符集(三件事)
web亂碼問題:瀏覽器解析,php處理(本地文件),數據庫處理
校隊集問題:比較規則:_bin , _cs和_ci
-- 數據類型(列類型)
所謂的數據類型:對數據進行統一的分類,從系統的角度出發為了能夠使用統一的方式進行管理更好的利用有限的空間。
SQL 中將數據類型分成三大類:數值類型,字符串類型和時間類型。
一.數值型
數值型數據:都是數值,系統將數值型分為整數和小數型
1.整數型
存放整型數據:再SQL中因為更多考慮如何節省磁盤空間,所以系統將整型分為5類
Tinyint :迷你整型,使用一個字節存儲,表示的狀態最多位
smallint:小整形,使用2個字節存儲,表示的狀態最多位65536種
mediumint:中整型,使用3個字節存儲,表示
int:標準整型,使用4個字節存儲(常用)
bigint:大整型,使用8個字節存儲
例:創建一張整型表
mysql> create table my_int(int_1 tinyint, int_2smallint, init_3int) charset utf8;
例:輸入數據:只能插入整型,範圍內的整型
mysql> insert into my_int values (100,100,100,100); #有效數據
mysql> insert into my_int values (‘a‘,‘b‘,‘199‘,‘f‘); #
mysql> insert into my_int values (255,1000,10000,100000); #超出範圍
SQL中的數值類型全部都是默認有符號:分正負,但有時候需要使用無符號數據:需要給數據限定:int unsigned; #無符號,從0開始
例:給表增加一個無符號類型
mysql> alter table my_int add int_5 tinyint unsigned;
例:插入數據
mysql> insert into my_int values(127,1000,10000,100000,255);
查看表結構的時候,發現每個字段的數據類型之後都自帶一個括號裏面有數值,這個是顯示寬度,但它沒有任何含義只是告訴用戶可以顯示的形式而已;實際上用戶是可以控制的,這種控制不會改變數據本身大小;
例:mysql> alter table my_int add int_6 tinyint(1) unsigned; #指定顯示寬度為1
說明:顯示寬度的意義是在當數據不夠顯示寬度的時候,會自動讓數據變成對應的顯示寬度;通常需要搭配一個前導0來增加寬度,但是值大小不變。zerofill(零填充):零填充會導致數據自動變成無符號
例:mysql> alter table my_int add int_7 tinyint (2) zerofill; #表示顯示寬度為2,0填充
例:mysql> insert into my_int values(1,1,1,1,1,1,1); #零填充+顯示寬度的效果
mysql> insert into my_int values(100,100,100,100,100,100,100);
零填充的意義(顯示寬度):保證數據格式
2.小數型
小數型:帶有小數點或者範圍超出整型,SQL中將小數型分成兩種:浮點型和定點型
浮點型:小數點浮動,精度有限,而且會丟失精度
定點型:小樹點固定,精度是固定的,不會丟失精度
2.1浮點型
浮點型數據是一種精度型數據:超出指定範圍之後,會丟失精度(自動四舍五入)
Float : 單精度,占用4個字節存儲數據,精度範圍大概為7位左右
Double: 雙精度,占用8個字節存儲數據,精度方位大概為15位左右
例:創建浮點數表
浮點數的使用方式:直接float 表示沒有小數部分;float(M,D):M代表總長度,D代表小數部分長度,整數部分長度為 M-D
mysql> create table my_float (f1 float,f2 float(10,2),f3 float(6,2)) charset utf8;
例:插入符合條件數據,可以是直接小數也可以是科學計數法
mysql> inster into my_float values(1000.10,1000.10,1000.10); #符合條件
mysql> inster into my_float values(1234567890,12345678.90,1234.56); #符合條件
mysql> inster into my_float values(9999999999,99999999.99,9999.99); #最大值
mysql> inster into my_float values(3e38,3.01e7,1234.56); #符合條件
浮點型數據的插入:整數部分是不能超出長度的,但是小數部分可以超出長度(系統會自動四舍五入)
例:超出長度插入數據
mysql> inster into my_float values(123456,1234.12345678,123.9876543);#小數部分是可以的
mysql> inster into my_float values(123456,1234.12,123456.56); #整數部分超出
結果:浮點數一定會進行四舍五入(超出精度範圍):浮點數如果是因為系統進位導致整數超出指定的長度那麽系統也允許成立
2.2 定點型
定點型:絕對保證整數部分不會被四舍五入(不會丟失精度),小數部分有可能(理論小數部分也不會丟失)
創建定點數表
mysql> create table my_decimal(f1 float(10,2),d1 decimal(10,2)) charset utf8;
插入數據:定點數的整數部分一定不能超出長度(進位不可以),小數部分的長度可以隨意超出(系統自動四舍五入)
mysql> inster into my_decimal values(12345678.90,12345678.90); #有效數據
mysql> inster into my_decimal values(1234.123456,1234.123456); #小數部分超出
發現有一條警告,查看警告的命令位: mysql> show warnings;
浮點數如果進位導致長度溢出是可以的,但定點數不行
mysql> insert into my_decimal values(99999999.99,99999999.99);
mysql> insert into my_decimal values(99999999.99,99999999.999); #進位超出範圍
查看數據
二 . 時間日期類型
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
創建時間日期表
mysql> create table my_date(d1 datetime,d2 date,d3 time,d4 timestamp,d5 year) charset utf8;
插入數據:時間time可以是負數,而且可以是很大的負數,year 可以使用2位數插入,也可以使用4位
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘11:50:54‘,‘2015-9-28 11:51:08‘,2015);
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘-11:50:54‘,‘2015-9-28 11:51:08‘,2015);
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘-211:50:54‘,‘2015-9-28 11:51:08‘,2015);
year 可以使用兩位或者四位
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘-11:50:54‘,‘2015-9-28 11:51:08‘,69);
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘-11:50:54‘,‘2015-9-28 11:51:08‘,70);
Timestramp 字段:只要當前所在的記錄被更新,該字段一定會自動更新成當前時間
修改記錄
mysql> update my_date set d1 = ‘2015-9-28 11:55:45‘ where d5 = 2069;
三.字符串類型
在SQL中,將字符串類型分成了6類:char,varchar,text,blob,enum和set
1.1 定長字符串
定長字符串:char,磁盤(二維表)在定義結構的時候,就已經確定了最終的存儲長度,以後不能改變
char(L):L 代表length,可以存儲的長度,單位為字符,最大長度為255.
char(4):在 utf8 環境下,需要4 * 3 = 12 字節
1.2 變長字符串
變長字符串:varchar,在分配空間的時候,按照最大的空間分配,但是實際上最終用了多少,是根據具體的數據來確定。
1.2 變長字符串
varchar(L):L 表示字符長度理論長度是65536 個字符,但是會多出1到2個字節來確定存儲的實際長度:但是實際上如果長度超過255,就既不用定長也不用變長,使用文本字符串text
varchar(10):的確存了10個漢字,utf8環境,10*3+1=31
存儲了3個漢字 3*3+1=10(bytes)
定長與邊長的存儲實際空間(utf8)
如何選擇定長或者是變長字符串呢?
定長的磁盤空間比較浪費,但效率高;如果數據基本上確定長度都一樣,那麽就使用定長,如:身份證,電話號,手機號等;
變長的磁盤空間比較節省,但是效率低;如果數據不能確定長度(不同數據有變化),如姓名,地址等
1.2 文本字符串
如果數據量非常大,通常超過255個字節就會使用文本字符串
文本字符串根據存儲的數據的格式進行分類:text和blob
Text :存儲文字(二進制數據實際上都是存儲路徑)
Blob :存儲二進制數據(通常不用)
四:枚舉字符串
枚舉:enum,事先將所有可能出現的結果都設計好,實際上存儲的數據必須是規定號中的一個
枚舉的使用方式
定義:enum(可能出現的元素列表);
使用:存儲數據,只能存儲上面定義好的數據
創建枚舉表:
mysql> create table my_enum(gender enum(‘男‘,‘女‘,‘保密‘)) charset utf8;
插入數據:作用之一:規範數據,數據只能是其中的一個
mysql> insert into my_enum values(‘男‘),(‘保密‘); #有效數據
mysql> insert into my_enum values(‘male‘); #錯誤數據,沒有該元素
作用二:節省存儲空間(枚舉別名:單選框):枚舉實際存儲的是數據而不是字符串
在mysql中,系統也是自動轉換數據格式的:而且基本和php一樣(尤其是字符串數字)
證明字段存儲的數據是數值:將數據取出來+0就可以判斷出原來的數據存的到底是字符串還是數值:如果是字符串最終結果永遠為0
mysql> select gender + 0, gender from my_enum; #將字段取出來進行+0運算
找出了枚舉元素的實際規律:按照元素出現的順序;從1開始開始編號
枚舉原理:枚舉在進行數據規範的時候系統會自動建立數字與枚舉元素的對應關系(關系放到日誌中):然後在進行數據插入的時候,系統自動將字符轉換成對應的數字存儲,然後在進行數據抓取的時候,系統自動將數值轉換成對應的字符串顯示。
因為枚舉實際存儲的是數值所以可以直接插入數值
mysql> insert into my_enum values (1),(2);
五:集合字符串
集合跟枚舉很類似:實際存儲的是數值,而不是字符串(集合是多選)
集合使用方式
定義:set(元素列表)
使用:可以使用元素列表中的元素(多個),使用,分隔
mysql> create table my_set(hobby set(‘籃球‘,‘足球‘,‘乒乓球‘,‘羽毛球‘,‘排球‘,‘臺球‘,‘網球‘,‘棒球‘)) charset utf8; #集合中:每個元素都是對應一個二進制位,被選中為1,沒有則為0,組後反過來。
創建集合表:
插入數據:可以使用多個元素字符串組合,有可以直接插入數值
mysql> insert into my_set values(‘足球‘,‘臺球‘,‘網球‘);
mysql> insert into my_set values(3);
查看集合數據
mysql> select hobby + 0, hobby from my_set;
集合中每個元素都是對應二進制位;
mysql> inster into my_set values(255);
集合中元素的順序沒有關系,最終系統都會去匹配順序。
顛倒元素出現的順序
mysql> inster into my_set values(‘網球‘,‘臺球‘,‘足球‘);
集合的強大在於能夠規範數據和空間,在實際應用中效率優先,所以很少使用。
六:Mysql記錄長度
Mysql 中規定:任何一條記錄最長不能超過65535個字節,(varchar 永遠達不到理論值) varchar 的實際存儲長度能達到多少需看字符集
UTF8 下 varchar 的實際頂配:21844 字符
GBK 下 varchar 的實際頂配;32766 字符
如果想用完65535個字節長度需增加個tinyint 字段
mysql記錄著如果有任何一個字段允許為空,那麽系統會自動從整個記錄中保留一個字節來存儲null(若想釋放null所占用的字節,必須保證所以的字段都允許空)
Mysql 中 text 文本字符串,不占用記錄長度;額外存儲,但是text文本字符串也是屬於記錄的一部分,一定需要占用記錄中的部分長度10個字節。(保存數據的地址和長度)
text 占用十個字節長度
mysql> create table my_utf82(age tinyint not null,name varchar(21843) not null,content text) charset utf8;
七:列屬性
列屬性:真正約束字段的是數據類型,但是數據類型的約束很單一,因此需要一些額外的約束來增加保證數據的合法性
列屬性有很多:NULL/NOT NULL,defaul,prinary key,uniquee key,auto_increment,comment
空屬性:NULL(默認的)和NOT NULL(不為空)
雖然默認的,數據庫基本都是字段為空,但是實際上我們盡可能保證所有數據都不應該為空:空數據沒有意義;空數據沒有辦法參與運算。
創建實際案例表:班級表(名字,教室)
mysql> creare table my_class(name varchar(20) not null,room varchar(20) null) charset utf8; #代表允許為空,null不寫默認就是為空
八:列描述
列描述:comment,描述沒有實際意義:是專門用來描述字段,會根據表創建語句保存:用來給數據庫管理員來進行了解的。
創建表
mysql> create table my_teacher(name varchar(20) not null comment ‘姓名‘,money decimal(10,2) not null comment ‘工資‘) charset utf8;
八:默認值
默認值:某一種數據會經常性的出現某個具體的值,可以再一開始就指定好,再需要真實的數據時,用戶可以選擇性的使用默認值。
默認值關鍵字:default
mysql> create table my_default(name varchar(20) not null ,age tinyint unsigned default 0,gender enum(‘男‘,‘女‘,‘保密‘) default ‘男‘) charset utf8;
默認值的生效:使用,在數據進行插入時,不給改字段賦值
插入數據
mysql> insert into my_default (name) values(‘高強‘);
想要使用默認值,可以不一定區指定列表;可以使用default關鍵字代替值
mysql> insert into my_default values(‘範立峰‘,‘18,default);
MySQL學習筆記(二)