支援的資料類型 - Amazon Redshift

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

支援的資料類型

Spark 連接器支援 Amazon Redshift 中的下列資料類型。如需 Amazon Redshift 中支援的資料類型完整清單,請參閱資料類型。如果資料類型不在下表中,則表示 Spark 連接器不支援該資料類型。

資料類型 別名
SMALLINT INT2
INTEGER INT、INT4
BIGINT INT8
DECIMAL NUMERIC
REAL FLOAT4
DOUBLE PRECISION FLOAT8、FLOAT
BOOLEAN BOOL
CHAR CHARACTER、NCHAR、BPCHAR
VARCHAR CHARACTER VARYING、NVARCHAR、TEXT
DATE
TIMESTAMP 不含時區的時間戳記
TIMESTAMPTZ 含時區的時間戳記
SUPER
TIME 不含時區的時間
TIMETZ 含時區的時間
VARBYTE VARBINARY、BINARY VARYING

複雜資料類型

您可以使用 Spark 連接器在 Redshift SUPER 資料類型資料欄中讀取和寫入 Spark 複雜資料類型 (例如 ArrayTypeMapTypeStructType)。如果您在讀取操作期間提供結構描述,資料欄中的資料會轉換為其在 Spark 中對應的複雜類型,包括任何巢狀類型。此外,如果已啟用 autopushdown,則巢狀屬性、映射值和陣列索引的投影會向下推送至 Redshift,在只存取一部分資料時,就不再需要卸載整個巢狀資料結構。

當您從連接器寫入 DataFrames 時,任何類型為 MapType (使用StringType)、StructType、或 ArrayType 的資料欄都會寫入到 Redshift SUPER 資料類型資料欄。在撰寫這些巢狀資料結構時,tempformat 參數的類型必須是 CSVCSV GZIPPARQUET。使用 AVRO 會導致例外狀況。撰寫具有 StringType 以外索引鍵類型的 MapType 資料結構也會導致例外狀況。

StructType

下列範例會示範如何建立具有 SUPER 資料類型且包含以下結構的資料表

create table contains_super (a super);

然後,您可以使用連接器,在使用如下列範例中的結構描述的資料表中,從 SUPER 資料欄 a 查詢 StringType 欄位 hello

import org.apache.spark.sql.types._ val sc = // existing SparkContext val sqlContext = new SQLContext(sc) val schema = StructType(StructField("a", StructType(StructField("hello", StringType) ::Nil)) :: Nil) val helloDF = sqlContext.read .format("io.github.spark_redshift_community.spark.redshift") .option("url", jdbcURL ) .option("tempdir", tempS3Dir) .option("dbtable", "contains_super") .schema(schema) .load().selectExpr("a.hello")

下列範例會示範如何將結構寫入到資料欄 a

import org.apache.spark.sql.types._ import org.apache.spark.sql._ val sc = // existing SparkContext val sqlContext = new SQLContext(sc) val schema = StructType(StructField("a", StructType(StructField("hello", StringType) ::Nil)) :: Nil) val data = sc.parallelize(Seq(Row(Row("world")))) val mydf = sqlContext.createDataFrame(data, schema) mydf.write.format("io.github.spark_redshift_community.spark.redshift"). option("url", jdbcUrl). option("dbtable", tableName). option("tempdir", tempS3Dir). option("tempformat", "CSV"). mode(SaveMode.Append).save

MapType

如果您偏好使用 MapType 來表示資料,則可以在結構描述中使用 MapType 資料結構,並擷取映射中與索引鍵對應的值。請注意,MapType 資料結構中的所有索引鍵都必須是字串類型,並且所有值都必須是相同類型,例如 int。

下列範例會示範如何取得資料欄 a 中索引鍵 hello 的值。

import org.apache.spark.sql.types._ val sc = // existing SparkContext val sqlContext = new SQLContext(sc) val schema = StructType(StructField("a", MapType(StringType, IntegerType))::Nil) val helloDF = sqlContext.read .format("io.github.spark_redshift_community.spark.redshift") .option("url", jdbcURL ) .option("tempdir", tempS3Dir) .option("dbtable", "contains_super") .schema(schema) .load().selectExpr("a['hello']")

ArrayType

如果資料欄包含陣列而不是結構,您可以使用連接器來查詢陣列中的第一個元素。

import org.apache.spark.sql.types._ val sc = // existing SparkContext val sqlContext = new SQLContext(sc) val schema = StructType(StructField("a", ArrayType(IntegerType)):: Nil) val helloDF = sqlContext.read .format("io.github.spark_redshift_community.spark.redshift") .option("url", jdbcURL ) .option("tempdir", tempS3Dir) .option("dbtable", "contains_super") .schema(schema) .load().selectExpr("a[0]")

限制

搭配 Spark 連接器使用複雜資料類型時有下列限制:

  • 所有巢狀的結構欄位名稱和映射索引鍵都必須小寫。如果要查詢包含大寫字母的複雜欄位名稱,因應措施是您可以嘗試省略結構描述,並使用 from_json Spark 函數在本機轉換傳回的字串。

  • 讀取或寫入操作中使用的任何映射欄位都必須只有 StringType 索引鍵。

  • 只有 CSVCSV GZIPPARQUET 才是支援將複雜類型寫入到 Redshift 的 tempformat 值。嘗試使用 AVRO 會擲回例外狀況。