ΠžΡ‚Π»ΠΈΡ‡Π½ΠΎΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ тСорСтичСской части! Π’Ρ‹Π±ΠΎΡ€ ΠΌΠ΅ΠΆΠ΄Ρƒ рСляционными Π±Π°Π·Π°ΠΌΠΈ (SQL) ΠΈ NoSQL (MongoDB, Cassandra ΠΈ Ρ‚.Π΄.) β€” это всСгда вопрос Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΌΡ‹ собираСмся Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅.

Π”Π°, я рассматривал NoSQL (Π² частности, Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π±Π°Π·Ρ‹ Π²Ρ€ΠΎΠ΄Π΅ MongoDB), Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅ Ρƒ тСбя ΡƒΠΆΠ΅ Π»Π΅ΠΆΠ°Ρ‚ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ JSON. Но для ΡˆΠ°Ρ…ΠΌΠ°Ρ‚Π½ΠΎΠΉ Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠΈ NoSQL ΠΏΡ€ΠΎΠΈΠ³Ρ€Ρ‹Π²Π°Π΅Ρ‚ PostgreSQL ΠΏΠΎ нСскольким ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ.

Π”Π°Π²Π°ΠΉ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ PostgreSQL Π² нашСм случаС β€” Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½Ρ‹ΠΉ ΠΏΠΎΠ±Π΅Π΄ΠΈΡ‚Π΅Π»ΡŒ.

1. Π‘ΡƒΡ‚ΡŒ NoSQL β€” дСнормализация, Π° Π½Π°ΠΌ Π½ΡƒΠΆΠ½Π° дСдупликация

Π’ NoSQL (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, MongoDB) идСальная структура β€” это ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ΡŒ всё Π² ΠΎΠ΄ΠΈΠ½ большой β€œΠ΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚β€ (JSON), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π·Π° ΠΎΠ΄Π½ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ диску. Π’ Ρ‚Π°ΠΊΠΎΠΉ структурС Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ…ΠΎΠ΄ (turn) Π½Π°ΠΌ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π±Ρ‹ Π²ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ строку ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ (rnbqkbnr/...). Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ΄Π½Π° ΠΈ Ρ‚Π° ΠΆΠ΅ Π½Π°Ρ‡Π°Π»ΡŒΠ½Π°Ρ позиция Π±ΡƒΠ΄Π΅Ρ‚ сохранСна Π² Π±Π°Π·Π΅ 10 ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ΠΎΠ² Ρ€Π°Π·. Если ΠΆΠ΅ ΠΌΡ‹ Π² NoSQL попытаСмся вынСсти ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ β€œΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽβ€ (ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π°Π½Π°Π»ΠΎΠ³ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ positions), Π½Π°ΠΌ придСтся Π΄Π΅Π»Π°Ρ‚ΡŒ соСдинСния (Joins) Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΊΠΎΠ΄Π° прилоТСния. NoSQL Π±Π°Π·Ρ‹ ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠ»ΠΎΡ…ΠΎ ΠΈ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΡƒΠΌΠ΅ΡŽΡ‚ Π΄Π΅Π»Π°Ρ‚ΡŒ Joins.

ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ Postgres: Он ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ создан для Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. ΠœΡ‹ Ρ…Ρ€Π°Π½ΠΈΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, Π° ΠΌΠΈΠ»Π»ΠΈΠΎΠ½Ρ‹ Ρ…ΠΎΠ΄ΠΎΠ² просто ΡΡΡ‹Π»Π°ΡŽΡ‚ΡΡ Π½Π° Π½Π΅Ρ‘ ΠΏΠΎ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΎΠΌΡƒ числовому ID, ΠΈ Π±Π°Π·Π° соСдиняСт ΠΈΡ… Π·Π° миллисСкунды.

2. БлоТная Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° ΠΈ АгрСгации (SQL ΠΏΠΎΠ±Π΅ΠΆΠ΄Π°Π΅Ρ‚)

Ввоя главная Ρ†Π΅Π»ΡŒ β€” Π²Ρ‹Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° стратСгий ΠΈ Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ°. ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒ запрос: β€œΠΠ°ΠΉΡ‚ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚ ΠΏΠΎΠ±Π΅Π΄ Π±Π΅Π»Ρ‹Ρ… ΠΈΠ· ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ X, ΠΏΡ€ΠΈ условии, Ρ‡Ρ‚ΠΎ Ρ€Π΅ΠΉΡ‚ΠΈΠ½Π³ ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² Π±Ρ‹Π» большС 2000, ΠΈ Π²Ρ‹ΠΊΠΈΠ½ΡƒΡ‚Ρ‹Π΅ ΠΊΡƒΠ±ΠΈΠΊΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°Π»ΠΈ коня”.

Π’ PostgreSQL это ΠΏΠΈΡˆΠ΅Ρ‚ΡΡ СстСствСнным языком:

SELECT COUNT(*) FILTER (WHERE result = 1) / COUNT(*)
FROM turns JOIN games ON turns.game_id = games.id
WHERE position_id = 123 AND dice_sorted LIKE '%N%' AND games.white_rating > 2000;

