日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

MySQL中建表時可空(NULL)和非空(NOT NULL)的用法詳解

瀏覽:59日期:2023-10-13 18:11:26

對于MySQL的一些個規范,某些公司建表規范中有一項要求是所有字段非空,意味著沒有值的時候存儲一個默認值。其實所有字段非空這么說應該是絕對了,應該說是盡可能非空,某些情況下不可能給出一個默認值。那么這條要求,是基于哪些考慮因素,存儲空間?相關增刪查改操作的性能?亦或是其他考慮?該理論到底有沒有道理或者可行性,本文就個人的理解,做一個粗淺的分析。

1,基于存儲的考慮

這里對存儲的分析要清楚MySQL數據行的存儲格式,這里直接從這篇文章白嫖一部分結論,文章里分析的非常清楚(其實也是參考《MySQL技術內容Innodb存儲引擎》)。對于默認的Dynamic或者Compact格式的數據行結構,其行結構格式如下:|變長字段長度列表(1~2字節)|NULL標志位(1字節)|記錄頭信息(5字節)|RowID(6字節)|事務ID(6字節)|回滾指針(7字節)|row content

1,對于變長字段,當相關的字段值為NULL時,相關字段不會占用存儲空間。NULL值沒有存儲,不占空間,但是需要一個標志位(一行一個)。2,對于變長字段,相關字段要求NOT NULL,存儲成’’的時候,也不占用空間,如果一個表中所有的字典都NOT NULL,行頭不需要NULL的標志位3,所有字段都是定長,不管是否要求為NOT NULL,都不需要標志位,同時不需要存儲變長列長度

鑒于null值和非空(not null default ’’)兩種情況,如果一個字段存儲的內容是空,也就是什么都沒有,前者存儲為null,后者存儲為空字符串’’,兩者字段內容本身存儲空間大小是一樣的。但是如果一個表中存儲在可空字段的情況下,其對應的數據行的頭部,都需要一個1字節的NULL標志位,這個就決定了存儲同樣的數據,如果允許為null,相比not null的情況下,每行多了一個字節的存儲空間的。這個因素或者就是某些公司或者個人堅持“所有表禁止null字段”這個信仰的原因之一(個人持否定態度,可以嘗試將數據庫中所有的字段都至為not null 然后default一個值后會不會雞飛狗跳)。這里不再去做“微觀”的分析,直接從“宏觀”的角度來看一下差異。

測試demo

直接創建結構一致,但是一個表字段not null,一個表字段為null,然后使用存儲此過程,兩張表同時按照null值與非null值1:10的比例寫入數據,也就是說每10行數據中1行數據字段為null的方式寫入600W行數據。

CREATE TABLE a( id INT AUTO_INCREMENT, c2 VARCHAR(50) NOT NULL DEFAULT ’’, c3 VARCHAR(50) NOT NULL DEFAULT ’’, PRIMARY KEY (id));CREATE TABLE b( id INT AUTO_INCREMENT, c2 VARCHAR(50), c3 VARCHAR(50), PRIMARY KEY (id));CREATE DEFINER=`root`@`%` PROCEDURE `create_test_data`( IN `loop_cnt` INT)LANGUAGE SQLNOT DETERMINISTICCONTAINS SQLSQL SECURITY DEFINERCOMMENT ’’BEGIN DECLARE v2 , v3 VARCHAR(36); START TRANSACTION; while loop_cnt>0 do SET v2 = UUID(); SET v3 = UUID(); if (loop_cnt MOD 10) = 0 then INSERT INTO a (c2,c3) VALUES(DEFAULT,DEFAULT); INSERT INTO b (c2,c3) VALUES(DEFAULT,DEFAULT); else INSERT INTO a (c2,c3) VALUES (v2,v3); INSERT INTO b (c2,c3) VALUES (v2,v3); END if ; SET loop_cnt=loop_cnt-1; END while; COMMIT;

a,b兩張表生產完全一致的數據。

