ЁЯЧДя╕П рдзрдбрд╛ 04 тАФ Data model рдЖрдгрд┐ database рдЪреА рдирд┐рд╡рдб: рдЖрдзреА рдкреНрд░рд╢реНрдирд╛рдВрдЪреЗ model рдХрд░рд╛
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 18 рдкреИрдХреА рдзрдбрд╛ 04 ┬╖ рдорд╛рдЧреЗ: lesson-03-api-design ┬╖ рдкреБрдвреЗ: lesson-05-caching
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ03, рдЖрдгрд┐ рднрд╛рдЧ 1 рдЪреА рд╢реЗрд╡рдЯрдЪреА рдкрд╛рдпрд░реА: data. Access patterns (app data рд▓рд╛ рд╡рд┐рдЪрд╛рд░рдгрд╛рд░
рддреЗ рдкреНрд░рд╢реНрди) рдпрд╛рдВрдЪреА рдпрд╛рджреА рдХрд░рд╛, рддреНрдпрд╛рдВрдЪреА рдЙрддреНрддрд░реЗ рджреЗрдгрд╛рд░реЗ table рдЖрдгрд┐ index рд▓рд┐рд╣рд╛, рдЖрдгрд┐ рдордЧрдЪ store рдЪрд╛
рдкреНрд░рдХрд╛рд░ рдирд┐рд╡рдбрд╛ тАФ рдореВрд▓рддрдГ relational, рдЖрдгрд┐ key-value store, search engine, vector index, object
storage рдХрд┐рдВрд╡рд╛ time-series store рдлрдХреНрдд рдПрдЦрд╛рджреНрдпрд╛ access pattern рд▓рд╛ рддреНрдпрд╛рдЪреА рдЧрд░рдЬ рдЕрд╕реЗрд▓ рддреЗрд╡реНрд╣рд╛рдЪ.
design/designs.py рдордзреАрд▓ choose_store() рдЧрд░рдЬрд╛рдВрдЪреЗ store рдордзреНрдпреЗ рд░реВрдкрд╛рдВрддрд░
рдХрд░рддреЗ; design/demo.py рдордзреАрд▓ data() рд╕реВрдЪрдирд╛ рдлрд▓рдХрд╛рдЪреА рдирд┐рд╡рдб рдЫрд╛рдкрддреЗ.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рд╢рд╛рд│реЗрдЪреЗ рдХрд╛рд░реНрдпрд╛рд▓рдп рдПрдХ рдореЛрдареА рдиреЛрдВрджрд╡рд╣реА ЁЯУТ рдареЗрд╡рддреЗ. рддрд┐рдЪреНрдпрд╛рд╕рд╛рдареА рдХрдкрд╛рдЯ рд╡рд┐рдХрдд рдШреЗрдгреНрдпрд╛рдЖрдзреА рджреАрдкрд┐рдХрд╛ рд╡рд┐рдЪрд╛рд░рддреЗ: "рд▓реЛрдХ рдпрд╛рдд рдХрд╛рдп рд╢реЛрдзрдгрд╛рд░ рдЖрд╣реЗрдд?"
- "рд╡рд░реНрдЧ 3A рдЪреНрдпрд╛ рд╕реВрдЪрдирд╛ рджрд╛рдЦрд╡рд╛, рдирд╡реНрдпрд╛ рдЖрдзреА." тАФ рджрд┐рд╡рд╕рд╛рд▓рд╛ рд▓рд╛рдЦреЛ рд╡реЗрд│рд╛ рд╡рд┐рдЪрд╛рд░рд▓реЗрд▓рд╛.
- "рдПрдХ рд╕реВрдЪрдирд╛ рддрд┐рдЪреНрдпрд╛ рдХреНрд░рдорд╛рдВрдХрд╛рдиреЗ рджрд╛рдЦрд╡рд╛."
- "рдХреЛрдгрддреНрдпрд╛ рд╕реВрдЪрдирд╛рдВрдордзреНрдпреЗ 'рдХреНрд░реАрдбрд╛ рджрд┐рди' рдЖрд╣реЗ?"
рдкрд╣рд┐рд▓реНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рд╕рд╛рдареА рддреА рдкрд╛рдиреЗ рдЖрдзреА рд╡рд░реНрдЧрд╛рдиреБрд╕рд╛рд░, рдордЧ рддрд╛рд░рдЦреЗрдиреБрд╕рд╛рд░ рдХреНрд░рдорд╛рдиреЗ рд▓рд╛рд╡рддреЗ, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧрд╛рд╕рд╛рдареА рдПрдХ рдЦреВрдг-рдкрдЯреНрдЯреА ЁЯУС. рдЖрддрд╛ рдХрд╛рд░рдХреВрди 3A рдЪреА рдкрдЯреНрдЯреА рдЙрдШрдбрддреЗ рдЖрдгрд┐ рд╡рд░рдЪреНрдпрд╛ 20 рд╡рд╛рдЪрддреЗ. рддреА рдкрдЯреНрдЯреА рдореНрд╣рдгрдЬреЗ index.
"рдХреНрд░реАрдбрд╛ рджрд┐рди" рдкреНрд░рд╢реНрдирд╛рд╕рд╛рдареА рд╕рд╛рдзреА рдиреЛрдВрджрд╡рд╣реА рд╡рд╛рдИрдЯ тАФ рдХрд╛рд░рдХреБрдирд╛рд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рди рд╡рд╛рдЪрд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓. рдореНрд╣рдгреВрди рд▓реЛрдХ рддреЛ рдЦрд░реЛрдЦрд░ рдЦреВрдк рд╡рд┐рдЪрд╛рд░рдд рдЕрд╕рддреАрд▓, рддрд░ рджреАрдкрд┐рдХрд╛ рдкреБрд╕реНрддрдХрд╛рдЪреНрдпрд╛ рдорд╛рдЧреЗ рдПрдХ рд╡реЗрдЧрд│реА рд╢рдмреНрджрд╕реВрдЪреА рдЬреЛрдбрддреЗ: "рдХреНрд░реАрдбрд╛ рджрд┐рди тЖТ рдкрд╛рдиреЗ 12, 88, 301". рддреЛ рдореНрд╣рдгрдЬреЗ search engine.
Photos рдиреЛрдВрджрд╡рд╣реАрдд рдЕрдЬрд┐рдмрд╛рдд рдЬрд╛рдд рдирд╛рд╣реАрдд. рддреЗ рдПрдХрд╛ рдХреЛрдареАрдЪреНрдпрд╛ рдЦреЛрд▓реАрдд ЁЯЧГя╕П рдЬрд╛рддрд╛рдд, рдЖрдгрд┐ рдиреЛрдВрджрд╡рд╣реАрдд рдлрдХреНрдд "photo box 17 рдордзреНрдпреЗ" рдПрд╡рдвреЗрдЪ рд▓рд┐рд╣рд┐рд▓реЗ рдЬрд╛рддреЗ.
рджреАрдкрд┐рдХрд╛ рдкрд╣рд┐рд▓реНрдпрд╛рдЪ рджрд┐рд╡рд╢реА рдкрд╛рдЪ рдХрдкрд╛рдЯреЗ рдШреЗрдд рдирд╛рд╣реА. рдпреЛрдЧреНрдп рдЦреВрдг-рдкрдЯреНрдЯреНрдпрд╛рдВрдЪреА рдПрдХ рдЪрд╛рдВрдЧрд▓реА рдиреЛрдВрджрд╡рд╣реА рдЬрд╡рд│рдЬрд╡рд│ рд╕рдЧрд│реНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рдВрдЪреА рдЙрддреНрддрд░реЗ рджреЗрддреЗ. рдПрдЦрд╛рджреНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рд▓рд╛ рдЧрд░рдЬ рдЕрд╕реЗрд▓ рддреЗрд╡реНрд╣рд╛рдЪ рддреА рдЦрд╛рд╕ рдХрдкрд╛рдЯ рдЬреЛрдбрддреЗ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart TB
q["тЭУ access patterns first<br/>notices of class 3A, newest first<br/>one notice by id ┬╖ my children's feed"]
q --> rel["ЁЯРШ relational (PostgreSQL / Aurora)<br/>the safe default<br/>joins ┬╖ transactions"]
rel --> t["notices(id, class_id, author, title,<br/>text, urgent, created_at)<br/>index (class_id, created_at DESC)"]
q -.->|"huge scale + key lookups"| kv["ЁЯФС key-value<br/>DynamoDB / Cassandra"]
q -.->|"full-text search"| se["ЁЯФО search<br/>OpenSearch"]
q -.->|"similar meaning"| vx["ЁЯзн vector<br/>pgvector / k-NN"]
q -.->|"photos, files"| ob["ЁЯкг object storage<br/>S3"]
q -.->|"metrics over time"| ts["тП▒я╕П time-series<br/>Timestream / Prometheus"]
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/system-design/lesson-diagrams.html#l04
тЭУ рдХрд╛рдп
- Access pattern тАФ app data рд▓рд╛ рд╡рд┐рдЪрд╛рд░рддреЛ рддреЛ рдПрдХ рдкреНрд░рд╢реНрди, рддреНрдпрд╛рдЪреНрдпрд╛ рд╡рд╛рд░рдВрд╡рд╛рд░рддреЗрд╕рд╣ рдЖрдгрд┐ рд╡реЗрдЧрд╛рдЪреНрдпрд╛ рдЙрджреНрджрд┐рд╖реНрдЯрд╛рд╕рд╣: "рдПрдХрд╛ рд╡рд░реНрдЧрд╛рдЪреНрдпрд╛ 20 рдирд╡реНрдпрд╛ рд╕реВрдЪрдирд╛, рд╕рд░рд╛рд╕рд░реА рд╕реЗрдХрдВрджрд╛рд▓рд╛ 1,157 рд╡реЗрд│рд╛, p99 < 200 ms". Tables рдЪреНрдпрд╛ рдЖрдзреА рддреНрдпрд╛рдВрдЪреА рдпрд╛рджреА рдХрд░рд╛.
- Entities рдЖрдгрд┐ relations тАФ рд╕реВрдЪрдирд╛ рдлрд▓рдХрд╛рдд
schools,classes,parents,children(рдореВрд▓ рдПрдХрд╛ рд╡рд░реНрдЧрд╛рдд рдЕрд╕рддреЗ; рдкрд╛рд▓рдХрд╛рд▓рд╛ рдореБрд▓реЗ рдЕрд╕рддрд╛рдд) рдЖрдгрд┐notices(рд╕реВрдЪрдирд╛ рдПрдХрд╛ рд╡рд░реНрдЧрд╛рдЪреА рдЕрд╕рддреЗ) рдЖрд╣реЗрдд. рдкрд╛рд▓рдХрд╛рдЪреЗ feed = рддрд┐рдЪреНрдпрд╛ рдореБрд▓рд╛рдВрдЪреНрдпрд╛ рд╡рд░реНрдЧрд╛рдВрдЪреНрдпрд╛ рд╕реВрдЪрдирд╛. - Relational database (PostgreSQL, MySQL, Aurora) тАФ tables, joins, transactions, constraints, рдЖрдгрд┐ рдкреБрдвреЗ рдирд╡реНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рдВрдЪреА рдЙрддреНрддрд░реЗ рджреЗрдК рд╢рдХрдгрд╛рд░реЗ SQL. рд╕реБрд░рдХреНрд╖рд┐рдд default. рдПрдХ primary рд╕реЗрдХрдВрджрд╛рд▓рд╛ рд╣рдЬрд╛рд░реЛ writes рд╣рд╛рддрд╛рд│рддреЛ; рдЖрдкрд▓реНрдпрд╛рд▓рд╛ 11.6 рд▓рд╛рдЧрддрд╛рдд.
- Index тАФ рдХрд╛рд╣реА columns рдЪреА рдХреНрд░рдорд╡рд╛рд░ рдкреНрд░рдд, рдЬрд┐рдЪреНрдпрд╛рдореБрд│реЗ database рдкреНрд░рддреНрдпреЗрдХ row рд╡рд╛рдЪрдгреНрдпрд╛рдРрд╡рдЬреА
seek рдХрд░реВ рд╢рдХрддреЛ.
(class_id, created_at DESC)20 index рдиреЛрдВрджреА рд╡рд╛рдЪреВрди "3A рдЪреНрдпрд╛ рдирд╡реНрдпрд╛ рд╕реВрдЪрдирд╛" рджреЗрддреЛ. Indexes reads рдЬрд▓рдж рдЖрдгрд┐ writes рдереЛрдбреЗ рд╣рд│реВ рдХрд░рддрд╛рдд, рдЖрдгрд┐ рддреЗ disk рдШреЗрддрд╛рдд. - рджреБрд╕рд░рд╛ store рдЬреЛрдбрдгреЗ рдХреЗрд╡реНрд╣рд╛ рдпреЛрдЧреНрдп (рдкреНрд░рддреНрдпреЗрдХрд╛рд╕рд╛рдареА рдЦрд░реЗ рдХрд╛рд░рдг):
- key-value / wide-column (DynamoDB, Cassandra) тАФ рдкреНрд░рдЪрдВрдб scale рдЖрдгрд┐ рдЖрдзреАрдЪ рдорд╛рд╣реАрдд рдЕрд╕рд▓реЗрд▓реЗ рд╕рд╛рдзреЗ key lookups (sessions, carts, inboxes). Joins рддреБрдордЪреА рдЬрдмрд╛рдмрджрд╛рд░реА рдмрдирддрд╛рдд.
- search engine (OpenSearch) тАФ full-text search, рдЯрд╛рдпрдкрд┐рдВрдЧрдЪреНрдпрд╛ рдЪреБрдХрд╛ рд╕рд╛рдВрднрд╛рд│рдгреЗ, ranking.
- vector index (pgvector, OpenSearch k-NN) тАФ "рд╕рд╛рд░рдЦрд╛рдЪ рдЕрд░реНрде рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╕реВрдЪрдирд╛ рд╢реЛрдзрд╛" (AI рд╢рд╛рд│рд╛ рдЖрдгрд┐ рдЗрдерд▓рд╛ рдзрдбрд╛ 18 рдкрд╛рд╣рд╛).
- object storage (S3) тАФ photos, PDFs, videos. Database рдлрдХреНрдд key рдареЗрд╡рддреЛ.
- time-series (Timestream, Prometheus) тАФ рдХрд╛рд│рд╛рдиреБрд╕рд╛рд░ рдЖрдХрдбреЗ: metrics, sensor readings.
- Denormalise тАФ рдПрдЦрд╛рджреНрдпрд╛ рдЧрд░рдо рдкреНрд░рд╢реНрдирд╛рд╕рд╛рдареА data рдЪреА рдкреНрд░рдд рджреБрд╕рд▒реНрдпрд╛ рдЖрдХрд╛рд░рд╛рдд рдареЗрд╡рд╛ (рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рд▓рдХрд╛рдЪреЗ feed, рдзрдбрд╛ 08). рд╡рд╛рдЪрд╛рдпрд▓рд╛ рдЬрд▓рдж, рдЖрдгрд┐ рдкреНрд░рддреА рдПрдХрдореЗрдХрд╛рдВрд╢реА рдЬреБрд│рд╡реВрди рдареЗрд╡рд╛рд╡реНрдпрд╛ рд▓рд╛рдЧрддрд╛рдд.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг data code рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдХрд╛рд│ рдЯрд┐рдХрддреЛ. рдЖрдЬ рд╡рд╛рдИрдЯ рд░рдЪрд▓реЗрд▓реЗ table рд╡рд░реНрд╖рд╛рдиреБрд╡рд░реНрд╖реЗ рдХрд╛рд│рдЬреАрдкреВрд░реНрд╡рдХ migrate рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓. рдЖрдгрд┐ рдХрд╛рд░рдг "рдХреЛрдгрддрд╛ database?" рд╣рд╛ рдкрд╣рд┐рд▓рд╛ рдкреНрд░рд╢реНрдирдЪ рдЪреБрдХреАрдЪрд╛ рдЖрд╣реЗ. рдпреЛрдЧреНрдп рдкрд╣рд┐рд▓рд╛ рдкреНрд░рд╢реНрди рдЖрд╣реЗ "рдХреЛрдгрддреЗ рдкреНрд░рд╢реНрди, рдХрд┐рддреА рд╡реЗрд│рд╛, рдХрд┐рддреА рдЬрд▓рдж?" тАФ store рддреНрдпрд╛рддреВрди рдард░рддреЛ. рдкреНрд░рддреНрдпреЗрдХ рдЬрд╛рд╕реНрддреАрдЪрд╛ store рдореНрд╣рдгрдЬреЗ рдЪрд╛рд▓рд╡рд╛рдпрд▓рд╛, backup рдШреНрдпрд╛рдпрд▓рд╛, рд╕реБрд░рдХреНрд╖рд┐рдд рдареЗрд╡рд╛рдпрд▓рд╛ рдЖрдгрд┐ рдЬреБрд│рд╡реВрди рдареЗрд╡рд╛рдпрд▓рд╛ рдЖрдгрдЦреА рдПрдХ system. 4 рдЬрдгрд╛рдВрдЪреНрдпрд╛ team рдиреЗ (рдзрдбрд╛ 01) рдПрдЦрд╛рджреНрдпрд╛ access pattern рд▓рд╛ рд╕реНрдкрд╖реНрдЯрдкрдгреЗ рджреБрд╕рд░рд╛ рд▓рд╛рдЧрдд рдирд╛рд╣реА рддреЛрдкрд░реНрдпрдВрдд рдПрдХрдЪ рдЪрд╛рд▓рд╡рд╛рд╡рд╛.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
design/designs.py рдордзреАрд▓ choose_store(needs) рдирд┐рдпрдорд╛рдВрдЪреА рдПрдХ рдпрд╛рджреА
рддрдкрд╛рд╕рддреЗ тАФ {transactions, joins}, {key-lookup, huge-scale}, {search}, {similarity},
{files}, {time-series} тАФ рдЖрдгрд┐ рдЬреНрдпрд╛рдЪреЗ рд╕рдЧрд│реЗ рд╢рдмреНрдж needs рдордзреНрдпреЗ рдЖрд╣реЗрдд рдЕрд╕рд╛ рдкрд╣рд┐рд▓рд╛ рдирд┐рдпрдо рдкрд░рдд
рджреЗрддреЗ. рдХреЛрдгрддрд╛рдЪ рдЬреБрд│рд▓рд╛ рдирд╛рд╣реА, рддрд░ рддреЗ relational рдкрд░рдд рджреЗрддреЗ: "access pattern рд╡реЗрдЧрд│реЗ рд╕рд╛рдВрдЧреЗрдкрд░реНрдпрдВрдд
рд╕реБрд░рдХреНрд╖рд┐рдд default". рд╣рд╛ рдЪрд░реНрдЪрд╛ рд╕реБрд░реВ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареАрдЪрд╛ рд╢рд┐рдХрд╡рдгреАрдЪрд╛ рдирд┐рдпрдо рдЖрд╣реЗ, рдХрд╛рдпрджрд╛ рдирд╛рд╣реА.
design/demo.py рдордзреАрд▓ data() рдЧрд░рдЬрд╛рдВрдЪреЗ рд╕рд╣рд╛ рд╕рдВрдЪ рд╡рд╛рдкрд░реВрди рдкрд╛рд╣рддреЗ рдЖрдгрд┐ рд╕реВрдЪрдирд╛
рдлрд▓рдХрд╛рдЪреЗ table рдЖрдгрд┐ index рдЫрд╛рдкрддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 design/demo.py data
python3 - <<'EOF'
import sys; sys.path.insert(0, "design"); from designs import choose_store
for needs in ({"time-series"}, {"search"}, {"search", "transactions", "joins"}, {"key-lookup"}, {"key-lookup", "huge-scale"}, {"transactions"}):
print(f"{', '.join(sorted(needs)):<30} тЖТ {choose_store(needs)}")
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
data рдЫрд╛рдкрддреЗ:
тФАтФА model the data from the questions you will ask it (access patterns), then pick the store
joins, transactions тЖТ relational (PostgreSQL / Aurora)
huge-scale, key-lookup тЖТ key-value / wide-column (DynamoDB / Cassandra)
search тЖТ search engine (OpenSearch)
similarity тЖТ vector index (pgvector / OpenSearch k-NN)
files тЖТ object storage (S3)
(nothing special) тЖТ relational (PostgreSQL) тАФ the safe default until an access pattern says otherwise
notice board: notices(id, class_id, author, title, text, urgent, created_at) ┬╖ index (class_id, created_at DESC)
one table, one index, one question answered fast тАФ add stores only when a new access pattern needs one
рддреБрдордЪрд╛ snippet рдЫрд╛рдкрддреЛ:
time-series тЖТ time-series store (Timestream / Prometheus)
search тЖТ search engine (OpenSearch)
joins, search, transactions тЖТ relational (PostgreSQL / Aurora)
key-lookup тЖТ relational (PostgreSQL) тАФ the safe default until an access pattern says otherwise
huge-scale, key-lookup тЖТ key-value / wide-column (DynamoDB / Cassandra)
transactions тЖТ relational (PostgreSQL) тАФ the safe default until an access pattern says otherwise
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдлрдХреНрдд "key lookups" рд╣реЗ key-value store рд╕рд╛рдареА рдкреБрд░реЗрд╕реЗ рдХрд╛рд░рдг рдирд╛рд╣реА тАФ PostgreSQL key lookups рдЪрд╛рдВрдЧрд▓реЗ рдХрд░рддреЛ. Scale рдЖрдгрд┐ key lookups рдорд┐рд│реВрди рддреЗ рдХрд╛рд░рдг рдмрдирддреЗ. рдЖрдгрд┐ app рд▓рд╛ joins рдЖрдгрд┐ search рджреЛрдиреНрд╣реА рд▓рд╛рдЧрдд рдЕрд╕рддреАрд▓, рддрд░ рдирд┐рдпрдо рдЖрдзреА relational рдирд┐рд╡рдбрддреЛ: рдореВрд│ рдиреЛрдВрджреАрдВрдЪреА system (system of record) relational рд░рд╛рд╣рддреЗ, рдЖрдгрд┐ search рддреНрдпрд╛рдЪреНрдпрд╛ рд╢реЗрдЬрд╛рд░реА рдПрдХ рдкреНрд░рдд рдореНрд╣рдгреВрди рдЬреЛрдбрд▓реЗ рдЬрд╛рддреЗ (events рдордзреВрди рднрд░рд▓реЗрд▓реЗ, рдзрдбрд╛ 08) тАФ рддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреА рдирд╛рд╣реА.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдЖрдзреА database рдирд┐рд╡рдбрдгреЗ ("рдЖрдкрдг MongoDB рд╡рд╛рдкрд░рддреЛ") рдЖрдгрд┐ рдкреНрд░рд╢реНрди рдирдВрддрд░
- reports рдЖрдгрд┐ рдРрдирд╡реЗрд│рдЪреНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рдВрдиреА рднрд░рд▓реЗрд▓реНрдпрд╛ app рд╕рд╛рдареА key-value store тАФ рдкреНрд░рддреНрдпреЗрдХ рдирд╡рд╛ рдкреНрд░рд╢реНрди рдореНрд╣рдгрдЬреЗ рдирд╡реЗ table
- рдЪрд╛рд░ рдЬрдгрд╛рдВрдЪреНрдпрд╛ team рд╕рд╛рдареА рдкрд╛рдЪ stores
- рд╕рд░реНрд╡рд╛рдд рдЧрд░рдо рдкреНрд░рд╢реНрдирд╛рд╕рд╛рдареА index рдирд╛рд╣реА тАФ рдХрд┐рдВрд╡рд╛ "рдЕрд╕реВ рджреЗ" рдореНрд╣рдгреВрди рдкреНрд░рддреНрдпреЗрдХ column рд╡рд░ index
- database рдордзреНрдпреЗ blobs рдореНрд╣рдгреВрди photos; рддреЗ object storage рдордзреНрдпреЗ рдареЗрд╡рд╛ рдЖрдгрд┐ key рд╕рд╛рдард╡рд╛
- search engine рд╣реАрдЪ data рдЪреА рдПрдХрдореЗрд╡ рдкреНрд░рдд тАФ рддреЛ рдПрдХ index рдЖрд╣реЗ, рддреЛ database рдордзреВрди рдкреБрдиреНрд╣рд╛ рдмрд╛рдВрдзрд╛
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рд╕реВрдЪрдирд╛ рдлрд▓рдХрд╛рдЪреЗ рдкрд╣рд┐рд▓реЗ table рдЖрдгрд┐ рддреНрдпрд╛рдЪрд╛ рдПрдХ рдЧрд░рдо index, PostgreSQL рдордзреНрдпреЗ:
CREATE TABLE notices (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
class_id text NOT NULL REFERENCES classes(id),
author_id bigint NOT NULL REFERENCES teachers(id),
title text NOT NULL,
body text NOT NULL, -- "text" in the demo
urgent boolean NOT NULL DEFAULT false,
photo_key text, -- the S3 object key, not the photo
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX notices_class_newest ON notices (class_id, created_at DESC, id DESC);
EXPLAIN SELECT id, title FROM notices WHERE class_id = '3A' ORDER BY created_at DESC, id DESC LIMIT 20;
-- look for: Index Scan using notices_class_newest (not Seq Scan)
On a real account тАФ рдкреБрдвреЗ рдПрдЦрд╛рджреНрдпрд╛ access pattern рд▓рд╛ key-value scale рд▓рд╛рдЧрд▓рд╛ (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде key рдиреЗ рд╡рд╛рдЪрд▓реНрдпрд╛ рдЬрд╛рдгрд╛рд▒реНрдпрд╛ 100 million рдкрд╛рд▓рдХ-inbox rows), рддрд░ рддреНрдпрд╛ рдПрдХрд╛ рдкреНрд░рд╢реНрдирд╛рд╕рд╛рдареА рд░рдЪрд▓реЗрд▓реЗ DynamoDB table:
aws dynamodb create-table --table-name parent-inbox \
--attribute-definitions AttributeName=parent_id,AttributeType=S AttributeName=created_at,AttributeType=S \
--key-schema AttributeName=parent_id,KeyType=HASH AttributeName=created_at,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST
рдЕрдзрд┐рдХ рдЦреЛрд▓рд╛рдд: Database рд╢рд╛рд│рд╛ (normal forms, joins, indexes рдЖрдгрд┐ EXPLAIN, transactions, replicas, partitioning, NoSQL) рдЖрдгрд┐ Vector DB рд╢рд╛рд│рд╛.
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: access patterns рдЪреА рдпрд╛рджреА design doc рдордзреНрдпреЗ schema рдЪреНрдпрд╛ рд╢реЗрдЬрд╛рд░реА рд▓рд┐рд╣рд╛. рдХреЛрдгреА рд╡рд┐рдЪрд╛рд░рд▓реЗ "DynamoDB рдХрд╛ рдирд╛рд╣реА?" рддрд░ рдЙрддреНрддрд░ рдореНрд╣рдгрдЬреЗ рддреНрдпрд╛ рдпрд╛рджреАрддрд▓реА рдПрдХ рдУрд│, рднрд╛рд╡рдирд╛ рдирд╡реНрд╣реЗ.
тПня╕П рдкреБрдвреЗ
рднрд╛рдЧ 1 рдкреВрд░реНрдг рдЭрд╛рд▓рд╛: рдХрд╛рдЧрдж, рдЖрдХрдбреЗ, рдХрд░рд╛рд░, data. рдЖрдХрдбреЗ рдореНрд╣рдгрд╛рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ write рдорд╛рдЧреЗ 100 reads. рднрд╛рдЧ 2 рддреНрдпрд╛рд╕рд╛рдареАрдЪреНрдпрд╛ рдкрд╣рд┐рд▓реНрдпрд╛ рдмрд╛рдВрдзрдгреАрдЪреНрдпрд╛ рдареЛрдХрд│реНрдпрд╛рдиреЗ рд╕реБрд░реВ рд╣реЛрддреЛ: рд╡рд╛рдЪрдгрд╛рд▒реНрдпрд╛рдЬрд╡рд│ рдкреНрд░рддреА рдареЗрд╡рдгреЗ.
git checkout lesson-05-caching