PostgreSQL 不在使用tigger或rule来模拟 SSQLSERVER timestamp 行变化版本管理
每種數據庫都有自己的特色,SQL SERVER 也有自己的招數,timestamp字段類型會針對于行中任何列值的變化,而改變,之前也寫過PG 怎么來模擬這個功能
https://blog.csdn.net/liuhuayang/article/details/106682052
看看自己以前寫的,青澀了。上一篇提到了,軟實力的建設,終究數據庫不光是備份,高可用架構,以及內核研究,你要服務的應用程序到底怎么能更用好數據庫的功能是另一個賽道。
PG中的Generated Columns 是基于PG12 后添加的,生成列主要的功能在于簡化數據的獲取,可以將部分SQL的撰寫變得更加的簡單。我們從簡單的開始,直到怎么能模擬 SQL SERVER timestamp 字段的獨有功能。
我們提供 actor 表作為源對象
然后我們將數據灌入到? actor_copy 表中,然后查看表,可以看到多了一列并且這一列實際上是 first_name 和 last_name 的組合。那么name ?這一列到底是怎么生成的。
create table actor_copy?
(id int,?
first_name varchar(20),
last_name varchar(20),
last_update timestamp,
name varchar(40) GENERATED ALWAYS AS (first_name ||' ' || last_name) stored);
其中name 就是一個生成列,通過生成列將表中的字段 first_name 和 last_name 兩個字段結合,生成新的字段name. ?在查詢時就不需要?在語句中拼接兩個字段。?
當然看上去好像也沒有什么用,我們看下一個例子,表payment 中 amount ?記錄這每次顧客付出的租金,而實際上如果要計算一個扣除稅的金額,并加載到表中就比較麻煩了。
Alter table payment add column after_tax numeric(10,2) GENERATED ALWAYS AS (amount - 1) stored;
在添加這一列后,可以看到我們的列中已經有了相關的數字。查詢SQL的時候后續就可以直接引用這一列,并且這一列會隨著amount的變化而變化。
生成列本身可以利用場景會比較多,看你怎么玩,甚至可以寫一個函數,將加載到這一列的值先進行函數的計算,然后落表。
下面進入主題,很多業務場景都希望在一次事務操作行后任意列的值是否變化并判斷這行是否變化了。應用場景有很多,舉例客戶點單,然后客戶在完成訂單后,會改變這個訂單所在行的某列,或某幾列的信息
之前類似SQL SERVER 的TimeSTAMP 就可以完成這個功能,任何一列的值變化,都會自動觸發timestamp 字段的值變化, SQL SERVER 中的timestamp 并不是一個時間字段,而是一段二進制碼。這個功能在 MYSQL 或ORACLE 都沒有。
大部分的思路想要模擬還是通過觸發器來在數據update 后,更新字段的值來完成判斷。
但PG可以拋棄trigger 的方式或rule的方式,通過 PG12 加入的生成列來完成這個功能。
這里我們用film 表做一個事例
1 添加generated 行,其中對于title 和 description 的字段合并后,進行md5的運算,然后將這個值存儲在 sqlserver_timestamp ?字段。
2? 我們隨便找一行,然后更改其中的值
3 我們比對在修改前 sqlserver_timestamp 字段的值的變化
4? OK 沒有問題
下面的命令就是添加這個功能在這個表,title 或者 description 兩個字段的值進行更改后,通過類似sql server timestamp功能來判斷這一行的兩個字段值變化了。
alter table film add column sqlserver_timestamp? text? GENERATED ALWAYS AS (md5(coalesce(title,'1') || coalesce(description,'1') )) stored;
經過比對后,的確值是變化了,哪怕你只改變一個字母,甚至你加入一個空格,都會改變值。
此時應用程序就很簡單的繼續使用類似SQL SERVER 的功能,
1?? 在處理事務前,通過查詢將修改的條件行中的sqlserver_timestamp 行的值記錄到緩存中
2? 執行事務
3? 查詢film表中的 sqlserver_timestamp 行的值,與之前的值是否有變化
變化就是證明這兩個字段的值一個或兩個都變化了,否則就是沒有改變。
這樣就能證明事務執行的成功或失敗,或者更新中那些行的改變值和原來的值是一致的,那些不是。
這個功能還是比較有用的,好處就是徹底和笨拙的 trigger 或 rule 說拜拜。
當然這里留了一個問題,為什么要通過coalesce 來對字段進行處理,直接計算不是更快?WHY
PG 功能還是很強大的,只要愿意動腦,大多數時候開發提出的需求,我們都可以說 sure, no problem. ?至少PG 不是一個數據存儲容器,而是數據處理的單元,維度不同,高度不同。
總結
以上是生活随笔為你收集整理的PostgreSQL 不在使用tigger或rule来模拟 SSQLSERVER timestamp 行变化版本管理的全部內容,希望文章能夠幫你解決所遇到的問題。