MySQL中建表時可空(NULL)和非空(NOT NULL)的用法詳解

MySQL中建表時可空(NULL)和非空(NOT NULL)的用法詳解

查看占用的存儲空間情況,從information_schema.TABLES中查詢這兩個表的存儲信息

MySQL中建表時可空(NULL)和非空(NOT NULL)的用法詳解

1,一個字節的差別,體現在avg_row_length,a表因為所有的字段都是not null,因此相比b表,每行節省了每行節省了一個字節的存儲2,總得空間的差別:a表662683648/1024/1024=631.98437500MB,b表666877952/1024/1024=635.98437500MB,  也當前情況下,600W行數據有4MB的差異,差異在1%之內,其實實際情況下,字段多,table size更大的的時候,這個差異會遠遠小于1%。

就存儲空間來說,你跟我說1T的數據庫你在乎1GB的存儲空間,隨便一點數據/索引碎片空間,一點預留空間,垃圾文件空間,無用索引空間……,都遠遠大于可為空帶來的額外這一點差異。

2,增刪查改的效率

讀寫操作對比,通過連續讀寫一個范圍之內的數據,來對比a,b兩張表在讀上面的情況。2.1.)首先buffer pool是遠大于table size的,因此不用擔心物理IO引起的差異,目前兩張表的數據完全都存在與buffer pool中。2.1.)讀測試操作放在MySQL實例機器上,因此網絡不穩定引起的差異可以忽略。

增刪查改的差異與存儲空間的差異類似,甚至更小,因為單行相差1個字節,放大到600W+才能看到一個5MB級別的差異,增刪查改的話,各種測試下來,沒有發現有明顯的差異

#!/usr/bin/env python3import pymysqlimport timemysql_conn_conf = {’host’: ’127.0.0.1’, ’port’: 3306, ’user’: ’root’, ’password’: ’******’, ’db’: ’db01’}def mysql_read(table_name): conn = pymysql.connect(host=mysql_conn_conf[’host’], port=mysql_conn_conf[’port’], database=mysql_conn_conf[’db’],user=mysql_conn_conf[’user’],password = mysql_conn_conf[’password’]) cursor = conn.cursor() try: cursor.execute(’’’ select id,c2,c3 from {0} where id>3888888 and id<3889999;’’’.format(table_name)) row = cursor.fetchall() except pymysql.Error as e: print('mysql execute error:', e) cursor.close() conn.close()def mysql_write(loop,table_name): conn = pymysql.connect(host=mysql_conn_conf[’host’], port=mysql_conn_conf[’port’], database=mysql_conn_conf[’db’],user=mysql_conn_conf[’user’],password = mysql_conn_conf[’password’]) cursor = conn.cursor() try: if loop%10 == 0: cursor.execute(’’’ insert into {0}} (c2,c3) values(DEFAULT,DEFAULT)’’’.format(table_name)) else: cursor.execute(’’’ insert into {1}} (c2,c3) values(uuid(),uuid())’’’.format(table_name)) except pymysql.Error as e: print('mysql execute error:', e) cursor.close() conn.commit() conn.close()if __name__ == ’__main__’: time_start = time.time() loop=10 while loop>0: mysql_write(loop) loop = loop-1 time_end = time.time() time_c= time_end - time_start print(’time cost’, time_c, ’s’)

3,相關字段上的語義解析和邏輯考慮

這一點就觀點差異就太多了,也是最容易引起口水或者爭議的了。

