Purpose
This statement is used to create an external table in a database.
The data of an external table is stored in an external storage service (such as the local file system, object storage, HDFS, or MaxCompute). OceanBase Database stores the table definition and access path. An external table is a read-only object that can be used for queries. It does not support DML operations, nor does it support defining constraints or creating indexes.
Privilege requirements
To execute
CREATE EXTERNAL TABLE, the current user must have theCREATEprivilege. For more information, see Privilege types in MySQL-compatible mode.When creating an external table by referencing a Location object, you must have the
READprivilege on that Location.GRANT READ ON LOCATION test_location_local TO user001 WITH GRANT OPTION;
Version information
Feature/Parameter |
Supported Versions |
|---|---|
| Read from HDFS external table | V4.3.5 BP1 and later |
IGNORE_LAST_EMPTY_COLUMN |
V4.3.5 BP2 and later |
API_MODE、SPLIT(ODPS external table) |
V4.3.5 BP3 and later |
Syntax
CREATE EXTERNAL TABLE table_name (column_definition [, column_definition ...])
LOCATION = 'file_name'
{FORMAT = (format_type_options)
| PROPERTIES = (properties_type_options)}
[PARTITION BY (column_name [, column_name ...])]
[PARTITION_TYPE = USER_SPECIFIED]
[PATTERN = 'regex_pattern']
[AUTO_REFRESH = 'xxx'];
column_definition:
column_name column_type [AS expr]
format_type_options:
type_csv_option
| type_parquet_option
| type_orc_option
type_csv_option:
TYPE = 'CSV'
LINE_DELIMITER = '<string>' | <expr>
FIELD_DELIMITER = '<string>' | <expr>
ESCAPE = '<character>' | <expr>
FIELD_OPTIONALLY_ENCLOSED_BY = '<character>' | <expr>
ENCODING = 'charset'
NULL_IF = ('<string>' | <expr>, '<string>' | <expr> ...)
SKIP_HEADER = <int>
SKIP_BLANK_LINES = {TRUE | FALSE}
TRIM_SPACE = {TRUE | FALSE}
EMPTY_FIELD_AS_NULL = {TRUE | FALSE}
IGNORE_LAST_EMPTY_COLUMN = {TRUE | FALSE}
type_parquet_option:
TYPE = 'PARQUET'
type_orc_option:
TYPE = 'ORC'
properties_type_options:
type_odps_option
type_odps_option:
TYPE = 'ODPS'
ACCESSID = '<string>'
ACCESSKEY = '<string>'
ENDPOINT = '<string>',
PROJECT_NAME = '<string>',
SCHEMA_NAME = '<string>',
TABLE_NAME = '<string>',
QUOTA_NAME = '<string>',
COMPRESSION_CODE = '<string>',
API_MODE = {"tunnel_api" | "storage_api"},
SPLIT = {"byte" | "row"}
Usage
When creating an external table, you need to specify LOCATION and choose either FORMAT or PROPERTIES based on the external table type (the two are mutually exclusive and cannot be used together):
clause |
Applicable External Table Types |
Description |
|---|---|---|
FORMAT = (...) |
File-based external tables (CSV, PARQUET, and ORC) | Specify External File Format and Parsing Options |
PROPERTIES = (...) |
ODPS External Table | Specify the MaxCompute connection parameter and API mode. This option is not for file formats. |
Other common clauses:
clause |
Description |
|---|---|
LOCATION |
External data paths (local, OSS/S3, HDFS, etc.).. |
PATTERN |
Regular expression, filter.LOCATIONThe files in the specified directory. If not specified, all files in the directory are accessed. The matching results are written to the system table during creation, and access is performed according to this list during scanning. |
AUTO_REFRESH |
Foreign table metadata refresh strategy:OFF(Default),INTERVAL、IMMEDIATE. |
PARTITION_TYPE = USER_SPECIFIED |
Used for manual partition management. |
AS expr / metadata$filecol{N} |
Manual column mapping. Once specified, you must define a mapping for all columns; automatic sequential mapping will then be invalid. |
Parameters
Parameter |
Description |
|---|---|
| table_name | The name of the external table. |
| column_name | Column name. By default, file columns and external table columns correspond one by one in the order they are defined. |
| column_type | Column type; cannot be defined.DEFAULT、NOT NULL、UNIQUE、CHECK、PRIMARY KEY、FOREIGN KEYconstraints. |
| AS expr | Manual column mapping. Throughmetadata$filecol{N}Specifies that the external table column corresponds to the Nth column in the file (where N starts from 1). For example,c2 INT AS (metadata$filecol4). Note that if manual column mapping is specified, the automatic mapping relationship will be invalid, and all columns must be manually mapped. |
| LOCATION | The data path of the external table, which typically points to a separate directory. When creating the external table, files in this directory (including subdirectories) are collected. For more information about creating a LOCATION object, see CREATE LOCATION. |
| FORMAT | File external table format options. For more information, see format_type_options. |
| PROPERTIES | Options for connecting to an ODPS external table. For more information, see properties_type_options. |
| PATTERN | Specify a regular expression pattern string to filter.LOCATIONfiles in the directory. For eachLOCATIONThe file path in the directory. If a file path matches this pattern string, the external table accesses the file; otherwise, it skips the file. If this parameter is not specified, the default access permission is granted.LOCATIONAll files in the directory. External tables willLOCATIONFiles under the specified path that meet the criteria ofPATTERNThe file list is stored in a database system table. During external table scanning, this list is used to access external files. |
| PARTITION_TYPE | Set toUSER_SPECIFIEDThe user manually adds or drops partitions. |
| AUTO_REFRESH | Used for automatic refresh of external tables. Valid values:
|
Supported path formats for LOCATION
Local path
When the file is local, the local
LOCATIONformat is:LOCATION = '[file:// | sfile://] local_file_path'file://: This protocol header indicates that when encountering files with the same logical path across multiple OBServer nodes, they are treated as different files and processed separately. Each node independently reads the file from its local path.sfile://: This protocol header indicates that when encountering files with the same logical path across multiple OBServer nodes, the system deduplicates them based on the logical path to ensure only one copy of the data is read (supports multi-server load balancing).Note
- When using
sfile://, the system performs consistency verification of file sizes. If files under the same logical path have inconsistent sizes across different OBServer nodes, the system reports theOB_INVALID_EXTERNAL_FILEerror to avoid result errors caused by data inconsistency. - For version V4.4.2, starting from V4.4.2 BP2, the
sfile://protocol header is supported in the local Location format of theCREATE EXTERNAL TABLEsyntax.
- When using
local_file_path: Can be a relative path or an absolute path. If a relative path is provided, the current directory must be the installation directory of OceanBase Database.secure_file_privis used to configure the file paths that OBServer nodes are authorized to access.local_file_pathcan only be a subpath of thesecure_file_privpath.
Object storage (OSS / S3)
LOCATION = '{oss|s3}://$ACCESS_ID:$ACCESS_KEY@$HOST:s3_region/remote_file_path'
$ACCESS_ID,$ACCESS_KEY, and$HOSTare the access information required to access Alibaba Cloud OSS, AWS S3, and object storage compatible with the S3 protocol.s3_region: The S3 region. The credentials are stored in an encrypted format in the system table.
Notice
In an object storage URL, parameters are separated by &. Parameter values can only contain English letters, numbers, /-_$+=, and wildcard characters. Otherwise, the setting may fail.
HDFS Path
Single NameNode:
LOCATION = 'hdfs://host:port/path'
Hadoop HA (logical nameservice):
LOCATION = 'hdfs://nameserviceID/path'
The client OBServer side must include the nameservice definition and failover strategy for the HA cluster.
Kerberos authentication:
Append query parameters to the URL: ?principal=...&keytab=...&krb5conf=...&configs=...
URL parameters |
Description |
|---|---|
| principal | The Kerberos login principal refers to the user undergoing authentication. |
| keytab | Key File Path |
| krb5conf | Path to the Kerberos configuration file (for example,/etc/krb5.conf) |
| configs | Additional HDFS configuration. The default value is empty. Multiple items are separated with#Separation. The Kerberos environment typically requires settingdfs.data.transfer.protection; In a high-availability environment, you also need to configure parameters such as nameservice, namenode address, and failover. |
In a HA + Kerberos environment, common configs parameters (multiple parameters are separated by #):
Parameter |
Description |
|---|---|
dfs.data.transfer.protection |
Data transmission protection level, which must be consistent with the cluster configuration. |
dfs.nameservices |
HA Cluster Nameservice ID |
dfs.ha.namenodes.{nameservice} |
List of Standby IDs for the NameNode |
dfs.namenode.rpc-address.{nameservice}.{nn} |
RPC Address of Each NameNode |
dfs.ha.automatic-failover.enabled.{nameservice} |
Whether to enable automatic failover |
dfs.client.failover.proxy.provider.{nameservice} |
The failover proxy class, typicallyConfiguredFailoverProxyProvider |
The example format is as follows:
dfs.data.transfer.protection=integrity#dfs.nameservices=mycluster#dfs.ha.namenodes.mycluster=nn1,nn2#...
Notice
HA-related parameters are bound to nameservice and must be consistent with the cluster's hdfs-site.xml. For a complete example of HA configuration, see Example 3 below and the Location configuration instructions in Load a Hive table through Catalog.
Note
Before accessing an HDFS external table, you must deploy the Java/JNI/HDFS environment on the OBServer node and configure cluster parameters such as ob_enable_java_env. For more information, see Deploy the OceanBase Java SDK environment.
File format and attribute description (format_type_options)
CSV format parameters (Type = 'CSV')
Parameter |
Description |
Default Value/Value Range |
|---|---|---|
LINE_DELIMITER |
Row delimiter | \n |
FIELD_DELIMITER |
Column delimiter | \t |
ESCAPE |
Escape character (1 byte) | \ |
FIELD_OPTIONALLY_ENCLOSED_BY |
field wrapper | empty |
ENCODING |
Character Set | UTF8MB4 |
NULL_IF |
Strings treated as NULL | empty |
SKIP_HEADER |
Number of Lines to Skip in the File Header | — |
SKIP_BLANK_LINES |
Whether to skip empty lines | FALSE |
TRIM_SPACE |
Trim leading and trailing spaces of fields | FALSE |
EMPTY_FIELD_AS_NULL |
Whether an empty string is considered NULL | FALSE |
IGNORE_LAST_EMPTY_COLUMN |
Whether to ignore trailing empty columns | TRUE |
COMPRESSION |
Optional. Specifies the file compression format. | Valid values:
|
Note
For V4.3.5, IGNORE_LAST_EMPTY_COLUMN is supported starting from V4.3.5 BP2.
format_type_options
TYPE = 'CSV'
The default values for each parameter are shown in the table above. The following are the constraints and considerations:
ESCAPE: Specifies the escape character for the CSV file, which must be 1 byte. Default value isESCAPE ='\'.ENCODING: Supported character sets are listed in Character sets. Default is UTF8MB4.FIELD_OPTIONALLY_ENCLOSED_BY: When the file containsNULLvalues (not the string"NULL"), this parameter must be explicitly configured and cannot be empty.Notice
When an external table data file contains
NULLvalues (not the string NULL, i.e., not "NULL"), theFIELD_OPTIONALLY_ENCLOSED_BYparameter must be explicitly configured and its value cannot be empty.
TYPE = 'PARQUET'
Specifies the external file format as Parquet.
TYPE = 'ORC'
Specifies the external file format as ORC.
properties_type_options
TYPE = 'ODPS'
Used to create a MaxCompute (ODPS) external table, accessing a remote table via API (not a file path external table).
Parameter |
Description |
|---|---|
| ACCESSID | Alibaba Cloud AccessKey ID, used for identity authentication. |
| ACCESSKEY | Specifies the AccessKey secret corresponding to the AccessKey ID for authentication. |
| ENDPOINT | ODPS service connection address |
| PROJECT_NAME | ODPS Project Name |
| SCHEMA_NAME | Optional. The name of the ODPS schema. |
| TABLE_NAME | ODPS Table Name |
| QUOTA_NAME | Optional. The quota name. |
| COMPRESSION_CODE | Optional. Compression format:ZLIB、ZSTD、LZ4、ODPS_LZ4; If not specified, compression is disabled. |
| API_MODE | API mode:tunnel_api(Default) orstorage_api. |
| SPLIT | Usestorage_apiSharding method during:byteorrow. |
API_MODE: Specifies the API mode for calling ODPS. Valid values:
Note
For OceanBase Database V4.3.5, API_MODE and SPLIT parameters are supported starting from V4.3.5 BP3.
tunnel_api(default):No special network configuration required: Suitable for all deployment scenarios, as OceanBase Database and MaxCompute do not need to reside in the same Virtual Private Cloud (VPC).
No additional MaxCompute permissions required: Authentication can be completed with only the AccessID and AccessKey; there is no need to enable MaxCompute Storage API permissions.
Applicable environments:
- OceanBase Database and MaxCompute are not deployed in the same VPC.
- The MaxCompute Storage API is not enabled.
- Low latency requirements for data transmission.
storage_api:Network dependency: OceanBase Database and MaxCompute must be deployed in the same VPC to achieve low-latency, high-throughput data transmission.
Permission dependency: You must enable the Storage API permission in MaxCompute and ensure that the AccessKey has the corresponding permissions.
Applicable environments:
- OceanBase Database and MaxCompute are in the same VPC.
- The MaxCompute Storage API is enabled.
- The data volume is extremely large or real-time requirements are high.
SPLIT: When usingstorage_api, specifies whether to split tasks bybyteorrowfor allocation to threads. Set this parameter tobytewhen the byte size of data in rows of a table varies greatly, and set it torowin other cases.
For details on scenario implementation and partition mapping, see ODPS external tables.
Usage instructions
- External tables are read-only objects and do not support DML, constraints, or indexes.
- The file list is collected based on the
LOCATIONandPATTERNparameters during creation. To add files to the directory, you must executeALTER EXTERNAL TABLE ... REFRESH. For more information, see Update the file list of an external table. - For more information about external file deletion, modification, concurrent access,
secure_file_priv, and HDFS/ODPS environments, see About external tables and external files and Manage external files. - When you do not need to persist table objects and only temporarily read from external files, you can use the FILES table function.
Examples
Example 1: Local CSV external table
Prepare the data. First, set the path of
secure_file_privto/home/admin/. Place the CSV fileextdata.csvcorresponding to the external table data to be imported in the/home/admin/testdirectory of the current local connection OBServer node.The following example shows how to set the global security path.
obclient> SET GLOBAL secure_file_priv = "/home/admin/"; Query OK, 0 rows affected obclinet> \q ByeNote
Because
secure_file_privis aGLOBALvariable, you must execute\qto exit and make it effective.The content of the CSV file is as follows:
1,'Dave','Smith','dsmith@outlook.com','friend',32 2,'Xena','Johnson','xjonson@outlook.com','contact',45 3,'Fred','Jackon','fjackson@outlook.com','co-worker',19 4,'Alma','Tyler','atyler@outlook.com','friend',53After logging in to the database as a user tenant, create an external table named
contacts.obclient> CREATE EXTERNAL TABLE contacts ( id INT, firstname VARCHAR(100), lastname VARCHAR(100), email VARCHAR(255), category CHAR(30), age NUMBER ) LOCATION = '/home/admin/test' FORMAT = ( TYPE = 'CSV' FIELD_DELIMITER = ',' FIELD_OPTIONALLY_ENCLOSED_BY ='\'' ) PATTERN = 'extdata.csv';Query data from the external table
contacts.obclient> SELECT * FROM contacts; +----+-----------+----------+----------------------+-----------+------+ | id | firstname | lastname | email | category | age | +----+-----------+----------+----------------------+-----------+------+ | 1 | Dave | Smith | dsmith@outlook.com | friend | 32 | | 2 | Xena | Johnson | xjonson@outlook.com | contact | 45 | | 3 | Fred | Jackon | fjackson@outlook.com | co-worker | 19 | | 4 | Alma | Tyler | atyler@outlook.com | friend | 53 | +----+-----------+----------+----------------------+-----------+------+ 4 rows in set
Example 2: HDFS CSV external table (without Kerberos)
Prerequisite: You have completed Java SDK environment deployment, which is required when accessing HDFS.
CREATE EXTERNAL TABLE test_tbl1_csv_mysql (
id INT,
name VARCHAR(50),
c_date DATE
)
LOCATION = 'hdfs://${hadoop_namenode_host}:${hadoop_namenode_port}/user'
FORMAT = (
TYPE = 'CSV'
FIELD_DELIMITER = ','
FIELD_OPTIONALLY_ENCLOSED_BY = '\''
)
PATTERN = 'test_tbl1.csv';
SELECT * FROM test_tbl1_csv_mysql;
Notice
Replace ${hadoop_namenode_host} and ${hadoop_namenode_port} with the actual HDFS NameNode address and port.
Example 3: HDFS HA + Kerberos
Prerequisites:
- You have completed the Java SDK environment deployment.
- The Kerberos credential files, such as the keytab and krb5.conf files, have been deployed on all OBServer nodes.
- The HA parameters in
configsare consistent with the cluster'snameserviceconfiguration.
CREATE EXTERNAL TABLE test_ha (
id INT,
r_name VARCHAR(100),
age INT
)
LOCATION = 'hdfs://mycluster/hadoop_ha_test?principal=ha/xxx@xxx.com&keytab=/path/to/ha.keytab&krb5conf=/path/to/krb5conf_file&configs=dfs.data.transfer.protection=integrity#dfs.nameservices=mycluster#dfs.ha.namenodes.mycluster=nn1,nn2#dfs.namenode.rpc-address.mycluster.nn1=localhost1:port#dfs.namenode.rpc-address.mycluster.nn2=localhost2:port#dfs.ha.automatic-failover.enabled.mycluster=true#dfs.client.failover.proxy.provider.mycluster=org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider'
FORMAT = (
TYPE = 'CSV'
FIELD_DELIMITER = ','
FIELD_OPTIONALLY_ENCLOSED_BY = '\''
)
PATTERN = 'test_simple.csv';
SELECT * FROM test_ha;
Example 4: HDFS Kerberos single-node
The prerequisites are the same as those in Example 3. In a single-NameNode environment, LOCATION can be simplified to:
CREATE EXTERNAL TABLE partsupp (
PS_PARTKEY INTEGER,
PS_SUPPKEY INTEGER,
PS_AVAILQTY INTEGER,
PS_SUPPLYCOST DECIMAL(15,2),
PS_COMMENT VARCHAR(199)
)
LOCATION = 'hdfs://localhost:8020/tpch_csv?principal=principal_str&keytab=/path/to/keytab&krb5conf=/path/to/krb5conf_file&configs=xxx=xxx#xxx=xxx'
FORMAT = (
TYPE = 'CSV'
FIELD_DELIMITER = '|'
FIELD_OPTIONALLY_ENCLOSED_BY = '"'
)
PATTERN = 'partsupp.tbl';
