# Building with Aerospike

Aerospike provides full support for key-value store and document store models. In fact, its operations provide much broader support than the textbook definitions of those models. Aerospike is a row-oriented database, where every _record_ (equivalent to a row in a relational database) is uniquely identified by a key. The record’s key and its other metadata live in the primary index. The record’s data lives in the pre-defined storage device of the Namespace it occupies. For detailed descriptions of an Aerospike Record, Namespace, Set, Key, Bins, and Data Types, read the [Data Model](https://aerospike.com/docs/database/learn/architecture/data-storage/data-model) section of the architecture overview.

## Data models

Aerospike supports both key-value store and document store models:

**Key-value store model**

Records are uniquely identified by a Key composed of the name of the [Set](https://aerospike.com/docs/database/learn/architecture/data-storage/data-model/#sets) and the _user key_. The user key is the primary identifier for a record from the app you are building on top of Aerospike. Although a value in a K-V store model is traditionally one opaque and schemaless blob of data, Aerospike records consist of one or more [Bins](https://aerospike.com/docs/database/learn/architecture/data-storage/data-model/#bins-and-data-types) of typed or untyped blob data.

**Document store model**

A variant of the key-value store model, where a single record is single document of data, encoded in XML, YAML, JSON, BSON. Aerospike customers commonly store a document of data in a [Map](https://aerospike.com/docs/develop/data-types/collections/map) data type. An Aerospike Map is a superset of JSON that can contain different data types, including nested Map and [List](https://aerospike.com/docs/develop/data-types/collections/list) structures. Maps transparently use MessagePack compression for efficient storage. Whereas a traditional document store model stores one document of data per record, an Aerospike record can contain multiple bins, and therefore multiple scalar and collection data types per record.

## Command types

A read or write command is either a CRUD (create, read, update, delete) record operation that executes against an entire record, or a series of bin operations using the operate command. Commands can be executed against one record (single-key) or in a batch against multiple records identified by a list of keys in parallel.

## Implementation considerations

Application developers should use the following best practices for implementing a data model.

-   Aerospike is schemaless. Prior to putting data in the database, you define _namespaces_ to associate data with hardware storage media types. By comparison, _sets_ (equivalent to tables in a relational database) and _bins_ (equivalent to columns in a relational database) are created in real time by the application as it performs write operations into Aerospike.
-   Aerospike modifies individual records atomically in Strong Consistency (SC) mode.  Multiple operations on one or more of a record’s bins are combined into one command, which executes under a record lock providing isolation and durability. Multiple commands on one or more records can be combined as a [transaction](https://aerospike.com/docs/database/learn/architecture/transactions) in Aerospike 8.0.0 and later.
-   Aerospike data types each have their own APIs of atomic write operations and server-side read operations, such as the Map data type’s [`get_by_rank_range()`](https://aerospike.com/docs/develop/data-types/collections/map/#map-api) operation.
-   Starting with Aerospike version 4.6.0, Map and List operations can be [applied on deeply nested elements](https://aerospike.com/docs/develop/data-types/collections/context).