MySql----資料型別(數值型別、char/varchar、enum、set、date)
一:資料型別分類:
二:數值型別
1.bit
bit[(M)] : 位欄位型別。M表示每個值的位數,範圍從1到64。如果M被忽略,預設為1。
例:
//表tt3的sno的值有8個位
mysql> create table tt3(age int,sno bit(8));
//插入資料
mysql> insert into tt3 values(10,24);
//查詢資料 sno的值24並不是24
mysql> select * from tt3;
是因為bit欄位在顯示時,是按照ASCII碼對於的值顯示。驗證如下:
//65是A的ASCII碼
insert into tt3 values(11,65);
如果需要欄位值用10進位制顯示:
//這樣sno欄位資料以十進位制顯示:
mysql select sno+0 from tt3;
欄位值以16進位制顯示:
mysql select hex(sno) from tt3;
如果需要欄位值以8進位制顯示:
mysql> select oct(sno) from tt3;
但是mysql使用上述函式時無法使用索引。
欄位值以二進位制顯示:
mysql> select bin(sno) from tt3;
當一個欄位只存放0或1,可以採用bit型別:
//bit預設1位
mysql> create table tt4(judge bit);
mysql> insert into tt4 valus(0);
mysql> insert into tt4 values(1);
插入資料為2時,會出現錯誤:
2.tinyint
tinyint預設為有符號為1個位元組,那麼取值範圍是-128-127,如果資料大於127就會越界:
在MySQL中,整型可以指定為有符號和無符號,如果沒有指定,預設為有符號,但是可以通過UNSIGNED來指定某個欄位是無符號的。
新增一個新欄位age2,為tinyint unsigned:
mysql> alter table tt2 add age2 tinyint unsigned ;
mysql> insert into tt2(ag2) values (128);
我們知道無符號和有符號相差一個數量級,如果有符號int超範圍,int unsigned同樣可能存放不下,所以在設計時資料過大,可以設計為bigint。
3.小數型別(float/decimal)
float[(m, d)] [unsigned] : m指定顯示長度,d指定小數位數,佔用空間4個位元組
有符號float:
float(4,2)表示的範圍是-99.99 ~ 99.99,MySQL在儲存值時會進行四捨五入。
//area值是4位數,小數位2位
mysql> create table tt5(area float(4,2));
//會進行四捨五入
mysql> insert into tt5 values(99.991);
mysql> insert into tt5 values(99.985);
無符號float
float(4,2) unsigned 這時,因為把它指定為無符號的數,範圍是 0 ~ 99.99。
mysql> create table tt6(area float(4,2) unsigned);
mysql> insert into tt6 values(-1);
decimal
decimal(m, d) [unsigned] : 定點數m指定長度,d表示小數點的位數
- decimal(5,2) 表示的範圍是 -999.99 ~ 999.99
- decimal(5,2) unsigned 表示的範圍 0 ~ 999.99
float和decimal的區別在於精度不同
mysql> create table tt7(area float(10,8),salary decimal(10,8));
mysql> insert into tt7 values(53.12345678,53.12345678);
- 可以發現decimal的精度更高,float的精度大約是7位,如果希望某個資料表示高精度,可以選擇decimal。
- decimal整數最大位數m為65,支援小數最大位數d是30。如果d被省略,預設為0,如果m被省略,預設是10。
- decima 按照字串形式儲存,以解決精度問題,但是在效能上,處理速度較慢。
三.字串型別
char
語法:
char(L): 固定長度字串,L是可以儲存的長度,單位為字元,最大長度值可以為255
//char(2)代表可以儲存的長度為2
mysql> create table tt8 (name char(2));
mysql> insert into tt8('ab');
mysql> insert into tt8 values('中國');
char(2)表示可以存放2個字元,可以是字母或者漢字,但是不能超過2個,最多隻能是255;
varchar
mysql> create table tt9 (name char(256));
mysql> insert into tt10 values("hello");
mysql> insert into tt10 values("中國,你好!");
關於varchar(len),len到底是多大,這個len值,和表的編碼密切相關:
varchar的最大長度是65535。
但是MySql限定行的最大值是65535位元組(byte),注意,這是行的最大長度,包括一行中所有列的長度總和,但是但是有1 - 2 個位元組用於記錄資料大小,所以說有效位元組數是65533。
對於char,不論採用哪一種字符集(utf8mb4一個字元4個位元組),255的長度都不會超過mysql 65535位元組的限制。然而對於varchar,字符集的大小就會對實際長度產生影響:
當我們的表的編碼是utf8時,varchar(n)的引數n最大值是65533/3=21844(因為utf中,一個字元佔用3個位元組),如果編碼是gbk,varchar(n)的引數n最大是65533/2=32766(因為gbk中,一個字元佔用2位元組)。
如何選擇定長或變長?
首先了解下什麼是變成定長:
變長定長區別體現在儲存方式上。char 作為定長型別,假設定義 char(10),我們存入’中國’,只佔用了2個字元數,那麼後面8個字元,儲存引擎會填充空格。反之varchar(10),不會自動填充空格。即varchar是變長。
- 如果資料確定長度都一樣,使用定長(char),如:身份證號碼,電話號碼等;
- 如果資料長度有變化,使用變長(varchar),如名字,地址,但是要保證最長的能存進去;
- 定長的磁碟空間比較浪費,但是效率高;
- 變長的磁碟空間比較節省,但是效率低;
日期和時間型別
日期
- datetime時間日期格式 ‘yyyy-mm-dd HH:ii:ss’ 表示範圍從1000到9999,佔用八位元組;
- data:日期 ‘yyyy-mm-dd’,佔用三位元組;
- timestamp:時間戳,從1970年開始的 yyyy-mm-dd HH:ii:ss格式和datetime完全一致,佔用四位元組.
mysql> create table tt11(t1 date,t2 datetime,t3 timestamp);
mysql> insert into tt11(t1,t2) values ('2000-1-1','2008-12-7 8:1:1');
mysql> insert into tt11(t1,t2) values ('2009-1-1','2018-12-7 10:19:0');
如果沒有指定時間戳,時間戳預設為當前時間。
enum和set
enum
語法:
//enum是單選
enum('選項1','選項2','選項3',...);
提供了若干選項的值,一次只能選擇一個,和c裡的列舉一樣,每個選項實際儲存的是數字,1,2,3,4…最大65535。
set
語法:
//set是多選
set('選項值1','選項值2','選項值3', ...);
set裡提供了若干選項的值,一次可以有多個選項,每個選項值實際儲存的是數字,1,2,4,8,16…最大是64。
儘管enum和set儲存的數字,但是在新增資料時,最好用具體含義,可讀性強。
例:調查男生女生喜歡的顏色(粉色,果綠,紫色);
//建立表
mysql> create table tt12(
-> name varchar(20),
-> colour set('粉紅','果綠','紫色'),
-> sex enum('male','female'));
mysql> insert into tt12 values("pick","紫色","male");
mysql> insert into tt12 values("sophia",'紫色,果綠',"male");
查詢所有喜歡紫色的資訊:
mysql> select * from tt12 where colour='紫色';
只查詢到唯一喜歡紫色的資訊,並沒有把喜歡紫色同學資訊全部查詢到,所以用到了find_ in_ set。
集合查詢使用find_ in_ set函式:
find_in_set(sub,str_list) :如果 sub 在 str_list 中,則返回下標;如果不在,返回0; str_list 用逗號分隔的字串。
mysql> select * from tt12 where find_in_set('紫色',colour);