要慎用mysql的enum字段的緣由。本站提示廣大學習愛好者:(要慎用mysql的enum字段的緣由)文章只能為提供參考,不一定能成為您想要的結果。以下是要慎用mysql的enum字段的緣由正文
PHP初級編程的兄弟是如許來看這個成績的,我作下筆錄以下,希冀能客不雅的懂得這個enum字段的長處及缺陷:
膘哥不雅點:
enum有長處。但小我認為。。。缺陷更多,客不雅的講:長處重要是在建數據 庫的時刻便可以把一些值給標准好。缺陷是。。enum不合適PHP。重要是PHP是弱類型,如:你insert into ..... set a= 1,你沒法曉得你是想 a= '1' 照樣 a= 1(a='1'是拔出值1,a=1是拔出enum的第一個值,特別php弱類型的,假如int的,很少有人在sql裡加雙引號。),這是PHP和mysql 在應用enum 最年夜的成績。所以。。安心點啦。爽性點直接tinyint。
單曲不雅點:
我認為沒甚麼長處,對數字型的enum,的確就是夢魇,boolean tinyint(1) 0,1 status tinyint(1) 1,2,3,4,5,6..tinyint歡淫你~~。如:audit_result enum(1,2,3),set audit_result = 1;...輕易湧現膘哥所說的混雜。
簡略不雅點:
罕用,普通都是用tinyint替換。
天楓不雅點:
我認為除狀況直不雅 沒甚麼長處,我普通直接int,tinyint([1or2or3]) 究竟有啥差別?(前面會簡略商量下,這外面的1or2or3差別。)
中庸不雅點:
a=1是拔出enum的第一個值,特別php弱類型的,假如int的,很少有人在sql裡加雙引號,根本上是不加引號的。
豎琴螺不雅點:
六種情形就:tinyint(1) -1,-2,1,2,3,4
下面各類不雅點重點集中在PHP這類弱類型說話對引號不看重,法式員不寫輕易惹起拔出的語句不是本身想要的成果的成績,輕易湧現int時沒有效引號招致拔出了新值而不是定的誰人值:
表構造以下:
CREATE TABLE `enum2tinyint` ( `switchs` enum('none','success','fail','delete','skip','1') DEFAULT NULL, `switch` tinyint(1) NOT NULL, KEY `switchs` (`switchs`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
正常帶引號拔出enum:
INSERT INTO `test`.`enum2tinyint` (`switchs`, `switch`) VALUES ('1', '1'); 1 1
PHP的弱類型成績,特殊是對int類型的情形,理論以下:
假如沒有帶引號拔出enum字段後以下(是第一個值none):
INSERT INTO `test`.`enum2tinyint` (`switchs`, `switch`) VALUES (1, '1'); none 1
假如沒有帶引號拔出enum字段後以下(是第2個值success):
INSERT INTO `test`.`enum2tinyint` (`switchs`, `switch`) VALUES (2, '1'); success 1
結論:要拔出enum的值,字段必需加引號,不加引號固然是數字,數字就是key,不是value。
勸戒:
1)enum是整型如許的毛病很輕易產生,特別是php弱類型的,普通新來一小我,沒留意enum類型,就會出錯。
2)數據庫解釋清晰的話,或許可選擇的滿是字符串的話,還沒甚麼,然則外面稀有字,不免有老手出錯,養成加引號的習氣很主要。
終究結論:
汗青緣由,要把enum改成tinyint法式修改太年夜了,用了的沒需要改·~,今後新建的時刻,盡可能應用tinyint就好。
這類字段的反復內容過量的,索引建不建,關系不年夜,這類在mysql叫索引的勢太低,其查詢後果不太好:(英文是這麼翻譯的:https://justwinit.cn/post/1405/)。
————————————————————————————————————————————————————————————————————
tinyint(1)和tinyint(4)一樣的,都是-127到128或許0到256。unsigned屬性滿是正,和c說話unsigned int有點相似:
tinyint(1) -128 ~ 127
tinyint(1) unsigned 0 ~ 255
為什麼表現的最年夜負數比最小正數的相對值少1呢?
第一名是符號位,1表現正數
所以正數可以到128,負數只能到127
-128正127
如:0111 1111 負數 ,正數 1111 1111
發問:
Mysql裡int(1)和int(11)差異很年夜的,mysql的int,有個屬性 ,UNSIGNED ZEROFILL 前面的ZEROFILL,就是有界說的位數不敷則用零補齊對齊一下(這兒能夠觸及到索引的機能罷):int, 長度(M)=5, 屬性=UNSIGNED ZEROFILL(無符號,用0來填充位數),00001,00002。
但這個tinyint呢,tinyint(1)和tinyint(4)一樣的?
看這文章後:http://www.jb51.net/article/53424.htm
我估量:mysql這塊對一個字節不像int這類四個字節要停止對其前部門停止部門字節索引,假如說tinyint(1)和tinyint(4)是一樣的表現規模情形下,但mysql對tinyint數字長度位數作了可設置的限制,從實際上說其存在硬盤裡的字節是紛歧樣才是符合邏輯的,這塊估量照樣為了對字節停止對齊便利索引等,以晉升效力為主罷,l如:ike keyword% 索引有用,假如同一對齊,索引後果會不會更好呢?我也只是猜想。
————————————————————————————————————————————————————————————————————
在網上找了下這個enum的mysql的年夜體完成以下:
一)enum的存儲道理我細心檢查了下手冊。是如許的:
在樹立這個字段時,我們會給他劃定一個規模好比enum('a','b','c'),這時候mysql外部會樹立一張hash構造的map表,相似:0000 -> a,0001 -> b,0002 -> c。
當我拔出一條數據,此字段的值位a或b或c時,他存儲在外面的不是這個字符,而是對應他的索引,也就是誰人0000或0001或0002。
異樣,enum在mysql手冊上的解釋:
ENUM('value1','value2',...)
1或2個字節,取決於列舉值的個數(最多65,535個值)
除非enum的個數跨越了必定數目,不然他所占的存儲空間也老是1字節。
二)tinyint:
類型 字節 最小值 最年夜值
(帶符號的/無符號的) (帶符號的/無符號的)
TINYINT 1 -128 127
他的最小存儲所占空間也是1字節。
最初,Enum,既然要用它,就不用要應用甚麼0,1,2來取代現實的字符串了。乃至中文字符串。他其實不會對數據庫機能停止過剩開支。由於關於它來講,你應用'0','1','2'和'張三','李四','王五'數據表所占的存儲空間一樣。然則斟酌到我們現實運用時數據須要從db辦事器回傳到web app,所以在收集傳輸時,固然照樣盡量的傳輸小數據比擬好。所以假如很在乎這些,照樣不消它好了。