Spark Tables and Catalog
A DataFrame lives only inside your program. A table gives the data a permanent name that other programs and users can query. The Spark catalog keeps a list of databases, tables, and views, so everyone finds data by name instead of by file path.
The Layman View
A library stores thousands of books. Without a catalog, a visitor must search every shelf. The catalog card says where each book sits. The Spark catalog works as that card system for your data.
Views Versus Tables
Temporary view Name for a DataFrame; vanishes when the session ends Global temp view Name shared across sessions of one application Table Permanent entry in the catalog with data stored on disk
Temporary Views
df = spark.read.parquet("/data/sales")
df.createOrReplaceTempView("sales_view")
spark.sql("SELECT region, SUM(amount) FROM sales_view GROUP BY region").show()
A temporary view stores no data. It saves only the query plan.
Managed Tables
Spark owns the data of a managed table. It places files inside the warehouse folder. Dropping the table deletes the data.
df.write.mode("overwrite").saveAsTable("sales_managed")
spark.sql("SELECT COUNT(*) FROM sales_managed").show()
External Tables
An external table points to files that live elsewhere. Spark manages only the table definition. Dropping the table keeps the files safe.
df.write.mode("overwrite").option("path", "/data/lake/sales").saveAsTable("sales_external")
Managed table External table
Catalog entry Catalog entry
| |
Files in warehouse folder Files in your own folder
DROP TABLE --> entry and files DROP TABLE --> entry only, files stay
deleted
Choose external tables for shared raw data that other tools also use.
Databases
Databases group tables like folders group files.
spark.sql("CREATE DATABASE IF NOT EXISTS retail")
spark.sql("USE retail")
df.write.saveAsTable("retail.sales")
spark.sql("SELECT * FROM retail.sales LIMIT 5").show()
Exploring the Catalog
spark.catalog.listDatabases()
spark.catalog.listTables("retail")
spark.catalog.listColumns("sales", "retail")
spark.catalog.tableExists("retail.sales")
spark.sql("DESCRIBE EXTENDED retail.sales").show(50, truncate=False)
DESCRIBE EXTENDED reveals the location, the table type, and the schema.
Where Table Definitions Live
Spark stores definitions in a metastore. A local session uses a small built-in store. A shared cluster connects to a Hive metastore so every application sees the same tables.
spark = (SparkSession.builder
.enableHiveSupport()
.getOrCreate())
Partitioned and Bucketed Tables
A partitioned table splits files into folders by column values. Queries that filter on the column read only matching folders.
df.write.partitionBy("year", "month").saveAsTable("sales_part")
/warehouse/sales_part/year=2026/month=1/part-0001.parquet
/warehouse/sales_part/year=2026/month=2/part-0001.parquet
Bucketing hashes a column into a fixed number of files. Joins between tables bucketed on the same key avoid a shuffle.
df.write.bucketBy(16, "customer_id").sortBy("customer_id").saveAsTable("orders_bucketed")
Refreshing Cached Information
Spark caches file listings. Run a refresh after another tool adds files to an external table.
spark.sql("REFRESH TABLE retail.sales")
spark.catalog.refreshTable("retail.sales")
Good Habits
- Use clear database names such as raw, clean, and reporting.
- Pick external tables for data that must survive a table drop.
- Choose partition columns with moderate variety. A column with millions of values creates millions of folders.
Querying Tables with SQL and DataFrames
A saved table works in both styles. SQL users write queries, and Python users load the table as a DataFrame. Both paths reach the same data.
sales = spark.table("retail.sales")
sales.groupBy("region").count().show()
spark.sql("SELECT region, COUNT(*) FROM retail.sales GROUP BY region").show()
Dropping and Cleaning Up
spark.sql("DROP TABLE IF EXISTS retail.sales_old")
spark.sql("DROP VIEW IF EXISTS sales_view")
spark.sql("DROP DATABASE IF EXISTS scratch CASCADE")
Check the table type before a drop. A managed table loses its data, and an external table keeps it. The CASCADE keyword removes every table inside the database.
