← Backend← Backend
BackendBackend19 Th7, 2026Jul 19, 202618 phút đọc14 min read

Cơ sở dữ liệu NoSQLNoSQL Databases

Thuộc bộ kiến thức Backend Roadmap.

Tổng quan

NoSQL (“Not Only SQL”) là thuật ngữ chung cho các database không dùng mô hình relational truyền thống gồm bảng, hàng, và schema cứng nhắc liên kết qua foreign key và join. Thay vào đó, mỗi họ NoSQL được tối ưu cho một hình dạng dữ liệu và pattern truy cập cụ thể: tra cứu đơn giản theo key, document lồng nhau, hàng thưa (wide row), hay đồ thị các thực thể liên kết.

Các database NoSQL xuất hiện vào giữa đến cuối những năm 2000, xuất phát từ nhu cầu của các công ty vận hành ở quy mô mà một server relational đơn lẻ khó đáp ứng. Google (Bigtable, 2006), Amazon (bài báo Dynamo, 2007) và Facebook (Cassandra, 2008) đều công bố hoặc open-source các hệ thống được xây để xử lý workload phân tán khổng lồ với throughput cao, nơi horizontal scaling (thêm nhiều máy commodity) quan trọng hơn khả năng truy vấn phong phú và các đảm bảo mạnh của một relational database (RDBMS).

Đánh đổi cốt lõi của NoSQL: nó nới lỏng một số thứ mà relational database đảm bảo — schema cố định, join nhiều bảng, và thường là ACID transaction mạnh — để đổi lấy sự linh hoạt, horizontal scalability, và hiệu năng trên các pattern truy cập cụ thể. NoSQL không phải là thứ thay thế SQL; nó là một bộ công cụ chuyên biệt mà bạn dùng khi mô hình relational không phù hợp.

Ghi chú này giả định bạn đã quen với Relational Databases và liên kết tới Database Design & Scaling cùng Caching.

Kiến thức nền tảng

Vì sao NoSQL xuất hiện

Relational database là kho lưu trữ đa dụng tuyệt vời, nhưng nhiều yếu tố đã bộc lộ giới hạn của chúng ở quy mô lớn:

Đánh đổi giữa SQL và NoSQL

Khía cạnhRelational (SQL)NoSQL
Data modelBảng, hàng, cột; đã normalizeKey-value, document, wide-column, graph
SchemaCố định, bắt buộc (schema-on-write)Linh hoạt / động (thường schema-on-read)
Ngôn ngữ truy vấnSQL (chuẩn hóa)API/DSL riêng theo sản phẩm (một số giống SQL)
JoinHạng nhất, mạnh mẽHạn chế hoặc không có; ưu tiên denormalization
TransactionACID mạnh xuyên hàng/bảngThường hạn chế; tùy sản phẩm
ScalingChủ yếu vertical; sharding khóHorizontal scaling là mục tiêu thiết kế hạng nhất
ConsistencyMạnh theo mặc địnhĐiều chỉnh được; thường eventual consistency
Phù hợp nhất choTruy vấn phức tạp, quan hệ, tính toàn vẹnThroughput cao, big data, hình dạng linh hoạt/chuyên biệt

Khi nào chọn cái nào

Chọn relational database khi:

Chọn NoSQL khi:

Hầu hết hệ thống thực tế đều polyglot: PostgreSQL cho dữ liệu transactional cốt lõi, Redis cho caching/session, Elasticsearch cho search, và có thể thêm một graph hoặc document store cho một tính năng cụ thể.

CAP theorem và các mô hình consistency

CAP theorem phát biểu rằng một kho dữ liệu phân tán chỉ có thể đảm bảo tối đa hai trong ba thuộc tính sau khi xảy ra network partition:

Vì network partition là không thể tránh trong mọi hệ phân tán, P không phải lựa chọn tùy ý — bạn buộc phải chịu được partition. Lựa chọn thực sự khi partition xảy ra là C hay A:

Các database hiện đại thường cho phép điều chỉnh theo từng operation (xem quorum read/write bên dưới), nên “CP vs AP” là một dải liên tục chứ không phải nhãn cố định.

Các mô hình consistency:

ACID vs BASE

