Spark SQL 表的命名方式是db_name.table_name,只有資料庫名稱和資料表名稱。如果沒有指定db_name而直接引用table_name,實際上是引用default 資料庫下的表。在Spark SQL中,資料庫只是指定表檔案儲存的路徑,每個表都可以使用不同的檔案格式來儲存資料,從這個角度來看,可以把database看作是Databricks 表的上層目錄,用於組織資料表及其檔案。
在python語言環境中,可以使用 %sql 切換到SQL命令模式:
%sql
一,管理資料庫
常用的資料庫命令,切換當前的資料庫、顯示資料庫列表、表列表、檢視列表和列資訊:
use db_name show databases show tables [in db_name] show views [in db_name] show columns in db_name.table_name
1,建立資料庫
建立資料庫,通過LOCATION 指定資料庫檔案儲存的位置:
CREATE { DATABASE | SCHEMA } [ IF NOT EXISTS ] database_name [ LOCATION database_directory ]
LOCATION database_directory:指定儲存資料庫檔案系統的路徑,如果底層的檔案系統中不存在該路徑,那麼需要先建立該目錄。如果未指定LOCATION引數,那麼使用預設的資料倉儲目錄來建立資料庫,預設的資料倉儲目錄是由靜態配置引數spark.sql.warehouse.dir指定的。
2,檢視資料庫的描述
{ DESC | DESCRIBE } DATABASE [ EXTENDED ] db_name
extended 選項表示檢視資料庫的擴充套件屬性。
3,刪除資料庫
DROP { DATABASE | SCHEMA } [ IF EXISTS ] dbname [ RESTRICT | CASCADE ]
IF EXISTS:該選項表示在資料庫不存在時,DROP操作不會引發異常。
RESTRICT:該選項表示不能刪除非空資料庫,並在預設情況下啟用。
CASCADE:該選項表示刪除資料庫中所有關聯的表和函式。
二,建立資料表
表有兩種作用域:全域性和本地,全域性表可以在所有的Cluster中引用,而本地表只能在本地的Cluster中引用,被稱作臨時檢視。使用者可以從DBFS中的檔案或儲存在任何受支援資料來源中的資料來填充表。
在建立表時,需要指定儲存表資料的檔案格式,以及表資料檔案儲存的位置。
1,使用資料來源建立表(標準的CREATE TABLE命令)
建立表的語法,注意:如果資料庫中已存在同名的表,則會引發異常。
CREATE TABLE [ IF NOT EXISTS ] [db_name].table_name [ ( col_name1 col_type1, ... ) ] USING data_source [ OPTIONS ( key1=val1, key2=val2, ... ) ] [ PARTITIONED BY ( col_name1, col_name2, ... ) ] [ CLUSTERED BY ( col_name3, col_name4, ... ) [ SORTED BY ( col_name [ ASC | DESC ], ... ) ] INTO num_buckets BUCKETS ] [ LOCATION path ] [ AS select_statement ]
引數註釋:
- IF NOT EXISTS:如果資料庫中已存在同名的表,則不會執行任何操作。
- USING data_source:用於表的檔案格式,data_source 必須是 TEXT、CSV、JSON、JDBC、PARQUET、ORC、HIVE、DELTA 或 LIBSVM 中的一個,或 org.apache.spark.sql.sources.DataSourceRegister 的自定義實現的完全限定的類名。支援使用 HIVE 建立 Hive SerDe 表。 你可以使用 OPTIONS 子句指定 Hive 特定的 file_format 和 row_format,這是不區分大小寫的字串對映。選項鍵為 FILEFORMAT、INPUTFORMAT、OUTPUTFORMAT、SERDE、FIELDDELIM、ESCAPEDELIM、MAPKEYDELIM 和 LINEDELIM。
- OPTIONS:用於優化表的行為或配置 HIVE 表的表選項。
- PARTITIONED BY (col_name1, col_name2, ...):按指定的列對建立的表進行分割槽,將為每個分割槽建立一個目錄。
- CLUSTERED BY col_name3, col_name4, ...):按照指定的列,把表中的分割槽分割到固定數目的 Bucket中,該選項通常與分割槽操作配合使用。delta格式的檔案不支援該子句。
- SORTED BY:資料在buckets中的排序方式,預設是升序ASC。
- INTO num_buckets BUCKETS:bucket是一個優化技術,使用bucket(和bucket 列)來確定資料的分割槽,並避免資料洗牌(data shuffle),使資料變得有序。
- LOCATION path:用於儲存表資料的目錄,可以指定分散式儲存上的路徑。
- AS select_statement:使用來自 SELECT 語句的輸出資料填充該表。
2,使用Delta Lake(增量Lake)建立表
使用者可以使用標準的CREATE TABLE命令來建立儲存在delta lake中的表,除了標準的建立delta table的命令之外,還可以使用以下的語法來建立delta表:
CREATE [OR REPLACE] TABLE table_identifier[(col_name1 col_type1 [NOT NULL], ...)] USING DELTA [LOCATION <path-to-delta-files>]
table_identifier 有兩種格式:
[database_name.] table_name
: 表的名稱delta.`delta_file_path`
LOCATION <path-to-delta-files> :如果指定的 LOCATION 已包含增量 lake 中儲存的資料,Delta lake 會執行以下操作:
如果僅指定了表名稱和位置,例如:
CREATE TABLE events USING DELTA LOCATION '/mnt/delta/events'
Hive 元儲存中的表會自動繼承現有資料的架構、分割槽和表屬性,此功能可用於把資料“匯入”到元儲存(metastore)中。
如果你指定了任何配置(架構、分割槽或表屬性),那麼 Delta Lake 會驗證指定的內容是否與現有資料的配置完全匹配。如果指定的配置與資料的配置並非完全匹配,則 Delta Lake 會引發一個描述差異的異常。
3,建立表的示例
--Use data source CREATE TABLE student (id INT, name STRING, age INT) USING PARQUET; --Use data from another table CREATE TABLE student_copy USING PARQUET AS SELECT * FROM student; --Omit the USING clause, which uses the default data source (parquet by default) CREATE TABLE student (id INT, name STRING, age INT);
--Create partitioned and bucketed table CREATE TABLE student (id INT, name STRING, age INT) USING PARQUET PARTITIONED BY (age) CLUSTERED BY (Id) INTO 4 buckets;
三,和資料來源的互動
資料來源表的作用類似於指向基礎資料來源的指標,例如,您可以使用JDBC資料來源在Azure Databricks中建立表foo,該表指向MySQL中的表bar。當讀寫表foo時,實際上就是讀寫表bar。
通常,CREATE TABLE會建立一個“指標”,並且必須確保它指向的物件是存在的,一個例外是檔案源,例如Parquet,JSON,如果您未指定LOCATION選項,那麼Azure Databricks會建立一個預設表位置。
對於CREATE TABLE AS SELECT,Azure Databricks使用select查詢的輸出資料來覆蓋(overwrite)底層的資料來源,以確保建立的表包含與輸入查詢完全相同的資料。
四,向表插入資料
使用者可以向表種插入資料,也可以向Spark支援的檔案中插入資料。
1,向表中插入資料
使用INSERT INTO 命令向表中追加資料,不會影響表中的現有資料;使用INSERT OVERWRITE 命令,會覆蓋表中的現有資料。
INSERT INTO [ TABLE ] table_identifier [ partition_spec ] { VALUES ( { value | NULL } [ , ... ] ) [ , ( ... ) ] | query } INSERT OVERWRITE [ TABLE ] table_identifier [ partition_spec [ IF NOT EXISTS ] ] { VALUES ( { value | NULL } [ , ... ] ) [ , ( ... ) ] | query }
引數註釋:
- table_identifier:[database_name.] table_name:表名稱,可選擇使用資料庫名稱進行限定。delta.<路徑到表> :現有增量表的位置。
- partition_spec:一個可選引數,用於指定分割槽的鍵/值對的逗號分隔列表。語法:PARTITION ( partition_col_name = partition_col_val [ , ... ] )
- 值 ( {value |NULL} [,...] ) [, ( ... ) ]:要插入的值。 顯式指定的值或 NULL 。 使用逗號分隔子句中的每個值。 您可以指定多個值集來插入多個行。
- query:生成要插入的行的查詢,可用的查詢格式:SELECT語句、TABLE語句、FROM語句
舉個例子,建立表之後,通過VALUES子句向表中插入少量的值,也可以通過 SELECT 子句、TABLE和FROM向表中批量插入資料。
CREATE TABLE students (name VARCHAR(64), address VARCHAR(64), student_id INT) USING PARQUET PARTITIONED BY (student_id); -- VALUES INSERT INTO students VALUES ('Bob Brown', '456 Taylor St, Cupertino', 222222), ('Cathy Johnson', '789 Race Ave, Palo Alto', 333333); -- SELECT INSERT INTO students PARTITION (student_id = 444444) SELECT name, address FROM persons WHERE name = "Dora Williams"; -- TABLE INSERT INTO students TABLE visiting_students; -- FROM INSERT INTO students FROM applicants SELECT name, address, id applicants WHERE qualified = true;
2,向檔案中插入資料
使用給定的Spark檔案格式用新值覆蓋目錄中的現有資料,也就是說,向目錄中插入資料時,只能用新資料覆蓋現有的資料:
INSERT OVERWRITE [ LOCAL ] DIRECTORY [ directory_path ] USING file_format [ OPTIONS ( key = val [ , ... ] ) ] { VALUES ( { value | NULL } [ , ... ] ) [ , ( ... ) ] | query }
引數註釋:
- directory_path:目標目錄,還可以使用在中指定 OPTIONS path 。 LOCAL關鍵字用於指定目錄位於本地檔案系統中。
- file_format:要用於插入的檔案格式。 有效選項包括 TEXT 、 CSV 、 JSON 、 JDBC 、 PARQUET 、ORC、HIVE、LIBSVM,或者自定義實現的完全限定類名 org.apache.spark.sql.execution.datasources.FileFormat 。
- OPTIONS ( key = val [,...] ):指定用於寫入檔案格式的一個或多個選項。
示例,使用新資料覆蓋目錄中的資料:
INSERT OVERWRITE DIRECTORY '/tmp/destination' USING parquet OPTIONS (col1 1, col2 2, col3 'test') SELECT * FROM test_table; INSERT OVERWRITE DIRECTORY USING parquet OPTIONS ('path' '/tmp/destination', col1 1, col2 2, col3 'test') SELECT * FROM test_table;
參考文件: