[{"data":1,"prerenderedAt":1430},["ShallowReactive",2],{"content:\u002F10-databases\u002F08-database-types-beyond-postgres":3},{"title":4,"description":5,"path":6,"body":7},"Другие типы БД","PostgreSQL - сильная база общего назначения. Она умеет транзакции, индексы, JSONB, full-text search, partitioning, extensions, replication и многое другое. Поэтому первый вопрос при выборе новой БД:","\u002F10-databases\u002F08-database-types-beyond-postgres",{"type":8,"value":9,"toc":1400},"minimark",[10,14,17,28,31,34,37,42,223,225,229,232,257,295,298,300,304,308,319,347,350,356,359,361,364,367,392,395,397,400,403,428,431,433,436,439,464,471,473,476,479,504,507,509,512,515,540,551,553,557,560,585,588,590,593,596,621,624,626,630,633,658,661,663,667,670,695,698,700,704,707,732,735,737,741,813,815,819,822,861,864,941,943,947,950,953,967,970,987,990,1010,1012,1016,1019,1022,1042,1045,1062,1065,1067,1071,1075,1089,1093,1107,1111,1125,1127,1131,1157,1159,1163,1183,1185,1189,1220,1355,1357,1361,1396],[11,12,4],"h1",{"id":13},"другие-типы-бд",[15,16,5],"p",{},[18,19,25],"pre",{"className":20,"code":22,"language":23,"meta":24},[21],"language-text","Почему PostgreSQL недостаточно?\n","text","",[26,27,22],"code",{"__ignoreMap":24},[15,29,30],{},"Хорошие причины бывают: latency в миллисекунды или микросекунды, горизонтальный write scale, поиск с relevance, графовые обходы, аналитика по миллиардам строк, append-only log событий, дешёвый object storage.",[15,32,33],{},"Но новая БД приносит operational cost: backup, monitoring, upgrades, security, schema evolution, capacity planning, client libraries, hiring и on-call knowledge.",[35,36],"hr",{},[38,39,41],"h2",{"id":40},"главная-карта","Главная карта",[43,44,45,65],"table",{},[46,47,48],"thead",{},[49,50,51,56,59,62],"tr",{},[52,53,55],"th",{"align":54},"left","Тип",[52,57,58],{"align":54},"Примеры",[52,60,61],{"align":54},"Основная идея",[52,63,64],{"align":54},"Когда смотреть",[66,67,68,83,97,111,125,139,153,167,181,195,209],"tbody",{},[49,69,70,74,77,80],{},[71,72,73],"td",{"align":54},"Key-value",[71,75,76],{"align":54},"Redis, DynamoDB, FoundationDB KV",[71,78,79],{"align":54},"Быстрый доступ по ключу.",[71,81,82],{"align":54},"Cache, session, rate limit, idempotency.",[49,84,85,88,91,94],{},[71,86,87],{"align":54},"Document",[71,89,90],{"align":54},"MongoDB, Couchbase, Firestore",[71,92,93],{"align":54},"Документ как единица хранения.",[71,95,96],{"align":54},"Гибкая структура, aggregate целиком.",[49,98,99,102,105,108],{},[71,100,101],{"align":54},"Wide-column",[71,103,104],{"align":54},"Cassandra, HBase, ScyllaDB",[71,106,107],{"align":54},"Распределённые таблицы под write-heavy.",[71,109,110],{"align":54},"Огромный write throughput, predictable access.",[49,112,113,116,119,122],{},[71,114,115],{"align":54},"Graph",[71,117,118],{"align":54},"Neo4j, JanusGraph, Neptune",[71,120,121],{"align":54},"Связи и обход графа first-class.",[71,123,124],{"align":54},"Social graph, fraud graph, recommendations.",[49,126,127,130,133,136],{},[71,128,129],{"align":54},"Search",[71,131,132],{"align":54},"Elasticsearch, OpenSearch, Solr",[71,134,135],{"align":54},"Inverted index, relevance, fuzzy search.",[71,137,138],{"align":54},"Поиск по тексту, faceting, ranking.",[49,140,141,144,147,150],{},[71,142,143],{"align":54},"Time-series",[71,145,146],{"align":54},"TimescaleDB, InfluxDB, VictoriaMetrics",[71,148,149],{"align":54},"Метрики и события во времени.",[71,151,152],{"align":54},"Monitoring, IoT, market data.",[49,154,155,158,161,164],{},[71,156,157],{"align":54},"OLAP\u002Fcolumnar",[71,159,160],{"align":54},"ClickHouse, BigQuery, Snowflake, DuckDB",[71,162,163],{"align":54},"Колонки и большие scan'ы.",[71,165,166],{"align":54},"Analytics, dashboards, aggregates.",[49,168,169,172,175,178],{},[71,170,171],{"align":54},"In-memory",[71,173,174],{"align":54},"Redis, Memcached, Hazelcast",[71,176,177],{"align":54},"Данные в памяти ради latency.",[71,179,180],{"align":54},"Hot data, cache, counters.",[49,182,183,186,189,192],{},[71,184,185],{"align":54},"Object storage\u002Flakehouse",[71,187,188],{"align":54},"S3, GCS, MinIO, Iceberg, Delta Lake",[71,190,191],{"align":54},"Файлы как дешёвый слой данных.",[71,193,194],{"align":54},"Data lake, архив, ML datasets.",[49,196,197,200,203,206],{},[71,198,199],{"align":54},"NewSQL\u002Fdistributed SQL",[71,201,202],{"align":54},"CockroachDB, YugabyteDB, Spanner",[71,204,205],{"align":54},"SQL + распределение + транзакции.",[71,207,208],{"align":54},"Multi-region SQL, horizontal scale.",[49,210,211,214,217,220],{},[71,212,213],{"align":54},"Message\u002Fevent stores",[71,215,216],{"align":54},"Kafka, Redpanda, NATS JetStream, EventStoreDB",[71,218,219],{"align":54},"Append-only stream событий.",[71,221,222],{"align":54},"Event-driven systems, replay, integration.",[35,224],{},[38,226,228],{"id":227},"cap-без-магии","CAP без магии",[15,230,231],{},"CAP грубо говорит: при network partition распределённая система выбирает между consistency и availability. В работе важнее конкретные вопросы:",[233,234,235,239,242,245,248,251,254],"ul",{},[236,237,238],"li",{},"что увидит клиент сразу после записи;",[236,240,241],{},"можно ли читать stale данные;",[236,243,244],{},"сколько replicas подтверждают запись;",[236,246,247],{},"что происходит при потере datacenter;",[236,249,250],{},"какая latency между регионами;",[236,252,253],{},"как система выходит из split-brain;",[236,255,256],{},"кто будет это поддерживать ночью.",[43,258,259,269],{},[46,260,261],{},[49,262,263,266],{},[52,264,265],{"align":54},"Термин",[52,267,268],{"align":54},"Смысл",[66,270,271,279,287],{},[49,272,273,276],{},[71,274,275],{"align":54},"Strong consistency",[71,277,278],{"align":54},"После успешной записи следующие чтения видят новое значение.",[49,280,281,284],{},[71,282,283],{"align":54},"Eventual consistency",[71,285,286],{"align":54},"Данные сходятся со временем, но сразу после записи возможна старая версия.",[49,288,289,292],{},[71,290,291],{"align":54},"Causal\u002Fsession consistency",[71,293,294],{"align":54},"Клиент видит свои записи и причинный порядок, но не обязательно глобальную линейность.",[15,296,297],{},"PostgreSQL на primary обычно даёт сильную консистентность для записей. Read replicas могут отставать. Kafka даёт порядок внутри partition, но не заменяет произвольные SQL-транзакции. Redis часто выбирают ради latency, а durability\u002Fconsistency зависят от режима.",[35,299],{},[38,301,303],{"id":302},"семейства-бд","Семейства БД",[305,306,73],"h3",{"id":307},"key-value",[15,309,310,311,314,315,318],{},"Суть: ",[26,312,313],{},"GET key",", ",[26,316,317],{},"SET key value",", TTL, atomic counters, conditional writes.",[43,320,321,334],{},[46,322,323],{},[49,324,325,328,331],{},[52,326,327],{"align":54},"Подходит",[52,329,330],{"align":54},"Не подходит",[52,332,333],{"align":54},"Цена",[66,335,336],{},[49,337,338,341,344],{},[71,339,340],{"align":54},"Cache, sessions, feature flags, rate limits, idempotency keys, counters.",[71,342,343],{"align":54},"Joins, ad-hoc queries, отчёты, сложные constraints.",[71,345,346],{"align":54},"Нужно проектировать key lifecycle и понимать consistency\u002Fdurability.",[15,348,349],{},"Пример key design:",[18,351,354],{"className":352,"code":353,"language":23,"meta":24},[21],"user:{id}\ncourse:{slug}\nrate_limit:{user_id}:{route}:{minute}\nidempotency:{user_id}:{key}\n",[26,355,353],{"__ignoreMap":24},[15,357,358],{},"Плохой key design превращает Redis\u002FDynamoDB в набор случайных строк без понятного lifecycle.",[35,360],{},[305,362,87],{"id":363},"document",[15,365,366],{},"Суть: данные хранятся документами, чаще JSON\u002FBSON-like. Документ может содержать вложенные объекты и массивы.",[43,368,369,379],{},[46,370,371],{},[49,372,373,375,377],{},[52,374,327],{"align":54},[52,376,330],{"align":54},[52,378,333],{"align":54},[66,380,381],{},[49,382,383,386,389],{},[71,384,385],{"align":54},"Aggregate читается и пишется целиком, структура часто меняется, nested data естественны.",[71,387,388],{"align":54},"Сложные joins, строгие cross-document constraints, много ad-hoc аналитики.",[71,390,391],{"align":54},"Легко задублировать данные и получить сложную миграцию документов.",[15,393,394],{},"Полезный вопрос: документ - это граница консистентности или просто удобная упаковка JSON? Если нужны связи и инварианты между сущностями, PostgreSQL часто проще.",[35,396],{},[305,398,101],{"id":399},"wide-column",[15,401,402],{},"Суть: огромные распределённые таблицы, оптимизированные под запись и заранее известные access patterns.",[43,404,405,415],{},[46,406,407],{},[49,408,409,411,413],{},[52,410,327],{"align":54},[52,412,330],{"align":54},[52,414,333],{"align":54},[66,416,417],{},[49,418,419,422,425],{},[71,420,421],{"align":54},"Write-heavy events, logs, telemetry, глобально распределённые данные.",[71,423,424],{"align":54},"Произвольные запросы, joins, частая смена схемы чтения.",[71,426,427],{"align":54},"Сначала проектируется запрос, потом таблица; плохой partition key дорог.",[15,429,430],{},"Главный навык - выбрать partition key и clustering так, чтобы нагрузка не собиралась в hot partitions.",[35,432],{},[305,434,115],{"id":435},"graph",[15,437,438],{},"Суть: вершины, рёбра и быстрые обходы связей.",[43,440,441,451],{},[46,442,443],{},[49,444,445,447,449],{},[52,446,327],{"align":54},[52,448,330],{"align":54},[52,450,333],{"align":54},[66,452,453],{},[49,454,455,458,461],{},[71,456,457],{"align":54},"Fraud detection, recommendations, social graph, dependency graph, permission graph.",[71,459,460],{"align":54},"Обычный CRUD, отчёты, simple lookup, транзакционная система заказов.",[71,462,463],{"align":54},"Нужно учить query language и отдельно эксплуатировать graph engine.",[15,465,466,467,470],{},"Если задача звучит как “найди путь”, “найди соседей N-го уровня”, “найди подозрительный паттерн связей”, graph DB может быть уместна. Если нужна просто связь ",[26,468,469],{},"user_id -> orders",", хватит PostgreSQL.",[35,472],{},[305,474,129],{"id":475},"search",[15,477,478],{},"Суть: inverted index, tokenization, ranking, fuzzy search, autocomplete, facets.",[43,480,481,491],{},[46,482,483],{},[49,484,485,487,489],{},[52,486,327],{"align":54},[52,488,330],{"align":54},[52,490,333],{"align":54},[66,492,493],{},[49,494,495,498,501],{},[71,496,497],{"align":54},"Поиск по тексту, relevance, typo tolerance, autocomplete, filters + ranking.",[71,499,500],{"align":54},"Source of truth, строгие транзакции, финансовые инварианты.",[71,502,503],{"align":54},"Индекс надо синхронизировать с primary DB и переиндексировать при изменении mapping.",[15,505,506],{},"PostgreSQL full-text search хорош для умеренных задач. Elasticsearch\u002FOpenSearch выбирают, когда поиск становится отдельным продуктовым сценарием.",[35,508],{},[305,510,143],{"id":511},"time-series",[15,513,514],{},"Суть: данные почти всегда имеют timestamp, часто пишутся append-only и читаются агрегатами по окнам.",[43,516,517,527],{},[46,518,519],{},[49,520,521,523,525],{},[52,522,327],{"align":54},[52,524,330],{"align":54},[52,526,333],{"align":54},[66,528,529],{},[49,530,531,534,537],{},[71,532,533],{"align":54},"Metrics, logs-derived metrics, IoT, monitoring, market quotes.",[71,535,536],{"align":54},"Сложные mutable entities, транзакционный CRUD, произвольные связи.",[71,538,539],{"align":54},"Нужны retention, downsampling, cardinality control.",[15,541,542,543,546,547,550],{},"Главная ловушка - cardinality: label вроде ",[26,544,545],{},"user_id"," или ",[26,548,549],{},"request_id"," может резко раздуть число series.",[35,552],{},[305,554,556],{"id":555},"olap-и-columnar","OLAP и columnar",[15,558,559],{},"Суть: хранение по колонкам и быстрые scan'ы больших объёмов для аналитики.",[43,561,562,572],{},[46,563,564],{},[49,565,566,568,570],{},[52,567,327],{"align":54},[52,569,330],{"align":54},[52,571,333],{"align":54},[66,573,574],{},[49,575,576,579,582],{},[71,577,578],{"align":54},"Dashboards, aggregates, product analytics, BI, event analytics.",[71,580,581],{"align":54},"OLTP-транзакции, frequent point updates, strict row-level invariants.",[71,583,584],{"align":54},"Обычно нужна ETL\u002FELT pipeline и отдельная модель данных.",[15,586,587],{},"PostgreSQL удобен для operational reports. ClickHouse\u002FBigQuery\u002FSnowflake появляются, когда отчёты начинают мешать OLTP или требуют scan'ов по огромным таблицам.",[35,589],{},[305,591,171],{"id":592},"in-memory",[15,594,595],{},"Суть: данные держатся в памяти ради скорости.",[43,597,598,608],{},[46,599,600],{},[49,601,602,604,606],{},[52,603,327],{"align":54},[52,605,330],{"align":54},[52,607,333],{"align":54},[66,609,610],{},[49,611,612,615,618],{},[71,613,614],{"align":54},"Cache, counters, locks с TTL, hot lookups, pub\u002Fsub в простых сценариях.",[71,616,617],{"align":54},"Единственное хранилище критичных данных без понимания persistence.",[71,619,620],{"align":54},"Memory дороже disk, eviction и persistence надо настроить.",[15,622,623],{},"Redis может быть cache, queue-like инструментом, rate limiter, lock service. Но “быстро” не означает “можно забыть о durability и consistency”.",[35,625],{},[305,627,629],{"id":628},"object-storage-и-lakehouse","Object storage и lakehouse",[15,631,632],{},"Суть: данные лежат файлами: Parquet\u002FJSON\u002FCSV\u002FAvro в S3\u002FGCS\u002FMinIO, поверх могут быть Iceberg\u002FDelta\u002FHudi.",[43,634,635,645],{},[46,636,637],{},[49,638,639,641,643],{},[52,640,327],{"align":54},[52,642,330],{"align":54},[52,644,333],{"align":54},[66,646,647],{},[49,648,649,652,655],{},[71,650,651],{"align":54},"Архив, data lake, ML datasets, дешёвое хранение событий, batch analytics.",[71,653,654],{"align":54},"Low-latency transactional reads\u002Fwrites, constraints, request path.",[71,656,657],{"align":54},"Нужны catalog, partitioning, compaction, schema evolution.",[15,659,660],{},"Это слой данных, а не замена OLTP-базе для приложения.",[35,662],{},[305,664,666],{"id":665},"newsql-и-distributed-sql","NewSQL и distributed SQL",[15,668,669],{},"Суть: SQL и транзакции поверх распределённого storage.",[43,671,672,682],{},[46,673,674],{},[49,675,676,678,680],{},[52,677,327],{"align":54},[52,679,330],{"align":54},[52,681,333],{"align":54},[66,683,684],{},[49,685,686,689,692],{},[71,687,688],{"align":54},"Multi-region, horizontal scale, global consistency, SQL API.",[71,690,691],{"align":54},"Маленький сервис, где обычный PostgreSQL проще и дешевле.",[71,693,694],{"align":54},"Latency consensus, сложная эксплуатация, особенности SQL dialect.",[15,696,697],{},"Главный вопрос: вам реально нужна распределённая транзакционность или достаточно PostgreSQL primary + replicas + хорошего partitioning?",[35,699],{},[305,701,703],{"id":702},"message-и-event-stores","Message и event stores",[15,705,706],{},"Суть: append-only stream событий. Kafka\u002FRedpanda\u002FNATS JetStream\u002FEventStoreDB хранят историю изменений, которую можно читать заново.",[43,708,709,719],{},[46,710,711],{},[49,712,713,715,717],{},[52,714,327],{"align":54},[52,716,330],{"align":54},[52,718,333],{"align":54},[66,720,721],{},[49,722,723,726,729],{},[71,724,725],{"align":54},"Event-driven integration, replay, audit trail, async processing, stream processing.",[71,727,728],{"align":54},"Произвольные queries по текущему состоянию, relational constraints, direct user-facing CRUD.",[71,730,731],{"align":54},"Нужны partitions, offsets, consumer groups, дедупликация и schema evolution.",[15,733,734],{},"Kafka - не “быстрая БД по ключу”. Обычно рядом нужна read model: PostgreSQL, Redis, Elasticsearch, ClickHouse или другая материализация.",[35,736],{},[38,738,740],{"id":739},"границы-знакомых-инструментов","Границы знакомых инструментов",[43,742,743,756],{},[46,744,745],{},[49,746,747,750,753],{},[52,748,749],{"align":54},"Инструмент",[52,751,752],{"align":54},"Силен как",[52,754,755],{"align":54},"Плох как",[66,757,758,769,780,791,802],{},[49,759,760,763,766],{},[71,761,762],{"align":54},"PostgreSQL",[71,764,765],{"align":54},"Source of truth, OLTP, constraints, умеренный search\u002FJSON\u002Fanalytics.",[71,767,768],{"align":54},"Бесконечный event log, тяжёлый OLAP по миллиардам строк, глобальный write scale без архитектуры.",[49,770,771,774,777],{},[71,772,773],{"align":54},"Redis",[71,775,776],{"align":54},"Cache, TTL, counters, rate limit, short-lived coordination.",[71,778,779],{"align":54},"Единственная БД для критичных mutable данных без persistence strategy.",[49,781,782,785,788],{},[71,783,784],{"align":54},"Kafka",[71,786,787],{"align":54},"Durable ordered log, интеграция сервисов, replay, stream processing.",[71,789,790],{"align":54},"Query engine, cache, transactional relational DB.",[49,792,793,796,799],{},[71,794,795],{"align":54},"Elasticsearch\u002FOpenSearch",[71,797,798],{"align":54},"Поиск, ranking, facets, autocomplete.",[71,800,801],{"align":54},"Source of truth для финансовых или строго консистентных данных.",[49,803,804,807,810],{},[71,805,806],{"align":54},"ClickHouse",[71,808,809],{"align":54},"Быстрая аналитика и агрегаты.",[71,811,812],{"align":54},"OLTP с частыми updates и transactional constraints.",[35,814],{},[38,816,818],{"id":817},"как-выбирать-бд","Как выбирать БД",[15,820,821],{},"Перед добавлением новой БД ответьте письменно:",[823,824,825,828,831,834,837,840,843,846,849,852,855,858],"ol",{},[236,826,827],{},"Какой главный access pattern?",[236,829,830],{},"Какие consistency требования?",[236,832,833],{},"Что является source of truth?",[236,835,836],{},"Какая допустимая stale-ness?",[236,838,839],{},"Как делать backup\u002Frestore?",[236,841,842],{},"Как мониторить и алертить?",[236,844,845],{},"Кто будет поддерживать это в on-call?",[236,847,848],{},"Как мигрировать schema\u002Fdata?",[236,850,851],{},"Как тестировать локально и в CI?",[236,853,854],{},"Что будет, если новая БД недоступна?",[236,856,857],{},"Как данные будут согласованы с другими хранилищами?",[236,859,860],{},"По каким критериям мы поймём, что решение надо откатить или заменить?",[15,862,863],{},"Сводная таблица:",[43,865,866,876],{},[46,867,868],{},[49,869,870,873],{},[52,871,872],{"align":54},"Нужда",[52,874,875],{"align":54},"Частый выбор",[66,877,878,885,893,901,909,917,925,933],{},[49,879,880,883],{},[71,881,882],{"align":54},"Надёжный OLTP и constraints",[71,884,762],{"align":54},[49,886,887,890],{},[71,888,889],{"align":54},"Cache и TTL",[71,891,892],{"align":54},"Redis\u002FMemcached",[49,894,895,898],{},[71,896,897],{"align":54},"Текстовый поиск",[71,899,900],{"align":54},"PostgreSQL FTS -> OpenSearch\u002FElasticsearch",[49,902,903,906],{},[71,904,905],{"align":54},"Метрики",[71,907,908],{"align":54},"Prometheus\u002FVictoriaMetrics\u002FInfluxDB\u002FTimescaleDB",[49,910,911,914],{},[71,912,913],{"align":54},"Product analytics",[71,915,916],{"align":54},"ClickHouse\u002FBigQuery\u002FSnowflake",[49,918,919,922],{},[71,920,921],{"align":54},"Event log",[71,923,924],{"align":54},"Kafka\u002FRedpanda\u002FNATS JetStream",[49,926,927,930],{},[71,928,929],{"align":54},"Графовые обходы",[71,931,932],{"align":54},"Neo4j\u002FNeptune\u002FJanusGraph",[49,934,935,938],{},[71,936,937],{"align":54},"Multi-region SQL",[71,939,940],{"align":54},"Spanner\u002FCockroachDB\u002FYugabyteDB",[35,942],{},[38,944,946],{"id":945},"multi-store-consistency","Multi-store consistency",[15,948,949],{},"Как только появляется второе хранилище, появляется вопрос: что считается правдой и как расходящиеся копии сходятся обратно.",[15,951,952],{},"Типичные пары:",[233,954,955,958,961,964],{},[236,956,957],{},"PostgreSQL + Redis cache: PostgreSQL source of truth, Redis можно удалить и восстановить.",[236,959,960],{},"PostgreSQL + Elasticsearch\u002FOpenSearch: поиск является index\u002Fread model, нужна reindex strategy.",[236,962,963],{},"PostgreSQL + Kafka + ClickHouse: события публикуются через outbox, аналитика eventually consistent.",[236,965,966],{},"PostgreSQL + object storage: metadata в БД, blob\u002Ffile в storage, нужна cleanup\u002Freconciliation job.",[15,968,969],{},"Риски:",[233,971,972,975,978,981,984],{},[236,973,974],{},"dual writes без transaction boundary: запись в БД прошла, запись во второе хранилище нет;",[236,976,977],{},"stale reads: пользователь видит старый search\u002Fcache\u002Fanalytics результат после успешного write;",[236,979,980],{},"replay duplicates: consumer обработал событие дважды;",[236,982,983],{},"ordering gaps: события разных partitions приходят не в глобальном порядке;",[236,985,986],{},"schema drift: producer, consumer и storage ожидают разные поля.",[15,988,989],{},"Практичные default'ы:",[233,991,992,995,998,1001,1004,1007],{},[236,993,994],{},"один явный source of truth;",[236,996,997],{},"outbox\u002Finbox или change data capture вместо ручных dual writes;",[236,999,1000],{},"идемпотентные consumers и уникальные ключи обработки;",[236,1002,1003],{},"reconciliation job, который находит расхождения;",[236,1005,1006],{},"понятная stale-ness policy в API и UI;",[236,1008,1009],{},"метрики lag, reindex progress, dead-letter\u002Fretry count.",[35,1011],{},[38,1013,1015],{"id":1014},"adoption-и-exit-criteria","Adoption и exit criteria",[15,1017,1018],{},"Новая БД должна пройти не только happy-path demo, но и operational gate.",[15,1020,1021],{},"Adoption criteria:",[233,1023,1024,1027,1030,1033,1036,1039],{},[236,1025,1026],{},"есть workload, который PostgreSQL не закрывает приемлемо по latency, scale, cost или search\u002Frelevance;",[236,1028,1029],{},"описаны owner, runbook, backup\u002Frestore, upgrade path и security model;",[236,1031,1032],{},"есть локальный\u002FCI способ тестировать integration;",[236,1034,1035],{},"понятны consistency guarantees, stale-ness и failure behavior;",[236,1037,1038],{},"есть metrics\u002Falerts и capacity baseline;",[236,1040,1041],{},"команда умеет выполнить restore\u002Freindex\u002Freplay без ручной магии.",[15,1043,1044],{},"Exit criteria:",[233,1046,1047,1050,1053,1056,1059],{},[236,1048,1049],{},"SLO не улучшается или operational cost выше выигрыша;",[236,1051,1052],{},"данные регулярно расходятся, а reconciliation не успевает;",[236,1054,1055],{},"on-call не может диагностировать инцидент без одного \"знающего человека\";",[236,1057,1058],{},"vendor\u002Fкластер слишком дорог для нагрузки;",[236,1060,1061],{},"feature можно вернуть в PostgreSQL проще и безопаснее.",[15,1063,1064],{},"Exit criteria лучше записывать до внедрения. Иначе новая технология становится постоянной только потому, что её уже жалко удалять.",[35,1066],{},[38,1068,1070],{"id":1069},"практические-сценарии","Практические сценарии",[305,1072,1074],{"id":1073},"онлайн-курс","Онлайн-курс",[233,1076,1077,1080,1083,1086],{},[236,1078,1079],{},"PostgreSQL: users, courses, lessons, progress, payments.",[236,1081,1082],{},"Redis: sessions, rate limit, cache популярных страниц.",[236,1084,1085],{},"Search: поиск по урокам, если PostgreSQL FTS перестал хватать.",[236,1087,1088],{},"ClickHouse: продуктовая аналитика по просмотрам и прохождениям.",[305,1090,1092],{"id":1091},"финтех-платёж","Финтех-платёж",[233,1094,1095,1098,1101,1104],{},[236,1096,1097],{},"PostgreSQL: ledger, payments, constraints, idempotency.",[236,1099,1100],{},"Kafka\u002FRedpanda: события для интеграций и downstream-сервисов.",[236,1102,1103],{},"Redis: rate limit и краткоживущие locks, но не ledger.",[236,1105,1106],{},"ClickHouse: аналитика и reconciliation reports.",[305,1108,1110],{"id":1109},"monitoring-system","Monitoring system",[233,1112,1113,1116,1119,1122],{},[236,1114,1115],{},"Time-series DB: метрики.",[236,1117,1118],{},"Object storage: долгий архив.",[236,1120,1121],{},"Kafka: ingestion pipeline.",[236,1123,1124],{},"PostgreSQL: пользователи, настройки, dashboards.",[35,1126],{},[38,1128,1130],{"id":1129},"что-запомнить","Что запомнить",[233,1132,1133,1136,1139,1142,1145,1148,1151,1154],{},[236,1134,1135],{},"PostgreSQL - baseline. Новая БД должна решать конкретную боль, а не добавляться “потому что модно”.",[236,1137,1138],{},"Выбор БД начинается с access pattern и consistency требований.",[236,1140,1141],{},"Redis - не Kafka, Kafka - не PostgreSQL, Elasticsearch - не source of truth.",[236,1143,1144],{},"При нескольких хранилищах явно называйте source of truth, stale-ness policy и reconciliation path.",[236,1146,1147],{},"Новая БД должна иметь adoption и exit criteria, а не только proof of concept.",[236,1149,1150],{},"Для distributed systems важно не только CAP, но и operational cost.",[236,1152,1153],{},"Почти каждая специализированная БД требует отдельной модели данных и отдельного on-call знания.",[236,1155,1156],{},"Source of truth должен быть назван явно.",[35,1158],{},[38,1160,1162],{"id":1161},"практика","Практика",[823,1164,1165,1168,1171,1174,1177,1180],{},[236,1166,1167],{},"Для учебной платформы выпишите 5 access patterns и выберите, какие остаются в PostgreSQL.",[236,1169,1170],{},"Спроектируйте Redis keys для sessions, rate limits и idempotency. Укажите TTL и владельца данных.",[236,1172,1173],{},"Опишите pipeline “PostgreSQL -> outbox -> Kafka -> ClickHouse” для аналитики прохождения уроков.",[236,1175,1176],{},"Решите, нужен ли Elasticsearch для поиска по урокам, если данных 10 тысяч, 1 миллион и 100 миллионов документов.",[236,1178,1179],{},"Для monitoring-системы выберите storage для hot metrics, cold archive и user settings.",[236,1181,1182],{},"Для пары PostgreSQL + search index опишите reindex, stale reads и reconciliation.",[35,1184],{},[38,1186,1188],{"id":1187},"интерактивная-практика","Интерактивная практика",[1190,1191,1195,1198,1215],"quiz",{"answer":1192,"id":1193,"xp":1194},"1","db-beyond-q1","10",[15,1196,1197],{},"С чего лучше начинать выбор новой базы данных?",[1199,1200,1201],"template",{"v-slot:options":24},[233,1202,1203,1206,1209,1212],{},[236,1204,1205],{},"С access patterns, consistency требований и операционной цены",[236,1207,1208],{},"С популярности технологии в статьях",[236,1210,1211],{},"С желания заменить PostgreSQL целиком",[236,1213,1214],{},"С того, что у команды уже есть Kubernetes",[1199,1216,1217],{"v-slot:explanation":24},[15,1218,1219],{},"Новая БД должна решать конкретный workload и иметь понятные guarantees, on-call модель и exit criteria.",[1221,1222,1226,1229,1350],"predict",{"answer":1223,"id":1224,"xp":1225},"source-of-truth\\nread-index","db-beyond-p1","15",[15,1227,1228],{},"Что вернёт запрос?",[1199,1230,1231],{"v-slot:code":24},[18,1232,1236],{"className":1233,"code":1234,"language":1235,"meta":24,"style":24},"language-sql shiki shiki-themes github-dark","WITH stores(name) AS (\n    VALUES ('postgres-ledger'), ('search')\n)\nSELECT CASE\n    WHEN name = 'postgres-ledger' THEN 'source-of-truth'\n    ELSE 'read-index'\nEND AS role\nFROM stores;\n","sql",[26,1237,1238,1263,1285,1290,1299,1320,1329,1341],{"__ignoreMap":24},[1239,1240,1243,1247,1251,1254,1257,1260],"span",{"class":1241,"line":1242},"line",1,[1239,1244,1246],{"class":1245},"snl16","WITH",[1239,1248,1250],{"class":1249},"s95oV"," stores(",[1239,1252,1253],{"class":1245},"name",[1239,1255,1256],{"class":1249},") ",[1239,1258,1259],{"class":1245},"AS",[1239,1261,1262],{"class":1249}," (\n",[1239,1264,1266,1269,1272,1276,1279,1282],{"class":1241,"line":1265},2,[1239,1267,1268],{"class":1245},"    VALUES",[1239,1270,1271],{"class":1249}," (",[1239,1273,1275],{"class":1274},"sU2Wk","'postgres-ledger'",[1239,1277,1278],{"class":1249},"), (",[1239,1280,1281],{"class":1274},"'search'",[1239,1283,1284],{"class":1249},")\n",[1239,1286,1288],{"class":1241,"line":1287},3,[1239,1289,1284],{"class":1249},[1239,1291,1293,1296],{"class":1241,"line":1292},4,[1239,1294,1295],{"class":1245},"SELECT",[1239,1297,1298],{"class":1245}," CASE\n",[1239,1300,1302,1305,1308,1311,1314,1317],{"class":1241,"line":1301},5,[1239,1303,1304],{"class":1245},"    WHEN",[1239,1306,1307],{"class":1245}," name",[1239,1309,1310],{"class":1245}," =",[1239,1312,1313],{"class":1274}," 'postgres-ledger'",[1239,1315,1316],{"class":1245}," THEN",[1239,1318,1319],{"class":1274}," 'source-of-truth'\n",[1239,1321,1323,1326],{"class":1241,"line":1322},6,[1239,1324,1325],{"class":1245},"    ELSE",[1239,1327,1328],{"class":1274}," 'read-index'\n",[1239,1330,1332,1335,1338],{"class":1241,"line":1331},7,[1239,1333,1334],{"class":1245},"END",[1239,1336,1337],{"class":1245}," AS",[1239,1339,1340],{"class":1245}," role\n",[1239,1342,1344,1347],{"class":1241,"line":1343},8,[1239,1345,1346],{"class":1245},"FROM",[1239,1348,1349],{"class":1249}," stores;\n",[1199,1351,1352],{"v-slot:hint":24},[15,1353,1354],{},"Search index часто ускоряет чтение, но обычно не становится главным владельцем бизнес-фактов.",[35,1356],{},[38,1358,1360],{"id":1359},"что-спросят-на-собеседовании","Что спросят на собеседовании",[233,1362,1363,1366,1369,1372,1375,1378,1381,1384,1387,1390,1393],{},[236,1364,1365],{},"Почему нельзя выбирать NoSQL просто “для масштаба”?",[236,1367,1368],{},"Чем Redis отличается от Kafka?",[236,1370,1371],{},"Почему Elasticsearch обычно не source of truth?",[236,1373,1374],{},"Что такое eventual consistency?",[236,1376,1377],{},"Почему read replicas PostgreSQL могут отдавать stale данные?",[236,1379,1380],{},"Что такое partition key и чем опасен hot partition?",[236,1382,1383],{},"Когда ClickHouse лучше PostgreSQL?",[236,1385,1386],{},"Что ломается, если использовать Kafka как обычную БД?",[236,1388,1389],{},"Почему dual writes между двумя хранилищами опасны?",[236,1391,1392],{},"Какие exit criteria стоит записать перед внедрением новой БД?",[236,1394,1395],{},"Какие вопросы надо задать перед добавлением новой БД в сервис?",[1397,1398,1399],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":24,"searchDepth":1265,"depth":1265,"links":1401},[1402,1403,1404,1417,1418,1419,1420,1421,1426,1427,1428,1429],{"id":40,"depth":1265,"text":41},{"id":227,"depth":1265,"text":228},{"id":302,"depth":1265,"text":303,"children":1405},[1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416],{"id":307,"depth":1287,"text":73},{"id":363,"depth":1287,"text":87},{"id":399,"depth":1287,"text":101},{"id":435,"depth":1287,"text":115},{"id":475,"depth":1287,"text":129},{"id":511,"depth":1287,"text":143},{"id":555,"depth":1287,"text":556},{"id":592,"depth":1287,"text":171},{"id":628,"depth":1287,"text":629},{"id":665,"depth":1287,"text":666},{"id":702,"depth":1287,"text":703},{"id":739,"depth":1265,"text":740},{"id":817,"depth":1265,"text":818},{"id":945,"depth":1265,"text":946},{"id":1014,"depth":1265,"text":1015},{"id":1069,"depth":1265,"text":1070,"children":1422},[1423,1424,1425],{"id":1073,"depth":1287,"text":1074},{"id":1091,"depth":1287,"text":1092},{"id":1109,"depth":1287,"text":1110},{"id":1129,"depth":1265,"text":1130},{"id":1161,"depth":1265,"text":1162},{"id":1187,"depth":1265,"text":1188},{"id":1359,"depth":1265,"text":1360},1781022066106]