mysql char null_关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别...
一、背景
根據(jù)業(yè)務(wù)需求,發(fā)現(xiàn)以前的同事在設(shè)計(jì)表的時(shí)候,很多字段都沒有設(shè)置默認(rèn)值。在mysql5.7版本之后,沒有設(shè)定默認(rèn)值的字段,在嚴(yán)格模式下是很容易報(bào)錯(cuò)的,所以我這邊需要先給每個(gè)字段加上一個(gè)默認(rèn)值。
對(duì)于常見的int類型,默認(rèn)值為0就好,但是對(duì)于varchar類型呢,默認(rèn)值是設(shè)置為”還是Null呢?
二、‘’和null的區(qū)別
1、占用空間問題
(1)c語言:
'\0',這個(gè)表示空,需要消耗存儲(chǔ)空間的。
NULL,則表示連這個(gè)\0都沒有。
(2)、mysql:
1:空值('')是不占用空間的
2: MySQL中的NULL其實(shí)是占用空間的。官方文檔說明:
“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”
可見為了表示某個(gè)字段是否為空是需要額外開辟空間存儲(chǔ)Null值,而在C語言中空值’不占用存儲(chǔ)空間。
不僅如此,不使用NULL可以提高索引效率,因?yàn)闃湫嗡饕Y(jié)構(gòu)中將NULL也視作一般數(shù)據(jù)節(jié)點(diǎn)。
2、上面說到了null會(huì)影響索引效率
其實(shí)我們?cè)诔鯇W(xué)mysql的時(shí)候,都會(huì)看到一段話,那就是mysql建議字段最好為不要為null,盡量為not null。
原話:
盡量避免NULL:應(yīng)該指定列為NOT NULL,除非你想存儲(chǔ)NULL。在MySQL中,含有空值的列很難進(jìn)行查詢優(yōu)化。因?yàn)樗鼈兪沟盟饕⑺饕慕y(tǒng)計(jì)信息以及比較運(yùn)算更加復(fù)雜。你應(yīng)該用0、一個(gè)特殊的值或者一個(gè)空串代替空值。
null會(huì)影響索引的統(tǒng)計(jì),一般會(huì)默認(rèn)null為同一個(gè)值,這樣這個(gè)索引的篩選價(jià)值就降低了,影響優(yōu)化器的判斷。當(dāng)然也可以調(diào)整參數(shù),使得null被認(rèn)為是不同的值。
結(jié)論:也就是說,在設(shè)置默認(rèn)值的時(shí)候,盡量不要用Null來當(dāng)默認(rèn)值,用空字符串(”)會(huì)更好一些。帶有null的默認(rèn)值還是可以走索引的,只是會(huì)影響效率。當(dāng)然,如果確認(rèn)該字段不會(huì)用到索引的話,也是可以設(shè)置為null的
三、在統(tǒng)計(jì)時(shí),”和null的區(qū)別
這部分建議參考博客:
MySQL 中NULL和空值的區(qū)別
結(jié)論:
1:在進(jìn)行count()統(tǒng)計(jì)某列的記錄數(shù)的時(shí)候,如果采用的NULL值,會(huì)別系統(tǒng)自動(dòng)忽略掉,但是空值是會(huì)進(jìn)行統(tǒng)計(jì)到其中的。
2: 判斷NULL 用IS NULL 或者 is not null,SQL 語句函數(shù)中可以使用ifnull()函數(shù)來進(jìn)行處理,判斷空字符用 =''或者 <>''來進(jìn)行處理
3: 對(duì)于MySQL特殊的注意事項(xiàng),對(duì)于timestamp數(shù)據(jù)類型,如果往這個(gè)數(shù)據(jù)類型插入的列插入NULL值,則出現(xiàn)的值是當(dāng)前系統(tǒng)時(shí)間。插入空值,則會(huì)出現(xiàn) '0000-00-00 00:00:00'
4:對(duì)于空值的判斷到底是使用is null 還是 =''要根據(jù)實(shí)際業(yè)務(wù)來進(jìn)行區(qū)分。
四、關(guān)于char和varchar的選用
1、定義
眾所周知的,char是定長,而varchar是變長。
char(M)類型的數(shù)據(jù)列里,每個(gè)值都占用M個(gè)字節(jié),如果某個(gè)長度小于M,MySQL就會(huì)在它的右邊用空格字符補(bǔ)足.(在檢索操作中那些填補(bǔ)出來的空 格字符將被去掉)在varchar(M)類型的數(shù)據(jù)列里,每個(gè)值只占用剛好夠用的字節(jié)再加上一個(gè)用來記錄其長度的字節(jié)(即總長度為L+1字節(jié))。
2、哪個(gè)更合適
對(duì)于MyISAM表,盡量使用Char,對(duì)于那些經(jīng)常需要修改而容易形成碎片的myisam和isam數(shù)據(jù)表就更是如此,它的缺點(diǎn)就是占用磁盤空間;
對(duì)于InnoDB表,因?yàn)樗臄?shù)據(jù)行內(nèi)部存儲(chǔ)格式對(duì)固定長度的數(shù)據(jù)行和可變長度的數(shù)據(jù)行不加區(qū)分(所有數(shù)據(jù)行共用一個(gè)表頭部分,這個(gè)標(biāo)頭部分存放著指向 各有關(guān)數(shù)據(jù)列的指針),所以使用char類型不見得會(huì)比使用varchar類型好。事實(shí)上,因?yàn)閏har類型通常要比varchar類型占用更多的空間, 所以從減少空間占用量和減少磁盤i/o的角度,使用varchar類型反而更有利。
3、結(jié)論
1、在確定字段為短小且定長的時(shí)候,用char會(huì)好一些
2、在某字段需要頻繁改寫的時(shí)候,用char會(huì)好一些(因?yàn)関archar每次存儲(chǔ)都要有額外的計(jì)算,得到長度等工作,如果一個(gè)非常頻繁改變的,那就要有很多的精力用于計(jì)算,而這些對(duì)于char來說是不需要的。)
3、設(shè)計(jì)varchar()值的時(shí)候,不要一股腦的都用varchar(255):mysql會(huì)把表信息放到內(nèi)存中(查詢第一次后,就緩存住 了,linux下很明顯,但windows下似乎沒有,不知道為啥),這時(shí)內(nèi)存的申請(qǐng)是按照固定長度來的,如果varchar很大就會(huì)有問題。
4、關(guān)于varchar(255)和varchar(256) :根據(jù)mysql官方文檔,varchar(255)需要一個(gè)字節(jié)記錄字段的長度 256以上需要兩個(gè)字節(jié)記錄長度。設(shè)置長度超過256會(huì)有點(diǎn)浪費(fèi)。
5、因?yàn)樵跇I(yè)務(wù)中使用innoDB多一些,所以盡量還是用varchar()好一些
end
=====================================================================
18年5月26日更新:
在設(shè)置字段的時(shí)候,可以給字段設(shè)置為 not null ,因?yàn)?not null 這個(gè)概念和默認(rèn)值是不沖突的。我們?cè)谠O(shè)置默認(rèn)值為”的時(shí)候,雖然避免了null的情況,但是可能存在直接給字段賦值為null,這樣數(shù)據(jù)庫中還是會(huì)出現(xiàn)null的情況,所以強(qiáng)烈建議都給字段加上 not null。
就這樣的:
alter table 數(shù)據(jù)表 modify `字段名` VARCHAR (255) NOT NULL DEFAULT '';
=======================================================================
18年8月8日更新
既然上面都說了varchar字段的默認(rèn)值最好不要為null,那么我們平時(shí)建表的時(shí)候改怎么寫呢?特別是在phpmyadmin中:
1、如果字段是int類型,默認(rèn)為0
2、如果是varchar類型,默認(rèn)值留空就好。就是定義,然后留空,直接空格就可以。這個(gè)時(shí)候我們查看數(shù)據(jù)表的結(jié)構(gòu),就會(huì)發(fā)現(xiàn)該字段是有默認(rèn)值的。
總結(jié)
以上是生活随笔為你收集整理的mysql char null_关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用mysql随机查询表a10条数据_ES
- 下一篇: 北京数字人民币红包怎么用 指定商户即可直