---
title: "MAP type"
description: "MAP is a nested SQL data type storing an ordered collection of unique key-value pairs, useful for representing dynamic or sparse attributes within a single column."
canonical: "https://motherduck.com/glossary/map-type/"
related:
  - title: "Data types | MotherDuck Docs"
    url: "https://motherduck.com/docs/sql-reference/duckdb-sql-reference/data-types/"
  - title: "DuckLake Architecture Deep Dive"
    url: "https://motherduck.com/blog/ducklake-architecture-deep-dive/"
  - title: "DuckDB statements | MotherDuck Docs"
    url: "https://motherduck.com/docs/sql-reference/duckdb-sql-reference/duckdb-statements/"
gated_asset:
  title: "DuckLake on MotherDuck"
  url: "https://motherduck.com/product/ducklake/"
---

# MAP type

> MAP is a nested SQL data type storing an ordered collection of unique key-value pairs, useful for representing dynamic or sparse attributes within a single column.

## Overview
A `MAP` column holds key-value pairs where all keys share one type and all values share one type — similar to a dictionary or hash map in a programming language. It's the right nested type when the set of "attribute names" per row isn't fixed or known ahead of time.

```sql
CREATE TABLE tbl (id INTEGER, attrs MAP(VARCHAR, VARCHAR));

INSERT INTO tbl VALUES (1, MAP {'color': 'red', 'size': 'M'});

SELECT attrs['color'] AS color FROM tbl;
```

## MAP vs STRUCT
Both `MAP` and `STRUCT` hold key-value-like data, but they serve different purposes:
- **STRUCT** has a fixed, known set of named fields, and different fields can have different value types (like a row/record type). Accessing a missing field is an error.
- **MAP** has a dynamic, per-row set of keys, but all values must share one type. Looking up a missing key returns `NULL` instead of erroring.

Use `STRUCT` for fixed schemas (e.g., an `{street, city, zip}` address), and `MAP` for open-ended or sparse key sets (e.g., arbitrary event properties or feature flags).

## DuckDB specifics
DuckDB supports the `MAP(key_type, value_type)` type declaration, the `MAP {key: value, ...}` literal syntax, and the `MAP(key_list, value_list)` function form for building a map from two parallel lists:

```sql
SELECT MAP(['a', 'b', 'c'], [1, 2, 3]) AS m;
```

DuckDB also provides `map_from_entries([(key, value), ...])` to build a map from a list of key-value pairs, plus accessor functions `map_keys()`, `map_values()`, and `map_entries()`. Keys in a DuckDB `MAP` need not be strings — any comparable type, including nested types like lists, is allowed as a key.