见docs
Hive 从根本上知道两种不同类型的表:
托管(内部)
外部
托管表:托管表存储在
hive.metastore.warehouse.dir 路径属性,默认在文件夹中
路径类似于 /user/hive/warehouse/databasename.db/tablename/。这
默认位置可以被 location 属性覆盖
表创建。如果删除了托管表或分区,则数据
并且与该表或分区关联的元数据将被删除。如果
未指定 PURGE 选项,数据被移动到垃圾文件夹
在定义的持续时间内。
当 Hive 应该管理表的生命周期时使用托管表,
或在生成临时表时。
外部表:外部表描述了元数据/架构
外部文件。外部表文件可以通过以下方式访问和管理
Hive 之外的进程。外部表可以访问存储在
Azure 存储卷 (ASV) 或远程 HDFS 位置等来源。
如果外部表的结构或分区发生更改,则
MSCK REPAIR TABLE table_name 语句可用于刷新元数据
信息。
当文件已经存在或远程时使用外部表
位置,即使删除表,文件也应保留。
结论:
因为您使用的是外部的 s3 位置,所以它的显示方式是这样的。
如果您想进一步了解代码的工作原理,请参阅 CreateTableLikeCommand :在此 val tblType = if (location.isEmpty) CatalogTableType.MANAGED else CatalogTableType.EXTERNAL 是它动态决定的地方...
/**
* A command to create a table with the same definition of the given existing table.
* In the target table definition, the table comment is always empty but the column comments
* are identical to the ones defined in the source table.
*
* The CatalogTable attributes copied from the source table are storage(inputFormat, outputFormat,
* serde, compressed, properties), schema, provider, partitionColumnNames, bucketSpec.
*
* The syntax of using this command in SQL is:
* {{{
* CREATE TABLE [IF NOT EXISTS] [db_name.]table_name
* LIKE [other_db_name.]existing_table_name [locationSpec]
* }}}
*/
case class CreateTableLikeCommand(
targetTable: TableIdentifier,
sourceTable: TableIdentifier,
location: Option[String],
ifNotExists: Boolean) extends RunnableCommand {
override def run(sparkSession: SparkSession): Seq[Row] = {
val catalog = sparkSession.sessionState.catalog
val sourceTableDesc = catalog.getTempViewOrPermanentTableMetadata(sourceTable)
val newProvider = if (sourceTableDesc.tableType == CatalogTableType.VIEW) {
Some(sparkSession.sessionState.conf.defaultDataSourceName)
} else {
sourceTableDesc.provider
}
// If the location is specified, we create an external table internally.
// Otherwise create a managed table.
val tblType = if (location.isEmpty) CatalogTableType.MANAGED else CatalogTableType.EXTERNAL
val newTableDesc =
CatalogTable(
identifier = targetTable,
tableType = tblType,
storage = sourceTableDesc.storage.copy(
locationUri = location.map(CatalogUtils.stringToURI(_))),
schema = sourceTableDesc.schema,
provider = newProvider,
partitionColumnNames = sourceTableDesc.partitionColumnNames,
bucketSpec = sourceTableDesc.bucketSpec)
catalog.createTable(newTableDesc, ifNotExists)
Seq.empty[Row]
}
}
更新:
如果我在 hive 控制台中执行此查询,它会创建托管表,那么如何在 spark 中执行相同的操作?
希望您使用的是 hive 和 spark 共存的相同本地位置(不是不同的 vpc)。
如果是,那么设置
spark.sql.warehouse.dir=hdfs:///... 到 s3 位置
使用 spark conf.... 您可能需要设置访问密钥和秘密 id 凭据以触发配置对象以创建 spark 会话。