通过 Azure Synapse Analytics,不同的工作区计算引擎可在其 Apache Spark 池与无服务器 SQL 池之间共享数据库和表。

Spark 作业创建数据库后,你可通过 Spark 在其中创建使用 Parquet、Delta 或 CSV 作为存储格式的表。 表名称将转换为小写,并且需要使用小写名进行查询。 这些表将立即可供任何 Azure Synapse 工作区 Spark 池查询。 还可以在任何 Spark 作业中按权限使用这些表。

Spark 创建的表、托管表和外部表还可以使用相同名称在无服务器 SQL 池的相应已同步数据库中以外部表形式提供。 在 SQL 中公开 Spark 表 提供了有关表同步的更多详细信息。

由于表以异步方式同步到无服务器 SQL 池,因此这些表略微延迟一会儿才会出现。

管理 Spark 创建的表

使用 Spark 管理 Spark 创建的数据库。 例如,通过无服务器 Apache Spark 池作业删除数据库,通过 Spark 在数据库中创建表。

无法从无服务器 SQL 池修改同步数据库中的对象。

使用 SQL 公开 Spark 表

共享的 Spark 表

Spark 提供两种类型的、由 Azure Synapse 在 SQL 中自动公开的表:

Spark 提供多种选项(例如 TEXT、CSV、JSON、JDBC、PARQUET、ORC、HIVE、DELTA 和 LIBSVM),供用户选择如何在托管表中存储数据。 这些文件通常存储在托管表数据所存储到的 warehouse 目录中。

Spark 还可让用户通过提供 LOCATION 选项或使用 Hive 格式,来基于现有数据创建外部表。 可以基于各种数据格式(包括 Parquet)创建此类外部表。

Azure Synapse 目前只共享使用 SQL 引擎以 Parquet、DELTA 或 CSV 格式存储其数据的托管 Spark 表和外部 Spark 表。 其他格式支持的表不会自动同步。 你可以在自己的 SQL 数据库中自行显式将此类表作为外部表进行同步,前提是 SQL 引擎支持这些表的基础格式。

目前,无服务器 SQL 池仅完全支持 Parquet 和 CSV 格式。 Spark Delta 表也可在无服务器 SQL 池中使用,但此功能目前以公共预览版提供。 在 Spark 中创建的外部表在专用 SQL 池数据库中不可用。

共享 Spark 表