ACID (RDBMS điển hình)BASE (NoSQL điển hình)
Viết tắt củaAtomicity, Consistency, Isolation, DurabilityBasically Available, Soft state, Eventual consistency
Mục tiêuTính đúng đắn và an toànAvailability và scale
ConsistencyMạnh, tức thìEventual (hội tụ theo thời gian)
TransactionNhiều lệnh, tất-cả-hoặc-khôngThường single-item; hạn chế multi-item
Trạng tháiLuôn hợp lệ sau mỗi transactionCó thể inconsistent tạm thời
Đánh đổiLatency/availability lấy tính đúng đắnTính đúng đắn (ngắn hạn) lấy availability

Lưu ý: ranh giới đang mờ dần. MongoDB hỗ trợ ACID transaction đa document; DynamoDB hỗ trợ transaction; Google Spanner và CockroachDB cung cấp strong consistency phân tán. Hãy chọn dựa trên đảm bảo thực tế mà sản phẩm cung cấp, không phải dựa trên cái nhãn.

Khái niệm chính

Bốn họ NoSQL nhìn nhanh

HọData modelTruy vấn theoSản phẩm tiêu biểuUse case điển hình
Key-valueValue dạng “hộp đen” dưới một key duy nhấtChỉ theo keyRedis, Memcached, DynamoDB, RiakCache, session, feature flag, counter
DocumentDocument JSON/BSON tự mô tảKey + truy vấn theo fieldMongoDB, CouchDB, FirestoreCatalog, user profile, CMS, dữ liệu app
Wide-columnHàng với cột động, gom theo column familyPartition key + clusteringCassandra, ScyllaDB, HBase, BigtableTime-series, event log, feed ở quy mô lớn
GraphNode + edge kèm propertyTraversal / pattern matchNeo4j, Dgraph, Amazon NeptuneSocial graph, fraud, recommendation

Key-value store

Mô hình đơn giản nhất: một hash map khổng lồ, phân tán. Bạn lưu một value (database coi như bytes “hộp đen”) dưới một key duy nhất, và lấy lại theo key đó. Cực nhanh và dễ scale, nhưng thường bạn không thể truy vấn theo nội dung của value.

Sản phẩm: Redis (in-memory, nhiều cấu trúc dữ liệu phong phú, tùy chọn persistence), Memcached (cache in-memory, không persistence), DynamoDB (managed, bền, scale được), Riak (phân tán, AP, kiểu Dynamo).

Ví dụ (Redis):

# Lưu session kèm thời gian hết hạn
SET session:abc123 '{"userId":42,"role":"admin"}' EX 3600
GET session:abc123

# Counter atomic cho rate limiting
INCR api:calls:user:42
EXPIRE api:calls:user:42 60

# Bảng xếp hạng dùng sorted set
ZADD leaderboard 1500 "player:alice"
ZADD leaderboard 2300 "player:bob"
ZREVRANGE leaderboard 0 9 WITHSCORES   # top 10

Ngoài string thuần, Redis còn cung cấp list, set, sorted set, hash, stream, và pub/sub — đó là lý do nó được dùng vượt xa caching đơn thuần. Xem Caching.

Document store

Lưu các document — bản ghi tự mô tả, lồng nhau ở dạng JSON hoặc BSON. Document được gom vào các collection. Không có schema cố định, nên các document khác nhau trong cùng collection có thể có field khác nhau. Bạn có thể truy vấn trên bất kỳ field nào, tạo index, và cập nhật từng phần lồng nhau của document.

Sản phẩm: MongoDB (phổ biến nhất; truy vấn phong phú, aggregation pipeline, transaction), CouchDB (API HTTP/JSON, đồng thời đa phiên bản, đồng bộ offline), Firebase/Firestore (managed, listener real-time, ưu tiên mobile).

Ví dụ (MongoDB):

// Một document sản phẩm — dữ liệu liên quan được embed, không join
db.products.insertOne({
  _id: "SKU-1001",
  name: "Mechanical Keyboard",
  price: 89.99,
  tags: ["electronics", "peripherals"],
  specs: { switches: "brown", layout: "TKL", backlight: true },
  reviews: [
    { user: "alice", rating: 5, text: "Great feel" },
    { user: "bob",   rating: 4, text: "A bit loud" }
  ]
});

// Truy vấn theo field lồng nhau + phần tử trong array
db.products.find({
  "specs.switches": "brown",
  tags: "peripherals",
  price: { $lt: 100 }
});

