json字段類型在當(dāng)前的版本中自身沒有索引,那么在生產(chǎn)中是非??膳碌?,json字段的增、刪、改、查效率可想而知,基本沒法用,也許是基于此,mysql5.7中提供了generated字段類型,網(wǎng)上有叫生成列或是計算列的。這里先來了解一下什么是generated column。
1、Generated Column介紹
Generated Column是MySQL 5.7.6引入的新特性,所謂Cenerated Column,就是數(shù)據(jù)庫中這一列由其他列計算而得。引用官方參考手冊中的例子予以說明:
CREATE?TABLE?triangle?( ??sidea?DOUBLE, ??sideb?DOUBLE, ??sidec?DOUBLE?AS?(SQRT(sidea?*?sidea?+?sideb?*?sideb)) ); INSERT?INTO?triangle?(sidea,?sideb)?VALUES(1,1),(3,4),(6,8); mysql>?SELECT?*?FROM?triangle; +-------+-------+--------------------+ |?sidea?|?sideb?|?sidec??????????????| +-------+-------+--------------------+ |?????1?|?????1?|?1.4142135623730951?| |?????3?|?????4?|??????????????????5?| |?????6?|?????8?|?????????????????10?| +-------+-------+--------------------+
Generated Column有兩種,即Virtual Generated Column和Stored Generated Column,前者只將Generated Column保存在數(shù)據(jù)字典中(表的元數(shù)據(jù)),并不會將這一列數(shù)據(jù)持久化到磁盤上;后者會將Generated Column持久化到磁盤上,而不是每次讀取的時候計算所得。很明顯,后者存放了可以通過已有數(shù)據(jù)計算而得到的數(shù)據(jù),需要更多的磁盤空間,與Virtual Column相比并沒有優(yōu)勢,因此,MySQL 5.7中,不指定Generated Column的類型,默認(rèn)是Virtual Column。雖然一般情況下都應(yīng)該使用Virtal Generated Column,但是,目前使用Virtual Generated Column還有很多限制:不能用作主鍵、不能作為主鍵、不能創(chuàng)建全文索引和空間索引等,但是在后續(xù)的版本中可能支持,所以如果使用Generated Column字段做索引的話,還是使用Stored Generated Column吧,在使用Generated Column做索引上,JSON字段索引的解決方案,官方也是推薦使用Stored Generated Column。使用Stored Generated Column建表語句如下,只是在加了個單詞:
CREATE?TABLE?triangle?( ??sidea?DOUBLE, ??sideb?DOUBLE, ??sidec?DOUBLE?AS?(SQRT(sidea?*?sidea?+?sideb?*?sideb)?STORED) );
2、Generated Column注意事項
Generated Column是不能進(jìn)行寫操作的,它是自動生成的;在創(chuàng)建的時候要考慮這個列的計算公式是否合理,不合理的話創(chuàng)建的時候不會報錯,使用時插入值就會報錯;Generated Column依賴的列在刪除的時候會提示報錯,必須先刪除Generated Column才能再去刪除它依賴的列;Generated Column定義不合法,如我們將generated column定義為?“x列+y列”,很明顯,x列或y列都是數(shù)值型,如果我們將x列或y列定義(或修改)為字符型,則預(yù)期會報錯,但實際上我們可以正常創(chuàng)建,但是在插入的時候是會報錯的。
3、利用Generated Column給JSON字段添加索引
正常情況下,JSON字段的相關(guān)查詢是掃描全表的,因為JSON字段本身不能創(chuàng)建索引的,我們利用Generated Column特性,對JSON字段中相關(guān)key作為Generated Column來做生成列,然后對Generated Column做索引:
ALTER?TABLE?json_test?ADD?COLUMN?age?INT?AS? (JSON_EXTRACT(user_info,'$.age'))?STORED, ?ADD?KEY?idx_age?(age);
前后對比圖如下:
可以很明顯的看出,使用Generated Column并添加索引后,查詢JSON字段中的值使用索引。
結(jié)束語
MySQL5.7中Generated Column和JSON Column的出現(xiàn),使一些場景替代MongoDB等NoSQL提供了可能,雖然整體上還沒有MongoDB等做的那么強(qiáng)大,但相信以后使用這兩種類型的場景會越來越多,?同時對DBA的挑戰(zhàn)也越來越大,希望密集使用JSON類型業(yè)務(wù)使用獨立的MySQL實例來運行,以免JSON成為大字段(存儲在JSON文檔的大小JSON?列被限制為值?max_allowed_packet的系統(tǒng)變量)時對其他業(yè)務(wù)帶來影響。
以上就是MySQL 5.7新特性| Json Column和Generated Column(下)的內(nèi)容,更多相關(guān)內(nèi)容請關(guān)注PHP中文網(wǎng)(www.php.cn)!