1,對于字符類型,NULL就是不存在,‘’就是空,不存在和空本身就不是一回事,不太認同一定要NOT NULL,然后給出默認值。2,對于字符類型,任何數據庫中,NULL都是不等于NULL的,因為在處理相關字段上進行join或者where篩選的時候,是不需要考慮連接雙方都為NULL的情況的,一旦用’’替代了NULL,’’是等于’’的,此時就會出現與存儲NULL完全不用的語義3,對于字符類型,一旦將相關字段default成’’,如何區分’’與空字符串,比如備注字段,不允許為NULL,default成‘’,那么怎么區分,NULL表達的空和默認值的空字符串’’4,對于相關的查詢操作,如果允許為NULL,篩選非NULL值就是where *** is not null,語義上很清晰直觀,一旦用字段非空,默認成’’,會使用where *** <>’’這種看起來超級惡心的寫法,究竟要表達什么,語義上就已經開始模糊了5,對于時間類型,絕大多數時候是不允許有默認值的,默認多少合適,當前時間合適么,千禧年2000合適么,2008年北京奧運會開幕時間合適么?6,對于數值類型,比如int,比如decimal,在可空的情況下,如果禁止為NULL,默認給多少合適,0合適嗎?-1合適嗎?-9999999……合適嗎?10086合適嗎?1024合適嗎?說實話,默認多少都不合適,NULL自身就是最合適的。

個人觀點很明確,除非有特殊的需求要求一個字段絕對不能出現NULL值的情況,正常情況下,該NULL就NULL。如果NULL沒有存在的意義,干脆數據庫就不要存在這個NULL就好了,事實上,哪個數據庫沒有NULL類型?當然也不排除,某些DBA為了顯得自己專業,弄出來一些莫須有的東西,現在就是有一種風氣,在數據庫上能提出來的限制條件越多,越有優越感。

想起來一個有關于默認值有意思的事,B站看視頻的時候某up主曾提到過,因為B站把注冊用戶默認為男,出生日期某認為某個指定的日期,導致該up主在對用戶點為分析后得到一些無法理解的數據。

個人認識有限,數據實話,非常想知道“所有字段非空”會帶來什么其他哪些正面的影響,以及如何衡量這個正面的因素,還有,你們真的做到了,可以禁止整個實例下所有的庫表中的字段禁止可空(nullable)?