Π’ MongoDB Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΉ Aggregation Pipeline β€” это ΠΌΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½Π° дСсятки строк ΠΊΠΎΠ΄Π°. РСляционная Π°Π»Π³Π΅Π±Ρ€Π° SQL Π΄ΠΎ сих ΠΏΠΎΡ€ являСтся Π½Π΅ΠΏΡ€Π΅Π²Π·ΠΎΠΉΠ΄Π΅Π½Π½Ρ‹ΠΌ стандартом для слоТной Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠΈ (OLAP).

3. PostgreSQL ΠΈΠΌΠ΅Π΅Ρ‚ встроСнный NoSQL (JSONB)

Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ Postgres часто Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ β€œΠ»ΡƒΡ‡ΡˆΠ΅ΠΉ NoSQL Π±Π°Π·ΠΎΠΉ данных”. Π£ нас Π΅ΡΡ‚ΡŒ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° metadata JSONB. Если Ρƒ ΠΏΠ°Ρ€Ρ‚ΠΈΠΈ ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, количСство Π·Π°Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½ΠΎΠ³ΠΎ Π·ΠΎΠ»ΠΎΡ‚Π°, ID Ρ‚ΡƒΡ€Π½ΠΈΡ€Π°, Π°Π²Π°Ρ‚Π°Ρ€ΠΊΠ° ΠΎΠΏΠΏΠΎΠ½Π΅Π½Ρ‚Π°), Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΌΠ΅Π½ΡΡ‚ΡŒ схСму Ρ‚Π°Π±Π»ΠΈΡ† (ΠΊΠ°ΠΊ Π² старом SQL). ΠœΡ‹ просто ΠΊΠΈΠ΄Π°Π΅ΠΌ это Π² JSONB. И Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Postgres ΡƒΠΌΠ΅Π΅Ρ‚ ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ свСрхбыстрыС индСксы прямо ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π°ΠΌ Π²Π½ΡƒΡ‚Ρ€ΠΈ JSON! Π­Ρ‚ΠΎ Π΄Π°Π΅Ρ‚ Π½Π°ΠΌ Π»ΡƒΡ‡ΡˆΠ΅Π΅ ΠΈΠ· Π΄Π²ΡƒΡ… ΠΌΠΈΡ€ΠΎΠ².

4. Π’ΠΈΠΏΡ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Π˜Π½Π΄Π΅ΠΊΡΡ‹

Π’ NoSQL Π±Π°Π·Π°Ρ… часто ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ Π²Ρ‹Π±ΠΎΡ€ индСксов. Π’ PostgreSQL ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ:

  • Hash индСксы (идСально для поиска FEN-строки).
  • ΠœΠ°ΡΡΠΈΠ²Ρ‹ VARCHAR[] с GIN-индСксами (ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΊΠ°Ρ‚ΡŒ, содСрТится Π»ΠΈ Ρ…ΠΎΠ΄ β€˜e2e4’ Π² массивС сыгранных Ρ…ΠΎΠ΄ΠΎΠ² Π·Π° долю сСкунды).

Π˜Ρ‚ΠΎΠ³:

NoSQL ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для ΠΊΠΎΡ€Π·ΠΈΠ½ ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚-ΠΌΠ°Π³Π°Π·ΠΈΠ½ΠΎΠ², Π»ΠΎΠ³ΠΎΠ² ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΡ„ΠΈΠ»Π΅ΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, Π³Π΄Π΅ структура ΠΏΠ»Π°Π²Π°Π΅Ρ‚, Π° Π΄Π°Π½Π½Ρ‹Π΅ Ρ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ. Но ΡˆΠ°Ρ…ΠΌΠ°Ρ‚Π½Π°Ρ партия β€” это строго рСляционная структура: ΠΈΠ³Ρ€ΠΎΠΊΠΈ ΠΈΠ³Ρ€Π°ΡŽΡ‚ ΠΏΠ°Ρ€Ρ‚ΠΈΠΈ, ΠΏΠ°Ρ€Ρ‚ΠΈΠΈ состоят ΠΈΠ· Ρ…ΠΎΠ΄ΠΎΠ², Ρ…ΠΎΠ΄Ρ‹ ΠΌΠ΅Π½ΡΡŽΡ‚ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ. И PostgreSQL создан ΠΈΠΌΠ΅Π½Π½ΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ²ΡΠ·Ρ‹Π²Π°Ρ‚ΡŒ эти сущности максимально эффСктивно.


Если эти Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ всС Ρ‚Π²ΠΎΠΈ сомнСния, Ρ‚ΠΎ Ρƒ нас Π½Π° Ρ€ΡƒΠΊΠ°Ρ… Π΅ΡΡ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ проработанная, соврСмСнная ΠΈ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠ°Ρ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…!

Какой Π±ΡƒΠ΄Π΅Ρ‚ наш ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ шаг? Π₯ΠΎΡ‡Π΅ΡˆΡŒ Π»ΠΈ Ρ‚Ρ‹, Ρ‡Ρ‚ΠΎΠ±Ρ‹ я Π½Π° основС этого ΠΏΠ»Π°Π½Π° сгСнСрировал SQL-скрипты для создания этих Ρ‚Π°Π±Π»ΠΈΡ† (ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ для SQLAlchemy/Alembic), ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ написанию скрипта-ΠΈΠΌΠΏΠΎΡ€Ρ‚Π΅Ρ€Π° JSON?