// Aggregation: rating trung bình mỗi sản phẩm
db.products.aggregate([
  { $unwind: "$reviews" },
  { $group: { _id: "$_id", avgRating: { $avg: "$reviews.rating" } } }
]);

Việc embed dữ liệu liên quan (reviews nằm trong product) tránh được join và cho phép đọc trọn sản phẩm trong một truy vấn — một ý tưởng modeling cốt lõi của NoSQL.

Wide-column store

Còn gọi là column-family store. Dữ liệu được tổ chức thành các hàng định danh bởi partition key, và mỗi hàng có thể có tập cột động, lớn. Các hàng được phân bố qua các node theo partition key; trong một partition, hàng được sắp xếp theo clustering column. Mô hình này được xây cho throughput write khổng lồ và read dự đoán được trên các partition đã biết — nhưng bạn phải thiết kế bảng quanh các truy vấn của mình, vì nó không hỗ trợ truy vấn tùy biến và join.

Sản phẩm: Cassandra (AP, consistency điều chỉnh được, không có single point of failure), ScyllaDB (tương thích Cassandra, viết bằng C++, hiệu năng cao hơn), HBase (chạy trên HDFS, CP, kiểu Bigtable), Google Bigtable (managed, vận hành Search/Maps/Analytics).

Ví dụ (Cassandra CQL):

-- Thiết kế bảng cho truy vấn: "các event gần đây của một device, mới nhất trước"
CREATE TABLE events_by_device (
  device_id   text,
  event_time  timestamp,
  event_type  text,
  payload     text,
  PRIMARY KEY (device_id, event_time)
) WITH CLUSTERING ORDER BY (event_time DESC);

-- Write
INSERT INTO events_by_device (device_id, event_time, event_type, payload)
VALUES ('dev-42', '2026-07-19T10:00:00Z', 'temp', '{"c":21.5}');

-- Read: hiệu quả, chỉ chạm một partition, đã được sắp xếp sẵn
SELECT * FROM events_by_device
WHERE device_id = 'dev-42'
LIMIT 100;

Partition key (device_id) quyết định node nào giữ dữ liệu; clustering column (event_time) quyết định thứ tự sắp xếp bên trong. Chọn partition key tốt (để tránh “hot partition” và partition phình vô hạn) là kỹ năng trung tâm.

Graph database

Mô hình hóa dữ liệu thành các node (thực thể) nối với nhau bởi các edge (quan hệ), cả hai đều có thể mang property. Chúng vượt trội khi quan hệ là trọng tâm — duyệt “bạn của bạn”, tìm đường ngắn nhất, hoặc phát hiện các vòng tài khoản fraud liên kết — những truy vấn sẽ cần rất nhiều join tốn kém trong SQL.

Sản phẩm: Neo4j (phổ biến nhất; ngôn ngữ truy vấn Cypher), Dgraph (phân tán, GraphQL-native), Amazon Neptune (managed; hỗ trợ Gremlin và SPARQL).

Ví dụ (Neo4j Cypher):

// Tạo người và một mối quan hệ bạn bè
CREATE (alice:Person {name: 'Alice'})
CREATE (bob:Person {name: 'Bob'})
CREATE (carol:Person {name: 'Carol'})
CREATE (alice)-[:FRIENDS_WITH]->(bob)
CREATE (bob)-[:FRIENDS_WITH]->(carol);

// Bạn-của-bạn của Alice mà cô ấy chưa là bạn
MATCH (alice:Person {name: 'Alice'})-[:FRIENDS_WITH]->(:Person)
      -[:FRIENDS_WITH]->(fof:Person)
WHERE NOT (alice)-[:FRIENDS_WITH]->(fof) AND fof <> alice
RETURN DISTINCT fof.name;

Chi phí traversal phụ thuộc vào số quan hệ đi qua, không phải tổng kích thước dataset — nên truy vấn quan hệ sâu vẫn nhanh dù dữ liệu tăng lên.

Các kho dữ liệu chuyên biệt

Ngoài bốn họ kinh điển, một số kho được xây cho mục đích riêng cũng rất phổ biến trong backend:

Data modeling cho NoSQL

Modeling cho NoSQL khác biệt về bản chất so với modeling relational. Trong SQL bạn normalize trước rồi để join ghép lại dữ liệu. Trong NoSQL bạn mô hình quanh các pattern truy cập và thường denormalize mạnh tay.

