如何在Spark中实现SQL Server式表分组?Database与Schema有何差异?
1. Spark中Database与Schema是否同义?
在Spark SQL的默认行为里,Database和Schema是完全同义的。你执行spark.sql('show databases').show()和spark.sql('show schemas').show()得到相同结果,就是最直接的证明——这两个命令在Spark里是等价的,甚至USE database_name和USE schema_name的效果也完全一致。
2. 二者有没有区别?
严格从Spark的Catalog接口定义来看,Database和Schema在抽象概念上是分层的:Catalog是顶层元数据容器,Database是Catalog下的一级命名空间,Schema是Database下的二级命名空间。但问题在于,绝大多数Spark默认支持的数据源(比如内置Spark SQL、Delta Lake)都没有实现这种分层,而是把Database和Schema合并成了同一个层级。
只有对接部分外部企业级数据仓库时,可能会区分Database和Schema,但这属于数据源自身特性,并非Spark SQL的默认行为。
3. 能否实现SQL Server式的三级表结构?
可以通过Spark的多Catalog特性来模拟SQL Server的Catalog(Database) > Schema > Table三级结构,逻辑对齐方式如下:
- 将Spark的顶层Catalog对应SQL Server的Database;
- 将Spark Catalog下的Database对应SQL Server的Schema;
- 最终表的引用方式变为
spark_catalog_name.sql_server_schema_name.table_name,和SQL Server的DatabaseName.SchemaName.TableName逻辑一致。
举个实际操作的例子,连接SQL Server时可为每个SQL Server的Database创建独立的Spark Catalog:
// 创建对应SQL Server某Database的Catalog spark.sql("CREATE CATALOG sqlserver_db1 USING org.apache.spark.sql.jdbc OPTIONS (url 'jdbc:sqlserver://host:port;databaseName=db1', dbtable 'sys.tables', user 'xxx', password 'xxx')") // 使用该Catalog下的Schema(对应SQL Server的Schema) spark.sql("USE CATALOG sqlserver_db1") spark.sql("USE schema1") // 查询表 spark.sql("SELECT * FROM table1").show()
如果基于Spark自身元存储(比如内置内存Catalog或Hive Metastore),原生不支持三级分层,但可以通过命名规范模拟:比如用database_name.schema_prefix.table_name的命名方式,把Schema作为表名前缀,或创建视图映射结构,但这种方式不够规范,不如多Catalog方案严谨。
内容的提问来源于stack exchange,提问作者Merin Nakarmi

