記一次Oracle Rename Table的實戰應用


起因

在生產環境下我們要在某個表 PRODUCT 上刪除一些重復的數據。開始之前,我們首先對該表做了備份,如下:

	CREATE TABLE APP.PRODUCT_201910 TABLESPACE "TABLESPACE_1" nologging AS SELECT * FROM APP.PRODUCT WHERE 1=2;
	INSERT /*+ APPEND PARALLEL(8) */ INTO APP.PRODUCT_201910 nologging SELECT * FROM APP.PRODUCT;
	COMMIT;

需要注意的是,使用 CATS(CREATE TABLE AS) 方法創建出來的表,不從其父表繼承約束、身份列、默認列值或主鍵。

完了之后,我們就開始對 PRODUCT 進行操作,但是由於 DB Performance 的原因,在原先預估的時間內沒有完成。為了不影響后續其它腳本,決定先放棄這個操作,將 PRODUCT 還原回去。

發展

首先,我們讓 DBA 定位到正在運行的 query ,手動將其 kill 掉。

其次,我們用 backup 表替換回原表。

	RENAME APP.PRODUCT TO APP.PRODUCT_BROKEN;
	RENAME TABLE APP.PRODUCT_201910 TO APP.PRODUCT;

但是,到這里還沒有結束,原表還有很多屬性需要重新再修改回去。這個過程需要特別注意,因為很容易漏掉一些步驟。

設置 Sequence, Default Value

這幾步是比較常見也是執行得很快的。

Add sequence

	DROP SEQUENCE APP.PRODUCT_ID_SEQ
	ALTER TABLE APP.PRODUCT MODIFY PRODUCT_ID NUMBER(10,0) DEFAULT APP.PRODUCT_ID_SEQ.NEXTVAL

Set default value

	ALTER TABLE APP.PRODUCT MODIFY PRODUCT_KEY VARCHAR2(300 CHAR) DEFAULT '-1';
	ALTER TABLE APP.PRODUCT MODIFY PRODUCT_TYPE_ID NUMBER(5,0) DEFAULT -1;
	ALTER TABLE APP.PRODUCT MODIFY DATE TIMESTAMP (6) DEFAULT CURRENT_TIMESTAMP;

設置 Constrain

  1. 加主鍵。
  2. 檢查一下是否有外鍵鏈接到該表。
	-- 1
	DROP CONSTRAINT APP.PRODUCT_PK
	ALTER TABLE APP.PRODUCT ADD CONSTRAINT APP.PRODUCT_PK PRIMARY KEY ("PRODUCT_PK");
	
	-- 2
	SELECT * FROM DBA_CONSTRAINTS A, DBA_CONSTRAINTS B 
	WHERE A.CONSTRAINT_TYPE = 'R'
	AND A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME
	AND A.R_OWNER = B.OWNER
	AND B.TABLE_NAME = 'PRODUCT'
	AND B.OWNER = 'APP';

設置 Index

索引加起來可能會慢一點。

	DROP INDEX APP.IDX_PRODUCT_KEY_DATE

	CREATE INDEX APP.IDX_PRODUCT_KEY_DATE ON APP.PRODUCT ("PUBLIC_KEY", "END_DATE") 
	PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
	STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
	PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
	BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
	TABLESPACE "TABLESPACE_1";

需要注意的是,主鍵的index不需要再額外創建。

Oracle enforces a UNIQUE key or PRIMARY KEY integrity constraint on a table by creating a unique index on the unique key or primary key. This index is automatically created by Oracle when the constraint is enabled.

設置 Dependency

依賴對象重建:這里重建的只是直接依賴對象。

	-- check sql
	SELECT * FROM DBA_DEPENDENCIES A WHERE A.REFERENCED_NAME = 'PRODUCT' AND A.REFERENCED_OWNER = 'APP';
	-- modify sql
	SELECT 'alter '||DECODE(TYPE,'PACKAGE BODY','PACKAGE',TYPE)||' '||OWNER||'.'||NAME||' compile;' 
	FROM DBA_DEPENDENCIES A 
	WHERE A.REFERENCED_NAME = 'PRODUCT' 
	AND A.REFERENCED_OWNER = 'APP';

設置 Privilege

權限重建

	-- check sql
	SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME = UPPER('PRODUCT') AND OWNER = UPPER('APP');
	-- modify sql
	SELECT 'grant ' || PRIVILEGE || ' on ' || OWNER || '.' || TABLE_NAME || ' to ' || GRANTEE || ';'
	FROM DBA_TAB_PRIVS
	WHERE TABLE_NAME = UPPER('PRODUCT')
	AND OWNER = UPPER('APP');

總結

除了以上提到的

  • Sequence, Default Value
  • Constrain
  • Index
  • Dependency
  • Privilege

之外,還有物化視圖和物化視圖日志,具體可以看參考鏈接。

所以,用 rename 方法還是相當麻煩的。如果數據量不是很大的情況下,還是建議直接把數據 insert 回原表,方便簡潔不易出錯。

參考鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM