我一開始登入本地端 Oracle 資料庫(使用 DBA 帳號),想先確認有哪些 schema,可以用:
SELECT username FROM dba_users ORDER BY username;
如果只想看哪些 schema 有資料表,也可以查:
SELECT owner FROM dba_tables GROUP BY owner ORDER BY owner;
這些指令幫我快速掌握目前環境的 schema 構成,也避免誤判匯入後的結果。
匯入後發現,EIP schema 下的資料分散到 ASSM
和 EJEMS
兩個 tablespace。
這不是匯入錯誤,而是來源機器的 EIP schema 原本就有資料與索引分散在不同的 tablespace:
CREATE TABLE emp (...) TABLESPACE ASSM;
CREATE INDEX emp_idx ON emp(id) TABLESPACE EJEMS;
我用以下 SQL 來驗證這個狀況:
SELECT table_name, tablespace_name
FROM dba_tables
WHERE owner = 'EIP';
SELECT index_name, tablespace_name
FROM dba_indexes
WHERE owner = 'EIP';
項目 | Schema | Tablespace |
---|---|---|
是什麼 | 使用者帳號 | 儲存資料的邏輯空間 |
關係 | Schema 擁有物件 | Tablespace 儲存物件資料 |
可否一對多 | ✅ Schema 可跨多個 tablespace | ✅ 多 schema 可共用同一 tablespace |
Schema 是「誰擁有資料」,Tablespace 是「資料放在哪」。兩者沒有從屬關係,也不是一對一。
在應用程式的開發與執行層面上,通常不需要直接處理 Tablespace。程式只會針對已存在的資料表進行 CRUD 操作(Create, Read, Update, Delete),這些動作都不會影響物件實際儲存的位置。
但在下列情境中,Tablespace 的設計會間接影響應用程式:
若 tablespace 空間不足,會導致 INSERT 或 UPDATE 操作報錯,例如:
ORA-01653: unable to extend table ... in tablespace ...
若應用程式設計包含動態建表功能(如部署安裝時建立 schema),這時建表語法就必須指定正確的 tablespace 或預設 tablespace 已有足夠空間。
DBA 與 DevOps 人員會透過 Tablespace 管理儲存策略(分區、資料冷熱區隔、I/O 負載分散等),間接影響應用程式效能。
總結來說,應用程式通常無直接操作 tablespace,但建表與環境佈建的腳本則須留意 tablespace 的配置與配額,避免執行錯誤或資料分佈混亂。
我為本地測試環境建立了一個新的 schema KGEIP
,並配置好權限與 tablespace:
CREATE USER KGEIP IDENTIFIED BY mypassword
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP;
GRANT CONNECT, RESOURCE TO KGEIP;
ALTER USER KGEIP QUOTA UNLIMITED ON USERS;
如果忘了 QUOTA
,會出現錯誤訊息 ORA-01950: no privileges on tablespace 'USERS'
。
在複製資料庫時,我有使用 TOAD 的「Export DDL」功能來導出 schema 的建表與索引語法。預設設定中,TOAD 會加入 DROP TABLE
與 DROP INDEX
,這會導致若目標環境中該物件不存在時出現錯誤,例如:
ORA-00942: table or view does not exist
為了解決這個問題,我在 TOAD 的 Script Options
設定中取消了 DROP
的勾選。
另外一個需要留意的是:TOAD 產出的順序是先 CREATE INDEX
再 CREATE TABLE
,這在某些情況下會導致錯誤。為了確保建表過程順利,我將 CREATE TABLE
的語句移動到 CREATE INDEX
前面,手動調整語法順序後再執行。
這個調整雖然不大,但避免了重複執行腳本時造成不必要的錯誤與中斷。
在某個表格欄位值出現 PC&NB
時,匯入工具跳出了變數輸入框,讓我輸入 &NB
。
這是 Oracle 把 &
當成替代變數。解法有兩種:
SET DEFINE OFF;
'PC'||CHR(38)||'NB'
建議在 SQL 腳本開頭就加入:
SET DEFINE OFF;
以後就不會被 A&B
, R&D
這類字串搞瘋。
SELECT tablespace_name, contents FROM dba_tablespaces;
-- 範例略,可視需求使用 JOIN 查詢 data_files + free_space
SELECT tablespace_name, SUM(bytes_used)/1024/1024 AS used_mb
FROM v$temp_space_header GROUP BY tablespace_name;
SELECT default_tablespace FROM dba_users WHERE username = 'KGEIP';
我從測試機匯入 Oracle schema,為什麼會有多個 tablespace?
請給我 impdp remap_tablespace 的語法範例。
如何建立一個新的 Oracle 使用者並設定 tablespace 配額?
匯入時遇到 PC&NB 類似字串導致跳出變數對話框,該怎麼處理?
在使用 TOAD 匯出 Oracle 建表與資料腳本時,這些小技巧可以幫助你更順利地產出可用的 SQL:
DROP
選項,避免執行時因物件不存在而報錯。Insert
,讓導出的腳本包含資料內容(INSERT INTO 語句)。SET DEFINE OFF;
避免字串中出現 &
被當作變數。CREATE TABLE
語句手動移動到所有 CREATE INDEX
之前。這樣處理後,我成功產出了一份可以在本地端環境順利執行的完整建表與匯入語法。