Single-table design (DynamoDB): Một pattern nâng cao nổi tiếng, trong đó nhiều loại entity nằm trong một bảng, phân biệt bằng partition key (PK) và sort key (SK) được ghép khéo léo. Điều này cho phép một truy vấn lấy về các item liên quan (ví dụ một user và tất cả đơn hàng của họ) mà không cần join.

PKSKAttributes
USER#42PROFILE#42name, email
USER#42ORDER#1001total, status, date
USER#42ORDER#1002total, status, date
# Một truy vấn trả về profile CỦA user VÀ tất cả đơn hàng của họ:
Query where PK = "USER#42"
# Lọc chỉ lấy đơn hàng:
Query where PK = "USER#42" AND begins_with(SK, "ORDER#")

Nguyên tắc thiết kế: vì DynamoDB không có join và tính phí theo từng request, bạn đặt các item liên quan cùng một partition key để đọc chúng trong một truy vấn hiệu quả.

So sánh giữa các họ

Key-valueDocumentWide-columnGraph
Data modelKey → value hộp đenCollection các document JSONHàng có partition, cột độngNode + edge + property
Khả năng truy vấnChỉ theo keyTruy vấn phong phú trên mọi fieldPartition/clustering key; ad hoc hạn chếTraversal, pattern matching
ConsistencyĐiều chỉnh được (thường eventual)Điều chỉnh; MongoDB mặc định mạnh trên primaryĐiều chỉnh (Cassandra quorum)Thường mạnh (Neo4j ACID)
ScalingHorizontal xuất sắcTốt (sharding)Horizontal xuất sắcKhó phân tán hơn
Use case tốt nhấtCache, session, counterDữ liệu app, catalog, profileTime-series, log, feed quy mô lớnQuan hệ, social, fraud
Điểm yếuTruy vấn theo valueJoin xuyên documentTruy vấn ad hoc, joinWrite cực lớn, sharding

Best Practices

Tài liệu tham khảo

Part of the Backend Roadmap knowledge base.

Overview

NoSQL (“Not Only SQL”) is an umbrella term for databases that do not use the traditional relational model of tables, rows, and rigid schemas connected by foreign keys and joins. Instead, each NoSQL family optimizes for a specific data shape and access pattern: simple lookups by key, nested documents, wide sparse rows, or connected graphs.

NoSQL databases emerged in the mid-to-late 2000s, driven by companies operating at a scale that single relational servers struggled with. Google (Bigtable, 2006), Amazon (Dynamo paper, 2007), and Facebook (Cassandra, 2008) each published or open-sourced systems built to handle massive, distributed, high-throughput workloads where horizontal scaling (adding more commodity machines) mattered more than the rich querying and strong guarantees of a relational database (RDBMS).

The core trade NoSQL makes: it relaxes some of what relational databases guarantee — a fixed schema, multi-table joins, and often strong ACID transactions — in exchange for flexibility, horizontal scalability, and performance on specific access patterns. NoSQL is not a replacement for SQL; it is a set of specialized tools you reach for when the relational model is a poor fit.

This note assumes familiarity with Relational Databases and connects to Database Design & Scaling and Caching.

Fundamentals

Why NoSQL emerged

Relational databases are excellent general-purpose stores, but several forces exposed their limits at scale:

SQL vs NoSQL trade-offs

AspectRelational (SQL)NoSQL
Data modelTables, rows, columns; normalizedKey-value, document, wide-column, graph
SchemaFixed, enforced (schema-on-write)Flexible / dynamic (often schema-on-read)
Query languageSQL (standardized)Product-specific APIs/DSLs (some SQL-like)
JoinsFirst-class, powerfulLimited or none; prefer denormalization
TransactionsStrong ACID across rows/tablesOften limited; varies by product
ScalingPrimarily vertical; sharding is hardHorizontal scaling is a first-class design goal
ConsistencyStrong by defaultTunable; often eventual consistency
Best forComplex queries, relationships, integrityHigh throughput, big data, flexible/specialized shapes

When to choose which

Reach for a relational database when:

Reach for NoSQL when:

Most real systems are polyglot: PostgreSQL for core transactional data, Redis for caching/sessions, Elasticsearch for search, and perhaps a graph or document store for a specific feature.

CAP theorem and consistency models

