在開發過程中難免會遇見這樣的問題:在使用了一段資料庫後需要在資料庫的某乙個表上增加約束條件 ,來減少前台的校驗工作,將校驗工作交給資料庫來處理。但是在增加約束時會遇到乙個這樣的問題,就是已經存在的歷史資料不是都滿足這個約束條件的,這樣的話你加約束就會失敗。典型的問題是:你要使某一列為非空,但是在最開始建表的時候,並沒有考慮到這個問題,造成當前表中好多行的該字段的值為空,當然我們有辦法來搞定它,就是將空的都賦值,然後我們再增加約束,但是這終究是個治標不治本的問題。
基於上述原因,有必要對oracle的約束進行考究,原來oralce的約束狀態有四種:
1.enable validate;
--當將約束狀態轉變為這種狀態時需要新舊資料都要滿足這種需求,這也是預設的狀態。
2.enable novalidate;
--只對新資料產生作用,舊的資料不用次約束來檢查,即增加此約束後的新資料要滿足這種要求。
3.disable validate;
--不允許在表上執行任何dml操作。
4.disable novalidate;
--資料可以不滿足約束規則。
應用例項:我在scott上做測試。
create table t_operator_info(longin_name varchar2(20),password varchar2(20));
--增加主鍵約束:
alter table t_operator_info add constraint pk_login_name primary key(login_name);
--插入兩條資料:
insert into t_operator_info values ('admin','admin');
insert into t_operator_info values ('manager,123);
commit;
--增加約束條件,使得login_name的長度不能少於6位,但是現在已經存在少於6位的資料,因此我增加
下面的約束時會報錯:
alter table t_operator_info add constraint check_login_name check(length(login_name)>=6);
ora-02293: 無法驗證 (scott.con_check) - 違反檢查約束條件
但是我如果提供了該約束的狀態後就不會報錯:
alter table t_operator_info add constraint check_login_name check(length(login_name)>=6) enable novalidate;
table altered.
至此問題解決。
對於歷史資料問題的思考
在做企業資訊化的過程中,對於歷史資料和歷史資料包表的處理遇到了些問題,主要是兩個方面 1 歷史資料歸檔。這方面看到了一些討論,主要方向是做乙個相同的歸檔庫,定期將流通資料庫中內容放到歸檔庫或者叫歷史庫中。裡面有幾個細節問題需要考慮怎麼處理 首先是如何描述歸檔規則,也就是如何界定歷史資料 對於不同的資...
線上MySQL某個歷史資料表的分割槽筆記
背景 線上的乙個歷史資料庫,業務方反饋經常遇到乙個範圍查詢就導致cpu迅速飆公升的情況。拿到他們提供的sql後,sql類似下面這種 select from order his where x 222 and x 1 and order time 2016 11 01 00 00 00 and ord...
寫有效的歷史資料遷移sql
對於高併發oltp系統,生產庫可能只需保留當前幾個月的資料,之前的資料要全部遷移到歷史庫中。那麼,如何處理這樣的需求,如何寫合適的歷史遷移程式呢?1.常規寫法 begin 遷移資料 insert into tb users select from tb users dbc a where gmt m...