這篇文章給大家介紹PostgreSQL MySQL 行版本管理與 SQL SERVER timestamp 行版本管理對(duì)比的示例分析,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
員工經(jīng)過(guò)長(zhǎng)期磨合與沉淀,具備了協(xié)作精神,得以通過(guò)團(tuán)隊(duì)的力量開發(fā)出優(yōu)質(zhì)的產(chǎn)品。創(chuàng)新互聯(lián)堅(jiān)持“專注、創(chuàng)新、易用”的產(chǎn)品理念,因?yàn)椤皩W⑺詫I(yè)、創(chuàng)新互聯(lián)網(wǎng)站所以易用所以簡(jiǎn)單”。公司專注于為企業(yè)提供成都網(wǎng)站建設(shè)、成都做網(wǎng)站、微信公眾號(hào)開發(fā)、電商網(wǎng)站開發(fā),小程序開發(fā),軟件按需網(wǎng)站設(shè)計(jì)等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。
事情的發(fā)生時(shí)這樣的,在很久很久以前,SQL SERVER 有一個(gè)字段類型叫timestamp, 對(duì)比其他數(shù)據(jù)庫(kù)都沒有的 row version 自動(dòng)化管理的東西。這個(gè)東西厲害的地方,雖然看上去可能是一個(gè)時(shí)間字段,但實(shí)際上不是,只要你對(duì)SQL SERVER 表的任意一行進(jìn)行變動(dòng),那你放心那個(gè)字段的值一定會(huì)自動(dòng)變化,這樣你就可以通過(guò)這個(gè)字段,在程序里面先將這行的 timestamp值取出來(lái),然后根據(jù)業(yè)務(wù)邏輯,如果需要過(guò)段時(shí)間你再去這一行變化或曾經(jīng)變化過(guò)嗎?之間與現(xiàn)在的timestamp字段值進(jìn)行比對(duì),那妥妥的能告訴你,這行的數(shù)據(jù)任意字段是否變化過(guò),有人說(shuō)MYSQL也有timestamp ,那個(gè)字段是通過(guò)時(shí)間來(lái)update 只要這個(gè)行變動(dòng)過(guò)就觸發(fā)timestamp 更改時(shí)間就可以了,當(dāng)然datetime也行,早期版本不行。
我只能用哼的一聲回敬, too young to simple. 人家sql server 的字段不是時(shí)間,人家不存在你并發(fā)高然后給出的,毫秒,微妙之類可能重復(fù)的可能性,因?yàn)槿思沂俏ㄒ恢?一串人類不懂的二進(jìn)制。
所以MYSQL 用了timestamp 然后還得搭上一個(gè)觸發(fā)器,然后還不一定準(zhǔn)。
所以就這樣了,NO NO NO
只要知道大致的原理,PostgreSQL ,MYSQL 統(tǒng)統(tǒng)的可以活學(xué)活用,做我們自己的 row version management.
這里先說(shuō)PG ,PG 要比MYSQL 方便的多,因?yàn)樘焐幕?,讓他做這個(gè)事情,很簡(jiǎn)單。PG的行版本管理是基于system column 其中有一個(gè)字段是ctid
以下是官方文檔
意思就是這個(gè)ctid 字段在表里面行版本表示這一個(gè)行的物理位置。請(qǐng)注意,雖然可以使用ctid非??焖俚囟ㄎ恍邪姹?,但是如果更新或移動(dòng)了某個(gè)行的ctid,它就會(huì)發(fā)生變化。因此,ctid作為長(zhǎng)期行標(biāo)識(shí)符是無(wú)用的。應(yīng)該使用OID,或者用戶定義的序列號(hào)來(lái)標(biāo)識(shí)邏輯行。
所以呢,我們要的就是你的這個(gè)可以快速定位以及如果更新了,或移動(dòng)了某個(gè)行的ctid 就會(huì)變化值。這就等同于 ,postgresql 天生在每個(gè)行上都給你做了一個(gè)GPS, 然后只要update ,或者數(shù)據(jù)移動(dòng)了,例如copy 一個(gè)表到另一個(gè)地方等等的情況。那這個(gè)ctid 就會(huì)變化。
可以看下面的圖
通過(guò)這個(gè)系統(tǒng)自帶的ctid 可以很清楚,在這個(gè)行上到底做過(guò)UPDATE 操作沒有,只要做了,并且是更新的值和原有的值一樣的情況下,也會(huì)更新這個(gè)值。
從這里也就泄露了一些PG的原理。
所以PG 的行版本管理就如此簡(jiǎn)單的比SQL SERVER 還簡(jiǎn)單的完成了,并且性能還要高,這是原生的。只要每次獲得你關(guān)心這行的 ctid 然后在你想使用它的時(shí)候,在取一次值,相同那一定這一行是沒有動(dòng)過(guò),也就證明了你關(guān)心的那個(gè)字段一定也沒有變化。
下面輪到MYSQL 了,實(shí)際上MYSQL 本身的不具備POSTGRESQL 這樣的物理定位的標(biāo)記,同時(shí)也沒有SQL SERVER 那樣的timestamp 字段。可使用MYSQL 的人們一貫的心靈手巧,多動(dòng)多思,也有辦法。
實(shí)際上 sql server timestamp 想當(dāng)于給一個(gè)表添加了一個(gè)計(jì)數(shù)器,針對(duì)每一行, 而Postgresql 是每一行有一個(gè) "GPS" 定位系統(tǒng)。
MYSQL 我們可以
1 和開發(fā)團(tuán)隊(duì)定義一個(gè)判斷一行的字段變化的顯示值,也就是要添加一個(gè)字段,來(lái)模擬sql server 的timestamp 這個(gè)字段,具體用什么類型,插入什么值,需要和開發(fā)團(tuán)隊(duì)來(lái)商量
2 在任何的DML 語(yǔ)句中,只要有UPDATE 就需要附帶對(duì)這個(gè)字段的更新
我們看一下,我們要對(duì)當(dāng)前的表添加一個(gè)字段,具體是什么字段類型不重要,這里只是模擬一下。checksum 就是那個(gè)添加的字段 binary
在添加了字段后,我們對(duì)任何值的變動(dòng)都會(huì)將附加字段的值進(jìn)行變更,為了規(guī)范可以用一個(gè)函數(shù),(函數(shù)的質(zhì)量要高,否則可能會(huì)影響性能)
我們可以看一下結(jié)果,為什么選擇這個(gè)怪異的東西,原因是不會(huì)有人“失誤”的來(lái)更改我們的checksum 字段來(lái)避免一些“人為的錯(cuò)誤”。
通過(guò)上面的一些東西,也可以看出每種數(shù)據(jù)庫(kù)其實(shí)都有自己的特點(diǎn),掌握了原理,并且能模擬原理,就可以彌補(bǔ)一些本身不提供的功能,或者與生俱來(lái)的特異功能。
或許有人說(shuō),干嘛不給MYSQL 設(shè)置 default value 然后這樣我就不用去insert 的時(shí)候還要帶那個(gè)字段,或者在回到使用觸發(fā)器之類的。
1 使用MYSQL 是為了更高的并發(fā),使用觸發(fā)器不適合我們的初衷
2 如果設(shè)置了某些默認(rèn)值,并且在非單庫(kù)的情況下,會(huì)有類似的error提示
關(guān)于PostgreSQL MySQL 行版本管理與 SQL SERVER timestamp 行版本管理對(duì)比的示例分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。