The CAP theorem states that a distributed data store can guarantee at most two of the following three properties when a network partition occurs:

Since network partitions are unavoidable in any distributed system, P is not optional — you must tolerate partitions. The real choice during a partition is C vs A:

Modern databases often make this tunable per operation (see quorum reads/writes below), so “CP vs AP” is a spectrum, not a fixed label.

Consistency models:

ACID vs BASE

ACID (typical RDBMS)BASE (typical NoSQL)
Stands forAtomicity, Consistency, Isolation, DurabilityBasically Available, Soft state, Eventual consistency
GoalCorrectness and safetyAvailability and scale
ConsistencyStrong, immediateEventual (converges over time)
TransactionsMulti-statement, all-or-nothingOften single-item; limited multi-item
StateAlways valid after each transactionMay be temporarily inconsistent
Trade-offLatency/availability for correctnessCorrectness (short-term) for availability

Note: the line is blurring. MongoDB supports multi-document ACID transactions; DynamoDB supports transactions; Google Spanner and CockroachDB offer distributed strong consistency. Choose based on the actual guarantees a product offers, not the label.

Key Concepts

The four families at a glance

FamilyData modelQuery byRepresentative productsTypical use case
Key-valueOpaque value under a unique keyKey onlyRedis, Memcached, DynamoDB, RiakCache, sessions, feature flags, counters
DocumentSelf-describing JSON/BSON documentsKey + rich field queriesMongoDB, CouchDB, FirestoreCatalogs, user profiles, CMS, app data
Wide-columnRows with dynamic columns, grouped in familiesPartition key + clusteringCassandra, ScyllaDB, HBase, BigtableTime-series, event logs, feeds at scale
GraphNodes + edges with propertiesTraversals / pattern matchNeo4j, Dgraph, Amazon NeptuneSocial graphs, fraud, recommendations

Key-value stores

The simplest model: a giant, distributed hash map. You store a value (which the database treats as opaque bytes) under a unique key, and retrieve it by that key. Extremely fast and easy to scale, but you generally cannot query by the value’s contents.

Products: Redis (in-memory, rich data structures, optional persistence), Memcached (in-memory cache, no persistence), DynamoDB (managed, durable, scalable), Riak (distributed, AP, Dynamo-style).

Example (Redis):

# Session store with expiry
SET session:abc123 '{"userId":42,"role":"admin"}' EX 3600
GET session:abc123

# Atomic counter for rate limiting
INCR api:calls:user:42
EXPIRE api:calls:user:42 60

# Leaderboard using a sorted set
ZADD leaderboard 1500 "player:alice"
ZADD leaderboard 2300 "player:bob"
ZREVRANGE leaderboard 0 9 WITHSCORES   # top 10

Beyond plain strings, Redis provides lists, sets, sorted sets, hashes, streams, and pub/sub — which is why it’s used far beyond simple caching. See Caching.

Document stores

Store documents — self-describing, nested records in JSON or BSON. Documents are grouped into collections. There is no fixed schema, so different documents in a collection can have different fields. You can query on any field, index fields, and update nested parts of a document.

Products: MongoDB (most popular; rich queries, aggregation pipeline, transactions), CouchDB (HTTP/JSON API, multi-version concurrency, offline sync), Firebase/Firestore (managed, real-time listeners, mobile-first).

Example (MongoDB):

// A product document — related data embedded, not joined
db.products.insertOne({
  _id: "SKU-1001",
  name: "Mechanical Keyboard",
  price: 89.99,
  tags: ["electronics", "peripherals"],
  specs: { switches: "brown", layout: "TKL", backlight: true },
  reviews: [
    { user: "alice", rating: 5, text: "Great feel" },
    { user: "bob",   rating: 4, text: "A bit loud" }
  ]
});

// Query by nested field + array membership
db.products.find({
  "specs.switches": "brown",
  tags: "peripherals",
  price: { $lt: 100 }
});

// Aggregation: average rating per product
db.products.aggregate([
  { $unwind: "$reviews" },
  { $group: { _id: "$_id", avgRating: { $avg: "$reviews.rating" } } }
]);

Embedding related data (reviews inside the product) avoids joins and lets you read the whole product in one query — a core NoSQL modeling idea.

Wide-column stores