到此這篇關于MySQL中建表時可空(NULL)和非空(NOT NULL)的用法詳解的文章就介紹到這了,更多相關MySQL中建表時可空和非空 內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: MySQL 數據庫
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本成人在线一区| 国产日韩欧美一区二区三区在线观看 | 激情婷婷综合| 久久在线电影| 性色一区二区| 中文字幕av一区二区三区四区| 免费在线观看日韩欧美| 蜜桃久久av一区| 日韩1区2区3区| 国产免费久久| 久久久久久亚洲精品美女| 精品久久免费| 成人在线超碰| 国产精品久久久久av电视剧| 色老板在线视频一区二区| 国产一区日韩欧美| 亚洲专区一区| 欧美天堂一区二区| 精品三区视频| 亚洲香蕉网站| 国产一级久久| 91精品国产自产观看在线 | 日韩中文在线电影| 1024精品一区二区三区| 亚洲一区日韩在线| 欧美偷窥清纯综合图区| 国精品产品一区| 日韩大片在线播放| 婷婷亚洲综合| 午夜精品影视国产一区在线麻豆| 热久久久久久| 97在线精品| 国产一区导航| 国产精品2区| 成人免费电影网址| 亚洲精品高潮| 精品国产一级| 欧美高清不卡| 69堂精品视频在线播放| 精品视频97| 亚洲免费黄色| 国产三级一区| 影视先锋久久| 国产欧美69| 不卡视频在线| 国产精品啊v在线| 麻豆国产在线| 欧美综合二区| 高潮久久久久久久久久久久久久| 在线亚洲激情| 精品欧美视频| 快she精品国产999| 国产福利91精品一区二区| 欧美专区18| 久久不卡国产精品一区二区| 日韩欧美网址| 日韩一区二区三区高清在线观看| 精品久久不卡| 免费高清在线一区| 精品国产亚洲日本| 亚洲午夜免费| 久久久久一区| 国产精品激情电影| 亚洲免费影视| 88xx成人免费观看视频库| 欧美一区成人| 国产日韩专区| 美女av在线免费看| 91欧美日韩在线| 99久久精品国产亚洲精品| 青青草91视频| 亚洲一区二区三区免费在线观看| а√天堂8资源中文在线| 青草国产精品| 香蕉久久国产| 日韩精品影视| 欧美91在线|欧美| 免费一级片91| 久久精品官网| 日本一二区不卡| 欧美一级网址| 老色鬼久久亚洲一区二区| 日韩精品91| 精品三级在线| 欧美精品影院| 一区久久精品| 999久久久国产精品| 精品午夜久久| 国产精品玖玖玖在线资源| 亚洲有吗中文字幕| 久久精品国产99久久| 精品99在线| 国产九九精品| 日韩激情精品| 亚洲1区在线观看| 午夜欧美精品| 久久国产免费| 日韩久久视频| 大香伊人久久精品一区二区| 69堂免费精品视频在线播放| 在线国产精品一区| 1000部精品久久久久久久久| 麻豆视频在线观看免费网站黄 | 少妇精品久久久一区二区| 黄色亚洲免费| 蜜桃成人av| 日韩成人高清| 国产福利电影在线播放| 国产精品久久亚洲不卡| 亚洲免费毛片| 免费在线看一区| 亚洲一区观看| 免费久久99精品国产自在现线| 久久久久久美女精品| 激情黄产视频在线免费观看| 成人国产精品一区二区免费麻豆| 日本h片久久| 欧美亚洲tv| 国产精品久久乐| 国产精品亚洲一区二区在线观看| 国产探花一区| 国产精品日本一区二区三区在线| 国产探花在线精品一区二区| 久久精品 人人爱| 日韩精品免费观看视频| 日本 国产 欧美色综合| 免费欧美日韩| 亚洲色图国产| 日韩三级久久| 日韩二区在线观看| 国产精品视频一区视频二区| 国产日韩欧美三级| 国产精品亚洲综合久久| 麻豆久久久久久| 你懂的国产精品| 国产夫妻在线| 亚洲福利免费| 国产亚洲高清视频| 亚洲综合图色| 日本少妇一区二区| 欧美精品第一区| 黄色aa久久| 婷婷亚洲五月色综合| 中文一区一区三区免费在线观| 日韩国产精品久久久久久亚洲| 日韩成人精品一区二区三区| 国产亚洲欧美日韩在线观看一区二区| 久久av影院| 成人日韩精品| 午夜电影亚洲| 日韩精品一区二区三区免费视频| 91精品在线免费视频| 精品入口麻豆88视频| 成人午夜国产| 美女国产精品| 91成人小视频| 韩国久久久久久| 亚洲免费成人| 欧美欧美黄在线二区| 精品国产乱码久久久久久1区2匹| 日本在线高清| 在线亚洲国产精品网站| 日本麻豆一区二区三区视频| 久久精品免视看国产成人| 久久九九精品| 日韩精品视频在线看| 黄色在线观看www| 天使萌一区二区三区免费观看| 日本色综合中文字幕| 国语对白精品一区二区| 九九久久婷婷| 久久国产视频网| 色综合www| 亚洲毛片网站| 精品国产精品国产偷麻豆| 亚洲欧洲午夜| 卡一卡二国产精品| 美女少妇全过程你懂的久久| 日韩超碰人人爽人人做人人添| 国产理论在线| 亚洲精品大片| 日韩免费福利视频| 日韩av在线播放中文字幕| 97精品中文字幕| 日韩专区一卡二卡| 精品国产99| 亚州av一区| 久久久久久美女精品| 国产亚洲欧美日韩在线观看一区二区 | 亚洲精品日本| 日韩国产欧美一区二区| 国产调教精品| 久久一区二区三区电影| 国产精品美女久久久久久不卡| 91九色精品| 麻豆视频一区二区| 久久亚洲国产精品一区二区| 国产成人精品一区二区三区免费 | 欧美一区二区三区久久精品| 欧美日韩精品一区二区视频|