Mit Oracle External Table kann man seit jeher auf Datenmengen, die in Dateien ausserhalb der Datenbank gespeichert sind, lesend zugreifen.
In der Datenbank werden dabei nur die erforderlichen Metadaten der External Tables gespeichert.
Voraussetzung ist immer das Vorhandensein eines logischen Directories und die Verwendung eines entsprechenden Access Treibers wie z.B. ORACLE_LOADER oder
ORACLE_DATAPUMP.
Die Dateien können in unterschiedlichen Formaten im Dateisystem, im HDFS oder aber auch mit Autonomous Database im Oracle Cloud Object Storage
vorliegen. Bei Letzterem ist die Verwendung des Package DBMS_CLOUD erforderlich.
Seit geraumer Zeit gibt es zusätzlich die Möglichkeit External Tables auch partitioniert abzulegen. Damit war es nur noch eine Frage der Zeit, dass
man auch eine gemischte - also eine hybride Speicherung - mit der External Table Technik erlaubt.
Mit Oracle Database 19c ist es soweit: nun besteht die Möglichkeit hybride partitionierte Tabellen (engl. hybrid partitioned tables) anzulegen.
Die Partitionen von hybriden, partitionierten Tabellen können dann sowohl in der Oracle Datenbank in Oracle Tablespaces als auch in
externen Quellen vorliegen, wie z.B. Linux-Dateien mit CSV-Einträgen oder Dateien auf dem Hadoop Distributed File System (HDFS).
So lassen sich beispielsweise Partitionen, die nicht mehr so häufig abgefragt werden, einfach in externe Dateien verschieben,
um so eine kostengünstigere Speicherlösung zu verwenden.
Folgende Grafik zeigt die Architektur einer Hybrid Partitioned Table.
Hybrid Partitioned Tables unterstützen dabei alle existierenden Tabellentyptreiber für externe Partitionen wie
ORACLE_DATAPUMP, ORACLE_LOADER, ORACLE_HDFS und ORACLE_HIVE.
Um hybrid partitioned Tables anzulegen, wird eine erweiterte External Table Syntax verwendet. Hybrid Partitioned Tables können mit
CREATE TABLE oder auch mit ALTER TABLE erzeugt werden. Mit dem ALTER TABLE Kommando können dann beispielsweise "normal" partitionierte Tabellen
nachträglich mit externen Partitionen angereichert werden. Eine gute Einführung findet sich im Handbuch "VLDB and Partitioning Guide" im Kapitel Hybrid Partitioned Tables.
Hier werden u.a. auch die Einschränkungen beschrieben. So sind die Operationen wie SPLIT, MERGE und MOVE nicht erlaubt und als Partitionierungstyp
bisher nur Single Level Partitionierung mit LIST und RANGE möglich. Darüberhinaus gibt es im Moment auch keine Unterstützung für LOB, LONG und ADT Datentypen.
Hybrid Partitioned Tables mit CREATE TABLE erzeugen
In Szenario 1 wird eine hybrid partitioned Table mit CREATE TABLE angelegt. Die Partition DEPTNO_10 ist eine interne Partition, DEPTNO_20 eine externe Partition.
Die Klausel EXTERNAL PARTITION ATTRIBUTES gibt den Treiber (hier: ORACLE_LOADER) und das Directory (hier: HOME) für die externe(n) Partition(en) an.
Die CSV Datei emp_dept_20.csv im Directory HOME speichert die Informationen zur Partition DEPTNO_20.
Tipp: Mit dem SQL*Plus Kommando SET MARKUP CSV {ON|OFF} [DELIMI[TER] character] [QUOTE {ON|OFF}] lassen sich die Daten aus Tabellen einfach
im CSV Format ausgeben und speichern. Ein Beispiel dazu findet sich im Tipp
12.2: Ausgewählte Basisfeatures in SQL und PL/SQL .
Das Directory mit Namen HOME ist vorhanden, wie wir zuerst überprüfen.
SQL> SELECT directory_name, directory_path FROM all_directories; DIRECTORY_NAME DIRECTORY_PATH --------------- ------------------------------------------------------------ LOBHOME /home/oracle/LOB TEST /home/oracle/test HOME /home/oracle ...
Nun wird eine hybrid partitioned Table EXT_EMP_DEPT_HYBRID_1 erzeugt. Sie ist LIST partitioniert nach der Spalte DEPTNO.
DROP TABLE scott.ext_emp_dept_hybrid_1; CREATE TABLE scott.ext_emp_dept_hybrid_1 ( "ENAME" varchar2(10), "DNAME" varchar2(14), DEPTNO number) EXTERNAL PARTITION ATTRIBUTES ( TYPE oracle_loader DEFAULT DIRECTORY home REJECT LIMIT UNLIMITED ) PARTITION BY LIST (deptno) ( PARTITION deptno_10 VALUES (10) , -- intern PARTITION deptno_20 VALUES (20) EXTERNAL LOCATION ('emp_dept_20.csv')) -- extern / -- Befüllen der internen Partition INSERT INTO "SCOTT".EXT_EMP_DEPT_HYBRID_1 SELECT e.ename, d.dname, d.deptno FROM scott.emp e JOIN scott.dept d ON d.deptno=e.deptno WHERE d.deptno=10; -- Das Resultat abfragen SQL> SELECT * FROM scott.ext_emp_dept_hybrid_1; ENAME DNAME DEPTNO ---------- -------------- ---------- CLARK ACCOUNTING 10 KING ACCOUNTING 10 MILLER ACCOUNTING 10 "SMITH" "RESEARCH" 20 "JONES" "RESEARCH" 20 "SCOTT" "RESEARCH" 20 "ADAMS" "RESEARCH" 20 "FORD" "RESEARCH" 20 8 rows selected.
Weitere Partitionen lassen sich dann mit dem ALTER TABLE Kommando wie folgt hinzufügen.
SQL> ALTER TABLE scott.ext_emp_dept_hybrid_1 ADD PARTITION deptno_30 VALUES (30) EXTERNAL DEFAULT DIRECTORY home LOCATION ('emp_dept_30.csv');
Das Ganze kann auch mit dem Treiber ORACLE_DATAPUMP verwendet werden. Dazu ist es zuerst notwendig die externen Dateien, die später als externe Partitionen verwendet werden sollen, mit einer Hilfstabelle zu erzeugen. Die Dateien haben in unserem Beispiel dann den Namen emp_dept_20.exp bzw. emp_dept_30.exp. Folgendes Beispiel erzeugt die Datei emp_dept_20.exp.
DROP TABLE ext_emp_dept_help; CREATE TABLE ext_emp_dept_help ORGANIZATION EXTERNAL ( TYPE oracle_datapump DEFAULT DIRECTORY home LOCATION ('emp_dept_20.exp') ) REJECT LIMIT UNLIMITED AS SELECT e.ename, d.dname, deptno FROM scott.dept d JOIN scott.emp e USING (deptno) WHERE deptno=20 / --DROP TABLE ext_emp_dept_help;
Danach wird die Datei emp_dept_30.exp nach dem gleichen Verfahren erstellt.
Nun sind wir in der Lage im nächsten Schritt die hybrid partitioned Tabelle anzulegen.
Die externe Partition DEPTNO_20_30 greift dann auf die externen Dateien emp_dept_20.exp und emp_dept_30.exp zu,
die wir vorher mit der Hilfstabelle erzeugt und im Directory HOME zur Verfügung gestellt haben.
drop table "scott.ext_emp_dept_hybrid_2; CREATE TABLE scott.ext_emp_dept_hybrid_2 ( "ENAME" varchar2(10) , "DNAME" varchar2(14), DEPTNO number) EXTERNAL PARTITION ATTRIBUTES ( TYPE oracle_datapump DEFAULT DIRECTORY home ) PARTITION BY LIST (deptno) ( PARTITION deptno_10 VALUES (10), -- intern PARTITION deptno_20_30 VALUES (20,30) EXTERNAL LOCATION ('emp_dept_20.exp','emp_dept_30.exp') -- extern ) /
Partitioned Tables in Hybrid Partitioned Tables umwandeln
In Szenario 2 wird eine list partitioned Table in eine hybrid partitioned Table umgewandelt. Wir verwenden dazu eine "normale" list partitioned Table mit der internen Partition DEPTNO_10.
DROP TABLE scott.ext_emp_dept_hybrid_3; CREATE TABLE scott.ext_emp_dept_hybrid_3 ( "ENAME" varchar2(10), "DNAME" varchar2(14), DEPTNO number) PARTITION BY LIST (deptno) ( PARTITION deptno_10 values (10)); -- Befüllen der Partition INSERT INTO scott.ext_emp_dept_hybrid_3 SELECT e.ename, d.dname, d.deptno FROM scott.emp e JOIN scott.dept d ON d.deptno=e.deptno WHERE d.deptno=10;
Um externe Partitionen einbinden zu können, muss zuerst die Klausel EXTERNAL PARTITION ATTRIBUTES hinzugefügt werden. Damit wird dann der Treiber (hier ORACLE_LOADER) und das Default Directory (hier HOME) bekanntgegeben.
ALTER TABLE scott.ext_emp_dept_hybrid_3 ADD EXTERNAL PARTITION ATTRIBUTES ( TYPE oracle_loader DEFAULT DIRECTORY home REJECT LIMIT UNLIMITED );
Im nächsten Schritt können dann externe Partitionen hinzugefügt werden. Hier wird die externe Partition DEPTNO_20_30 angefügt, die ihre Informationen aus den Dateien emp_dept_20.csv und emp_dept_30.csv erhält.
ALTER TABLE scott.ext_emp_dept_hybrid_3 ADD PARTITION deptno_20_30 VALUES (20,30) EXTERNAL LOCATION ('emp_dept_20.csv', 'emp_dept_30.csv');
Hybrid Partitioned Tables und Oracle Object Storage
In Autonomous Database mit der Version 19c können ebenfalls hybrid partitioned Tables verwendet werden. Wie im Falle von External Tables oder Partitioned External Tables wird dazu das Package DBMS_CLOUD verwendet. Ein Beispiel zum Anlegen einer External Table mit DBMS_CLOUD findet sich im Community Tipp Autonomous Database: External Tables. Im Fall von hybrid partitioned Tables sieht die Syntax dann folgendermassen aus:
DBMS_CLOUD.CREATE_HYBRID_PART_TABLE ( table_name IN VARCHAR2, credential_name IN VARCHAR2, partitioning_clause IN CLOB, column_list IN CLOB, field_list IN CLOB DEFAULT, format IN CLOB DEFAULT);
Im Handbuch "Using Oracle Autonomous Data Warehouse on Shared Exadata Infrastructure" im Appendix A "Autonomous Database
Supplied Package Reference" findet sich dazu die Beschreibung der einzelnen Argumente.
Im Szenario 3 liegen die externen Informationen im Oracle Object Storage in den Dateien emp_dept_20.csv und emp_dept_30.csv, die zu Beginn schon erzeugt worden sind.
Wie beim Laden von Daten mit Data Pump muss auch in diesem Fall gewährleistet sein, dass die Kommunikation mit der Autonomous Database abgesichert
ist und nur autorisierte Daten geladen werden. Dazu sind die Datenbank Credentials mit dem Package DBMS_CLOUD zuvor angelegt und als Default festgelegt worden.
Wir überprüfen die Datenbank Credentials. Falls noch nicht vohanden, werden sie mit ALTER DATABASE PROPERTY festgelegt.
SQL> SELECT credential_name, username, enabled, comments FROM dba_credentials; CREDENTIAL_NAME USERNAME ENABL COMMENTS -------------------- ---------------------------------------- ----- ---------------------------------------- CREDENTIAL_US1 oracleidentitycloudservice/ulrike.schwin TRUE {"comments":"Created via DBMS_CLOUD.crea n@oracle.com te_credential"} -- falls nicht enabled -- alter database property set default_credential = 'ADMIN.CREDENTIAL_US1'; -- falls nicht vorhanden, dann zuerst mit dbms_cloud.create_credential erzeugen
Das Vorhandensein der Dateien im Object Storage lässt sich vorab auch mit DBMS_CLOUD übeprüfen.
Hinweis: DBMS_CLOUD.CREATE_HYBRID_PART_TABLE unterstützt nicht nur Oracle Cloud Infrastructure Object Storage,
sondern auch Microsoft Azure und AWS S3.
SQL> SELECT object_name, bytes FROM dbms_cloud.list_objects('CREDENTIAL_US1','https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/USBUCKET/') WHERE object_name LIKE 'emp%'; OBJECT_NAME BYTES -------------------------------------------------- ---------- emp_dept_20.csv 114 emp_dept_20.exp 12288 emp_dept_30.csv 121 emp_dept_30.exp 12288
Wir erzeugen nun eine hybrid partitioned Table mit der Prozedur DBMS_CLOUD.CREATE_HYBRID_PART_TABLE. Für eine erfolgreiche Anwendung ist dabei die Angabe von Tabellenname, der Credential Name, das Argument FORMAT, das Argument COLUMN_LIST und die Klausel für die externen und internen Partitionen erforderlich. Zur Erinnerung: der Parameter FORMAT muss als ein JSON Objekt angegeben. Dazu gibt es zwei Möglichkeiten.
format => '{"format_option" : "format_value" }' oder format => json_object('format_option' value 'format_value'))
Folgendes Beispiel zeigt die Verwendung. Im Argument FORMAT können wir den Typ CSV nutzen.
DROP TABLE ext_emp_dept_hybrid_auto; BEGIN DBMS_CLOUD.CREATE_HYBRID_PART_TABLE( table_name => 'EXT_EMP_DEPT_HYBRID_AUTO', credential_name => 'CREDENTIAL_US1', format => json_object('type' VALUE 'CSV'), column_list => 'ename varchar2(10), dname varchar2(14), deptno number', partitioning_clause => 'partition by list (deptno) (partition deptno_30 values (30) external location ( ''https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/USBUCKET/o/emp_dept_30.csv''), --extern partition deptno_20 values (20) external location ( ''https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/USBUCKET/o/emp_dept_20.csv''), --extern partition deptno_10 values (10) --intern )' ); END; /
Um sicher zu gehen, dass der Zugriff mit External Table erfolgreich sein wird, empfiehlt es sich vorab mit VALIDATE_EXTERNAL_TABLE eine Prüfung durchzuführen. Gibt es eine Fehlermeldung, sollte man noch einmal das Setup prüfen. In folgendem Beispiel ist offensichtlich die URI nicht korrekt. Die Fehlermeldung gibt dabei den richtigen Hinweis darauf.
execute DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE (table_name => 'EXT_EMP_DEPT_HYBRID_AUTO'); Error starting at line : 24 in command - BEGIN DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE (table_name => 'EXT_EMP_DEPT_HYBRID_AUTO'); END; Error report - ORA-20011: Invalid object uri - https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/USBUCKET/emp_dept_30.csv ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 844 ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 1105 ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 1389 ORA-06512: at line 1
Ist das Problem behoben, kann man erfolgreich auf die Daten zugreifen.
SQL> SELECT * FROM ext_emp_dept_hybrid_auto; ENAME DNAME DEPTNO ---------- -------------- ---------- ALLEN SALES 30 WARD SALES 30 MARTIN SALES 30 BLAKE SALES 30 TURNER SALES 30 JAMES SALES 30 SMITH RESEARCH 20 JONES RESEARCH 20 SCOTT RESEARCH 20 ADAMS RESEARCH 20 FORD RESEARCH 20 11 rows selected.
Möchte man den Treiber ORACLE_DATAPUMP verwenden, muss im Argument FORMAT der Treiber mit der Konstante DBMS_CLOUD.FORMAT_TYPE_DATAPUMP verwendet werden. Die beiden externen Dateien emp_dept_30.exp und emp_dept_20.exp aus dem ersten Beispiel sind dazu vorab in den Object Storage geladen worden.
DROP TABLE ext_emp_dept_hybrid_dp; BEGIN DBMS_CLOUD.CREATE_HYBRID_PART_TABLE ( table_name => 'EXT_EMP_DEPT_HYBRID_DP', credential_name => 'CREDENTIAL_US1', format => json_object('type' VALUE DBMS_CLOUD.FORMAT_TYPE_DATAPUMP), column_list => 'ename varchar2(10), dname varchar2(14), deptno number', partitioning_clause => 'partition by list (deptno) (partition deptno_30 values (30) external location ( ''https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/USBUCKET/o/emp_dept_30.exp''), partition deptno_20 values (20) external location ( ''https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/USBUCKET/o/emp_dept_20.exp''), partition deptno_10 values (10) )' ); END; /
Nach erfolgreicher Validierung, kann man auch hier wie gewohnt auf die Informationen mit SQL Kommandos zugreifen.
SQL> execute DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE (table_name => 'EXT_EMP_DEPT_HYBRID_AUTO_DP'); PL/SQL procedure successfully completed.
Monitoring
Möchte man herausfinden, ob eine Tabelle hybrid partitioned ist, kann man dazu im Data Dictionary nachsehen. External Tables - egal ob hybrid oder nicht - lassen sich generell mit der View USER/ALL/DBA_EXTERNAL_TABLES auflisten.
SQL> SELECT table_name, owner, type_name FROM all_external_tables; TABLE_NAME OWNER TYPE_NAME ------------------------------ ---------- -------------------- OPATCH_XML_INV SYS ORACLE_LOADER EXT_EMP_DEPT_HYBRID_LIST SCOTT ORACLE_DATAPUMP EXT_EMP_DEPT_HYBRID_3 SCOTT ORACLE_LOADER EXT_EMP_DEPT_HYBRID_2 SCOTT ORACLE_LOADER EXT_EMP_DEPT_HYBRID_RANGE SCOTT ORACLE_DATAPUMP EXT_EMP_DEPT_HYBRID_2 SCOTT ORACLE_DATAPUMP EXT_EMP_DEPT_HYBRID_1 SCOTT ORACLE_LOADER ORDERS_H OT ORACLE_LOADER HYPT_TO_INT_TABLE US ORACLE_LOADER EXT_EMP_DEPT_HELP US ORACLE_DATAPUMP 9 rows selected.
Sucht man speziell nach der Eigenschaft "hybrid", sollte man die View USER/ALL/DBA_TABLES mit der neuen Spalte HYBRID verwenden.
SQL> SELECT table_name, owner, hybrid FROM all_tables where hybrid='YES'; TABLE_NAME OWNER HYB ------------------------------ ---------- --- EXT_EMP_DEPT_HYBRID_RANGE SCOTT YES EXT_EMP_DEPT_HYBRID_2 SCOTT YES EXT_EMP_DEPT_HYBRID_LIST SCOTT YES EXT_EMP_DEPT_HYBRID_1 SCOTT YES EXT_EMP_DEPT_HYBRID_2 SCOTT YES EXT_EMP_DEPT_HYBRID_3 SCOTT YES ORDERS_H OT YES HYPT_TO_INT_TABLE US YES 8 rows selected.
Hybrid partitioned Tables werden natürlich auch in den Views, die mit external partitioned Tables eingeführt wurden, gelistet wie zum Beispiel:
Folgende Abfrage mit USER_XTERNAL_PART_TABLES listet alle partitionierten external Tables auf.
SQL> SELECT table_name, type_name, default_directory_name Directory, reject_limit, access_parameters FROM user_xternal_part_tables; TABLE_NAME TYPE_NAME DIRECTORY ------------------------------ -------------------- -------------------- REJECT_LIMIT ---------------------------------------- ACCESS_PARAMETERS -------------------------------------------------------------------------------- HYPT_TO_INT_TABLE ORACLE_LOADER HOME UNLIMITED FIELDS TERMINATED BY ',' (prod_id,cust_id,time_id DATE 'dd-mm-yyyy',chan ...
Fazit
Ab Oracle Database 19c gibt es die Möglichkeit partitionierte Tabellen mit Partitionen auszustatten, deren Daten innerhalb und ausserhalb der Datenbank liegen. So kann Speicherplatz für Daten nicht nur in der Datenbank selbst sondern auch außerhalb verwendet werden. Die Daten können dabei als Dateien im Dateisystem, im Hadoop Distributed File System (HDFS) oder wie im Fall vom Autonomous Database auch im Cloud Object Storage liegen. Ein aktuelles Beispiel liefert CERN, die damit die Möglichkeit nutzten 1 PB Daten mit Oracle Autonomous Database zu nutzen. Wer mehr dazu erfahren möchte, kann sich den Webcast Oracle Global Leaders Webcast: Managing 1 PB of data with Oracle Autonomous DW ansehen.
Weitere Informationen und Artikel zum Thema External Tables
Folgende Links listen unsere Blogeinträge zum Thema External Tables, die wir über die Jahre veröffentlicht haben - angefangen von den Grundlagen zu External Tables bis zum aktuellen Tipp in 19c.
Handbucheinträge
Zurück zur Community-Seite