Also called column-family stores. Data is organized into rows identified by a partition key, and each row can have a large, dynamic set of columns. Rows are distributed across nodes by partition key; within a partition, rows are sorted by clustering columns. This model is built for massive write throughput and predictable reads on known partitions — but you must design tables around your queries, since ad hoc querying and joins are not supported.

Products: Cassandra (AP, tunable consistency, no single point of failure), ScyllaDB (Cassandra-compatible, C++, higher performance), HBase (on HDFS, CP, Bigtable-style), Google Bigtable (managed, powers Search/Maps/Analytics).

Example (Cassandra CQL):

-- Model the table for the query: "recent events for a device, newest first"
CREATE TABLE events_by_device (
  device_id   text,
  event_time  timestamp,
  event_type  text,
  payload     text,
  PRIMARY KEY (device_id, event_time)
) WITH CLUSTERING ORDER BY (event_time DESC);

-- Write
INSERT INTO events_by_device (device_id, event_time, event_type, payload)
VALUES ('dev-42', '2026-07-19T10:00:00Z', 'temp', '{"c":21.5}');

-- Read: efficient, hits one partition, already sorted
SELECT * FROM events_by_device
WHERE device_id = 'dev-42'
LIMIT 100;

The partition key (device_id) determines which node holds the data; the clustering column (event_time) determines sort order within it. Choosing partition keys well (to avoid “hot partitions” and unbounded partition growth) is the central skill.

Graph databases

Model data as nodes (entities) connected by edges (relationships), both of which can hold properties. They excel when relationships are the point — traversing “friends of friends”, finding shortest paths, or detecting rings of connected fraud accounts — queries that would require many expensive joins in SQL.

Products: Neo4j (most popular; Cypher query language), Dgraph (distributed, GraphQL-native), Amazon Neptune (managed; supports Gremlin and SPARQL).

Example (Neo4j Cypher):

// Create people and a friendship
CREATE (alice:Person {name: 'Alice'})
CREATE (bob:Person {name: 'Bob'})
CREATE (carol:Person {name: 'Carol'})
CREATE (alice)-[:FRIENDS_WITH]->(bob)
CREATE (bob)-[:FRIENDS_WITH]->(carol);

// Friends-of-friends of Alice she isn't already friends with
MATCH (alice:Person {name: 'Alice'})-[:FRIENDS_WITH]->(:Person)
      -[:FRIENDS_WITH]->(fof:Person)
WHERE NOT (alice)-[:FRIENDS_WITH]->(fof) AND fof <> alice
RETURN DISTINCT fof.name;

Traversal cost depends on the number of relationships walked, not the total dataset size — so deep relationship queries stay fast even as data grows.

Specialized data stores

Beyond the four classic families, several purpose-built stores are common in backends:

Data modeling for NoSQL

Modeling for NoSQL is fundamentally different from relational modeling. In SQL you normalize first and let joins reassemble data. In NoSQL you model around access patterns and often denormalize aggressively.

Single-table design (DynamoDB): A well-known advanced pattern where multiple entity types live in one table, distinguished by carefully composed partition keys (PK) and sort keys (SK). This lets a single query fetch related items (e.g., a user and all their orders) without joins.

PKSKAttributes
USER#42PROFILE#42name, email
USER#42ORDER#1001total, status, date
USER#42ORDER#1002total, status, date
# One query returns the user profile AND all their orders:
Query where PK = "USER#42"
# Filter to just orders:
Query where PK = "USER#42" AND begins_with(SK, "ORDER#")

The design principle: because DynamoDB has no joins and charges per request, you co-locate related items under the same partition key so they can be read in one efficient query.

Cross-family comparison

Key-valueDocumentWide-columnGraph
Data modelKey → opaque valueCollections of JSON documentsPartitioned rows, dynamic columnsNodes + edges + properties
Query capabilityBy key onlyRich queries on any fieldPartition/clustering keys; limited ad hocTraversals, pattern matching
ConsistencyTunable (often eventual)Tunable; MongoDB defaults strong on primaryTunable (Cassandra quorum)Usually strong (Neo4j ACID)
ScalingExcellent horizontalGood (sharding)Excellent horizontalHarder to distribute
Best use caseCache, sessions, countersApp data, catalogs, profilesTime-series, logs, feeds at scaleRelationships, social, fraud
Weak atQuerying by valueCross-document joinsAd hoc queries, joinsVery high write volume, sharding

Best Practices

References