可共享的托管 Spark 表和外部 Spark 表在 SQL 引擎中作为具有以下属性的外部表公开:

  • SQL 外部表的数据源是表示 Spark 表位置文件夹的数据源。
  • SQL 外部表的文件格式为 Parquet、Delta 或 CSV。
  • SQL 外部表的访问凭据是直通身份验证凭据。
  • 由于所有 Spark 表名称是有效的 SQL 表名称,且所有 Spark 列名称是有效的 SQL 列名称,因此 Spark 表名称和列名称将用于 SQL 外部表。

    Spark 表与 Synapse SQL 引擎提供的数据类型不同。 下表将 Spark 表数据类型映射到了 SQL 类型:

    Spark 数据类型 SQL 数据类型 LongType , long , bigint bigint Spark :LongType 表示 8 字节带符号整数。
    SQL:请参阅 int、bigint、smallint 和 tinyint BooleanType , boolean bit (Parquet), varchar(6) (CSV) Spark :Boolean。
    SQL :请参阅 [/sql/t-sql/data-types/bit-transact-sql)。 DecimalType , decimal , dec , numeric decimal Spar k:DecimalType 表示任意精度的带符号十进制数。 在内部由 java.math.BigDecimal 提供支持。 BigDecimal 由一个任意精度的非标度整数值和一个 32 位整数标度构成。
    SQL :固定精度和小数位数。 使用最大精度时,有效值的范围为 - 10^38 +1 到 10^38 - 1。 decimal 的 ISO 同义词为 dec 和 dec(p,s) 。 numeric 在功能上完全等同于 decimal 。 请参阅 decimal 和 numeric IntegerType , Integer , int SparkIntegerType 表示 4 字节带符号整数。
    SQL:请参阅 int、bigint、smallint 和 tinyint ByteType , Byte , tinyint smallint Spark :ByteType 表示 1 字节带符号整数 [-128 到 127],ShortType 表示 2 字节带符号整数 [-32768 到 32767]。
    SQL :Tinyint 表示 1 字节带符号整数 [0, 255],smallint 表示 2 字节带符号整数 [-32768, 32767]。 请参阅 int、bigint、smallint 和 tinyint ShortType , Short , smallint smallint DoubleType , Double float Spark :DoubleType 表示 8 字节双精度浮点数。 SQL:请参阅 float 和 real FloatType , float , real Spark :FloatType 表示 4 字节双精度浮点数。 SQL:请参阅 float 和 real DateType , date Spark :DateType 表示包含年月日字段的值,不带时区。
    SQL :请参阅 date TimestampType , timestamp datetime2 Spark :TimestampType 表示包含年、月、日、小时、分钟和秒字段的值,还包含会话本地时区。 时间戳值表示绝对时间点。
    SQL :请参阅 datetime2 StringType , String , varchar Varchar(n) Spark :StringType 表示字符串值。 VarcharType(n) 是 StringType 的变体,它有长度限制。 如果输入字符串超过长度限制,数据写入将失败。 此类型只能用于表架构,不能用于函数/运算符。
    CharType(n) 是固定长度的 VarcharType(n) 的变体 。 读取 CharType(n) 类型的列会始终返回长度为 n 的字符串值。 CharType(n) 列比较会将较短的列填充到较长的列。
    SQL :如果从 Spark 提供了长度,则 varchar(n) 中的 n 将设置为该长度。 如果是已分区的列,则 n 最大可为 2048。 否则,将是 varchar(max)。 请参阅 char 和 varchar
    将其与排序规则 Latin1_General_100_BIN2_UTF8 一起使用。 BinaryType , binary varbinary(n) SQL :如果从 Spark 提供了长度,则 Varbinary(n) 中的 n 将设置为该长度。 如果是已分区的列,则 n 最大可为 2048。 否则,将是 Varbinary(max)。 请参阅 binary 和 varbinary array , map , struct varchar(max) SQL :使用排序规则 Latin1_General_100_BIN2_UTF8 序列化为 JSON。 请参阅 JSON 数据

    Spark 数据库和表及其在 SQL 引擎中的已同步表示形式将在基础存储级别受到保护。 由于它们当前对对象本身不拥有权限,因此可以在对象资源管理器中查看对象。

    创建托管表的安全主体被视为该表的所有者,对该表以及基础文件夹和文件拥有所有权限。 此外,数据库的所有者将自动成为该表的共同所有者。

    如果使用直通身份验证创建 Spark 或 SQL 外部表,则数据只会在文件夹和文件级别受到保护。 如果某人查询这种类型的外部表,则该查询提交者的安全标识会传递给文件系统,而文件系统将检查该提交者是否有访问权限。

    有关如何设置文件夹和文件权限的详细信息,请参阅 Azure Synapse Analytics 共享数据库

    在 Spark 中创建托管表并从无服务器 SQL 池进行查询

    在此场景中,你有一个名为 mytestdb 的 Spark 数据库。 请参阅 使用无服务器 SQL 池创建并连接到 Spark 数据库

    运行以下命令,使用 SparkSQL 创建托管的 Spark 表:

        CREATE TABLE mytestdb.myparquettable(id int, name string, birthdate date) USING Parquet
    

    此命令在数据库 mytestdb 中创建表 myparquettable。 表名称将转换为小写。 在短暂的延迟后,可以在无服务器 SQL 池中看到该表。 例如,在无服务器 SQL 池中运行以下语句。

        USE mytestdb;
        SELECT * FROM sys.tables;
    

    请验证结果中是否包含 myparquettable

    不使用 Delta、Parquet 或 CSV 作为存储格式的表不会同步。

    接下来,通过 Spark 在该表中插入一些值,例如,在 C# 笔记本中使用以下 C# Spark 语句:

    using Microsoft.Spark.Sql.Types;
    var data = new List<GenericRow>();
    data.Add(new GenericRow(new object[] { 1, "Alice", new Date(2010, 1, 1)}));
    data.Add(new GenericRow(new object[] { 2, "Bob", new Date(1990, 1, 1)}));
    var schema = new StructType
        (new List<StructField>()
                new StructField("id", new IntegerType()),
                new StructField("name", new StringType()),
                new StructField("birthdate", new DateType())
    var df = spark.CreateDataFrame(data, schema);
    df.Write().Mode(SaveMode.Append).InsertInto("mytestdb.myparquettable");
    

    现在,可以从无服务器 SQL 池中读取数据,如下所示:

    SELECT * FROM mytestdb.dbo.myparquettable WHERE name = 'Alice';
    

    在结果中应会看到以下行:

    id | name | birthdate
    ---+-------+-----------
    1 | Alice | 2010-01-01
    

    在 Spark 中创建外部表并从无服务器 SQL 池进行查询

    在此示例中,我们将基于在前一个托管表示例中创建的 Parquet 数据文件创建一个外部 Spark 表。

    例如,使用 SparkSQL 运行:

    CREATE TABLE mytestdb.myexternalparquettable
        USING Parquet
        LOCATION "abfss://<storage-name>.dfs.core.windows.net/<fs>/synapse/workspaces/<synapse_ws>/warehouse/mytestdb.db/myparquettable/"
    

    将占位符 <storage-name> 替换为正在使用的 ADLS Gen2 存储帐户名称,<fs> 替换为正在使用的文件系统名称,并将 <synapse_ws> 占位符替换为用于运行此示例的 Azure Synapse 工作区的名称。

    以上示例在数据库 mytestdb 中创建表 myextneralparquettable。 在短暂的延迟后,可以在无服务器 SQL 池中看到该表。 例如,在无服务器 SQL 池中运行以下语句。

    USE mytestdb;
    SELECT * FROM sys.tables;
    

    请验证结果中是否包含 myexternalparquettable

    现在,可以从无服务器 SQL 池中读取数据,如下所示:

    SELECT * FROM mytestdb.dbo.myexternalparquettable WHERE name = 'Alice';
    

    在结果中应会看到以下行:

    id | name | birthdate
    ---+-------+-----------
    1 | Alice | 2010-01-01
    
  • 详细了解 Azure Synapse Analytics 的共享元数据
  • 详细了解 Azure Synapse Analytics 的共享元数据数据库
  •