Β«Database as Π‘odeΒ» Experience

«Database as Π‘ode» Experience

SQL, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΡ‰Π΅? ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· нас ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΡΡ‚Π΅Π½ΡŒΠΊΠΈΠΉ запрос β€” Π½Π°Π±ΠΈΡ€Π°Π΅ΠΌ select, пСрСчисляСм Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ, Π·Π°Ρ‚Π΅ΠΌ from, имя Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ условий Π² where ΠΈ всС β€” ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Ρƒ нас Π² ΠΊΠ°Ρ€ΠΌΠ°Π½Π΅, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ (ΠΏΠΎΡ‡Ρ‚ΠΈ) нСзависимо ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ какая Π‘Π£Π‘Π” Π² это врСмя находится ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ (Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈ Π½Π΅ Π‘Π£Π‘Π” вовсС). Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Ρƒ практичСски с Π»ΡŽΠ±Ρ‹ΠΌ источником Π΄Π°Π½Π½Ρ‹Ρ… (рСляционным ΠΈ Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ) ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° (со всСми Π²Ρ‹Ρ‚Π΅ΠΊΠ°ΡŽΡ‰ΠΈΠΌΠΈ β€” version control, code review, статичСский Π°Π½Π°Π»ΠΈΠ·, автотСсты ΠΈ Π²ΠΎΡ‚ это всС). И это касаСтся Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ самих Π΄Π°Π½Π½Ρ‹Ρ…, схСм ΠΈ ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΉ, Π° Π²ΠΎΠΎΠ±Ρ‰Π΅ всСй ΠΆΠΈΠ·Π½Π΅Π΄Π΅ΡΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°. Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ повсСднСвных Π·Π°Π΄Π°Ρ‡Π°Ρ… ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°Ρ… Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ Π‘Π” ΠΏΠΎΠ΄ ΠΏΡ€ΠΈΡ†Π΅Π»ΠΎΠΌ "database as code".

И Π½Π°Ρ‡Π½Π΅ΠΌ прямо с ORM. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Π±Π°Ρ‚Π»Ρ‹ Π²ΠΈΠ΄Π° "SQL vs ORM" Π±Ρ‹Π»ΠΈ Π·Π°ΠΌΠ΅Ρ‡Π΅Π½Ρ‹ Π΅Ρ‰Π΅ Π² допСтровской Руси.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎ-рСляционный ΠΌΠ°ΠΏΠΈΠ½Π³

Π‘Ρ‚ΠΎΡ€ΠΎΠ½Π½ΠΈΠΊΠΈ ORM Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎ цСнят ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ ΠΈ простоту Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡ‚ Π‘Π£Π‘Π” ΠΈ чистоту ΠΊΠΎΠ΄Π°. Для ΠΌΠ½ΠΎΠ³ΠΈΡ… ΠΈΠ· нас ΠΊΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π‘Π” (Π° Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΈ сама Π‘Π”)

ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ выглядит ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ…

@Entity
@Table(name = "stock", catalog = "maindb", uniqueConstraints = {
        @UniqueConstraint(columnNames = "STOCK_NAME"),
        @UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "STOCK_ID", unique = true, nullable = false)
    public Integer getStockId() {
        return this.stockId;
    }
  ...

МодСль обвСшСна ΡƒΠΌΠ½Ρ‹ΠΌΠΈ аннотациями, Π° Π³Π΄Π΅-Ρ‚ΠΎ Π·Π° кулисами доблСстный ORM Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈ выполняСт Ρ‚ΠΎΠ½Π½Ρ‹ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ SQL-ΠΊΠΎΠ΄Π°. К слову ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ всСми силами ΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ ΠΎΡ‚Π³ΠΎΡ€ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ ΠΎΡ‚ своСй Π‘Π” ΠΊΠΈΠ»ΠΎΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ абстракций, Ρ‡Ρ‚ΠΎ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ "SQL нСнависти".

По Π΄Ρ€ΡƒΠ³ΡƒΡŽ сторону Π±Π°Ρ€Ρ€ΠΈΠΊΠ°Π΄ ΠΏΡ€ΠΈΠ²Π΅Ρ€ΠΆΠ΅Π½Ρ†Ρ‹ чистого "handmade"-SQL ΠΎΡ‚ΠΌΠ΅Ρ‡Π°ΡŽΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π²Ρ‹ΠΆΠΈΠΌΠ°Ρ‚ΡŒ всС соки ΠΈΠ· своСй Π‘Π£Π‘Π” Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… прослоСк ΠΈ абстракций. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ‡Π΅Π³ΠΎ ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ "data-centric" ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρ‹, Π³Π΄Π΅ Π±Π°Π·ΠΎΠΉ Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΎΠ±ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ люди (ΠΎΠ½ΠΈ ΠΆΠ΅ "базисты", ΠΎΠ½ΠΈ ΠΆΠ΅ "Π±Π°Π·ΠΎΠ²ΠΈΠΊΠΈ", ΠΎΠ½ΠΈ ΠΆΠ΅ "Π±Π°Π·Π΄Π΅Π½ΡŒΡ‰ΠΈΠΊΠΈ" ΠΈ Ρ‚.Π΄.), Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ остаСтся "Π΄Π΅Ρ€Π³Π°Ρ‚ΡŒ" Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Π²ΡŒΡŽΡ…ΠΈ ΠΈ Ρ…Ρ€Π°Π½ΠΈΠΌΡ‹Π΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ΠΊΠΈ, Π½Π΅ вдаваясь Π² подробности.

А Ρ‡Ρ‚ΠΎ Ссли Π²Π·ΡΡ‚ΡŒ Π»ΡƒΡ‡ΡˆΠ΅Π΅ ΠΈΠ· Π΄Π²ΡƒΡ… ΠΌΠΈΡ€ΠΎΠ²? Как это сдСлано Π² Π·Π°ΠΌΠ΅Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ инструмСнтС с ΠΆΠΈΠ·Π½Π΅ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°ΡŽΡ‰ΠΈΠΌ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ Yesql. ΠŸΡ€ΠΈΠ²Π΅Π΄Ρƒ ΠΏΠ°Ρ€Ρƒ строк ΠΈΠ· ΠΎΠ±Ρ‰Π΅ΠΉ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ Π² ΠΌΠΎΠ΅ΠΌ вольном ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π΅, Π° Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ с Π½Π΅ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ здСсь.

Clojure это ΠΊΡ€ΡƒΡ‚ΠΎΠΉ язык для создания DSL’Π΅ΠΉ, Π½ΠΎ SQL ΡƒΠΆΠ΅ сам ΠΏΠΎ сСбС являСтся ΠΊΡ€ΡƒΡ‚Ρ‹ΠΌ DSL, ΠΈ Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ΅Π½ Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½. S-выраТСния прСкрасны, Π½ΠΎ здСсь ΠΎΠ½ΠΈ Π½Π΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ. Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ скобки Ρ€Π°Π΄ΠΈ скобок. НС согласны? Π’ΠΎΠ³Π΄Π° Π΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ΡΡŒ Ρ‚ΠΎΠ³ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠ³Π΄Π° абстракция Π½Π°Π΄ Π‘Π” даст Ρ‚Π΅Ρ‡ΡŒ, ΠΈ Π²Ρ‹ Π½Π°Ρ‡Π½Π΅Ρ‚Π΅ Π±ΠΎΡ€ΡŒΠ±Ρƒ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ (raw-sql)

И Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ? Π”Π°Π²Π°ΠΉΡ‚Π΅ оставим SQL ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ SQL’Π΅ΠΌ β€” ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» Π½Π° ΠΎΠ΄ΠΈΠ½ запрос:

-- name: users-by-country
select *
  from users
 where country_code = :country_code

… Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ этот Ρ„Π°ΠΉΠ», ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΠ² Π΅Π³ΠΎ Π² ΠΎΠ±Ρ‹Ρ‡Π½ΡƒΡŽ Clojure Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ:

(defqueries "some/where/users_by_country.sql"
   {:connection db-spec})

;;; A function with the name `users-by-country` has been created.
;;; Let's use it:
(users-by-country {:country_code "GB"})
;=> ({:name "Kris" :country_code "GB" ...} ...)

ΠŸΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡΡΡŒ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ° "SQL ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ, Clojure ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ", Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚Π΅:

  • Никаких синтаксичСских ΡΡŽΡ€ΠΏΡ€ΠΈΠ·ΠΎΠ². Π’Π°ΡˆΠ° Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… (ΠΊΠ°ΠΊ ΠΈ любая другая) Π½Π΅ соотвСтствуСт SQL стандарту Π½Π° 100% β€” Π½ΠΎ для Yesql это Π½Π΅ Π²Π°ΠΆΠ½ΠΎ. Π’Ρ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚Π΅ Ρ‚Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ врСмя Π½Π° ΠΎΡ…ΠΎΡ‚Ρƒ Π·Π° функциями с синтаксисом эквивалСнтным SQL. Π’Π°ΠΌ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ придСтся Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (raw-sql "some (‘funky’ :: SYNTAX)")).
  • Π›ΡƒΡ‡ΡˆΠ°Ρ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°. Π’Π°Ρˆ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ ΡƒΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΡ‚Π»ΠΈΡ‡Π½ΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ SQL. Бохраняя SQL ΠΊΠ°ΠΊ SQL, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ.
  • Командная ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ. Π’Π°ΡˆΠΈ DBA ΠΌΠΎΠ³ΡƒΡ‚ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈ ΠΏΠΈΡΠ°Ρ‚ΡŒ SQL, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Π² своСм Clojure ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅.
  • Π‘ΠΎΠ»Π΅Π΅ простая настройка ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. НуТно ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΏΠ»Π°Π½ для ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ½ΠΎΠ³ΠΎ запроса? Π­Ρ‚ΠΎ Π½Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, ΠΊΠΎΠ³Π΄Π° ваш запрос являСтся ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ SQL.
  • ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ использованиС запросов. ΠŸΠ΅Ρ€Π΅Ρ‚Π°Ρ‰ΠΈΡ‚Π΅ эти ΠΆΠ΅ SQL-Ρ„Π°ΠΉΠ»Ρ‹ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρ‹, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ это просто старый Π΄ΠΎΠ±Ρ€Ρ‹ΠΉ SQL β€” просто ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚Π΅ΡΡŒ ΠΈΠΌ.

По ΠΌΠΎΠ΅ΠΌΡƒ идСя ΠΎΡ‡Π΅Π½ΡŒ крутая ΠΈ ΠΏΡ€ΠΈ этом ΠΎΡ‡Π΅Π½ΡŒ простая, благодаря Ρ‡Π΅ΠΌΡƒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΎΠ±Ρ€Π΅Π» мноТСство послСдоватСлСй Π½Π° самых Ρ€Π°Π·Π½Ρ‹Ρ… языках. А ΠΌΡ‹ Π΄Π°Π»Π΅Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΠΎΡ…ΠΎΠΆΡƒΡŽ Ρ„ΠΈΠ»ΠΎΡΠΎΡ„ΠΈΡŽ отдСлСния SQL-ΠΊΠΎΠ΄Π° ΠΎΡ‚ всСго ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π΄Π°Π»Π΅ΠΊΠΎ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ ORM.

IDE & DB-ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Ρ‹

НачнСм с простой повсСднСвной Π·Π°Π΄Π°Ρ‡ΠΈ. Часто Π½Π°ΠΌ приходится ΠΈΡΠΊΠ°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π² Π‘Π”, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π°ΠΉΡ‚ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ Π² схСмС ΠΈ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒ Π΅Π΅ структуру (ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ, ΠΊΠ»ΡŽΡ‡ΠΈ, индСксы, констрСйнты ΠΈ ΠΏΡ€ΠΎΡ‡Π΅Π΅). И ΠΎΡ‚ любой графичСской IDE ΠΈΠ»ΠΈ маломальского DB-manager’Π°, Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΌΡ‹ ΠΆΠ΄Π΅ΠΌ ΠΈΠΌΠ΅Π½Π½ΠΎ этих способностСй. Π§Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Π»ΠΎ быстро ΠΈ Π½Π΅ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ ΠΆΠ΄Π°Ρ‚ΡŒ ΠΏΠΎ полчаса, ΠΏΠΎΠΊΠ° нарисуСтся окошко с Π½ΡƒΠΆΠ½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ (особСнно ΠΏΡ€ΠΈ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠΌ соСдинСнии с ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΉ Π‘Π”), ΠΈ ΠΏΡ€ΠΈ этом Ρ‡Ρ‚ΠΎΠ±Ρ‹ получСнная информация Π±Ρ‹Π»Π° свСТСй ΠΈ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ, Π° Π½Π΅ Π·Π°ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΡΡ‚Π°Ρ€ΡŒΠ΅. ΠŸΡ€ΠΈΡ‡Π΅ΠΌ Ρ‡Π΅ΠΌ слоТнСС ΠΈ ΠΊΡ€ΡƒΠΏΠ½Π΅Π΅ Π‘Π” ΠΈ большС ΠΈΡ… количСство, Ρ‚Π΅ΠΌ слоТнСС это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ.

Но ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ я Π·Π°Π±Ρ€Π°ΡΡ‹Π²Π°ΡŽ ΠΌΡ‹ΡˆΡŒ ΠΊΡƒΠ΄Π° подальшС ΠΈ просто ΠΏΠΈΡˆΡƒ ΠΊΠΎΠ΄. Допустим, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠ·Π½Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ (ΠΈ с ΠΊΠ°ΠΊΠΈΠΌΠΈ свойствами) ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒΡΡ Π² схСмС "HR". Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ Π‘Π£Π‘Π” Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ Π²ΠΎΡ‚ Ρ‚Π°ΠΊΠΈΠΌ Π½Π΅Ρ…ΠΈΡ‚Ρ€Ρ‹ΠΌ запросом ΠΈΠ· information_schema:

select table_name
     , ...
  from information_schema.tables
 where schema = 'HR'

ΠžΡ‚ Π±Π°Π·Ρ‹ ΠΊ Π±Π°Π·Π΅ содСрТимоС Ρ‚Π°ΠΊΠΈΡ… Ρ‚Π°Π±Π»ΠΈΡ†-справочников Π²Π°Ρ€ΡŒΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ Π² зависимости ΠΎΡ‚ способностСй ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π‘Π£Π‘Π”. И, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для MySQL ΠΈΠ· этого ΠΆΠ΅ справочника ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ спСцифичныС для этой Π‘Π£Π‘Π” ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹:

select table_name
     , storage_engine -- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ "Π΄Π²ΠΈΠΆΠΎΠΊ" ("MyISAM", "InnoDB" etc)
     , row_format     -- Π€ΠΎΡ€ΠΌΠ°Ρ‚ строки ("Fixed", "Dynamic" etc)
     , ...
  from information_schema.tables
 where schema = 'HR'

Oracle Π½Π΅ ΡƒΠΌΠ΅Π΅Ρ‚ information_schema, Π·Π°Ρ‚ΠΎ Ρƒ Π½Π΅Π³ΠΎ Π΅ΡΡ‚ΡŒ Oracle metadata, ΠΈ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚:

select table_name
     , pct_free       -- ΠœΠΈΠ½ΠΈΠΌΡƒΠΌ свободного мСста Π² Π±Π»ΠΎΠΊΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… (%)
     , pct_used       -- ΠœΠΈΠ½ΠΈΠΌΡƒΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ мСста Π² Π±Π»ΠΎΠΊΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… (%)
     , last_analyzed  -- Π”Π°Ρ‚Π° послСднСго сбора статистики
     , ...
  from all_tables
 where owner = 'HR'

НС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ ClickHouse:

select name
     , engine -- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ "Π΄Π²ΠΈΠΆΠΎΠΊ" ("MergeTree", "Dictionary" etc)
     , ...
  from system.tables
 where database = 'HR'

Π§Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΠΎΡ…ΠΎΠΆΠ΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ Π² Cassandra (Π³Π΄Π΅ Π΅ΡΡ‚ΡŒ columnfamilies вмСсто tables ΠΈ keyspace’Ρ‹ вмСсто схСм):

select columnfamily_name
     , compaction_strategy_class  -- БтратСгия сборки мусора
     , gc_grace_seconds           -- ВрСмя ΠΆΠΈΠ·Π½ΠΈ мусора
     , ...
  from system.schema_columnfamilies
 where keyspace_name = 'HR'

Для Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Π‘Π” Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Ρ‚ΡŒ ΠΏΠΎΡ…ΠΎΠΆΠΈΠ΅ запросы (Π΄Π°ΠΆΠ΅ Π² Mongo Π΅ΡΡ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ систСмная коллСкция, которая содСрТит Π² сСбС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ всСх коллСкциях Π² систСмС).

Π‘Π°ΠΌΠΎ собой, Ρ‚Π°ΠΊΠΈΠΌ способом ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ…, Π° Π²ΠΎΠΎΠ±Ρ‰Π΅ ΠΎ любом ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅. ΠŸΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π΅ΡΠΊΠΈ Π΄ΠΎΠ±Ρ€Ρ‹Π΅ люди дСлятся Ρ‚Π°ΠΊΠΈΠΌ ΠΊΠΎΠ΄ΠΎΠΌ для Ρ€Π°Π·Π½Ρ‹Ρ… Π‘Π”, ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² сСрии Ρ…Π°Π±Ρ€Π°-статСй "Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ для докумСнтирования Π±Π°Π· Π΄Π°Π½Π½Ρ‹Ρ… PostgreSQL" (Π°ΠΉΠ±, Π±Π΅Π½, Π³ΠΈΠΌ). Π‘Π°ΠΌΠΎ собой, Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ всю эту Π³ΠΎΡ€Ρƒ запросов Π² Π³ΠΎΠ»ΠΎΠ²Π΅ ΠΈ постоянно Π½Π°Π±ΠΈΡ€Π°Ρ‚ΡŒ ΠΈΡ… β€” это "Ρ‚Π°ΠΊΠΎΠ΅ сСбС" ΡƒΠ΄ΠΎΠ²ΠΎΠ»ΡŒΡΡ‚Π²ΠΈΠ΅, поэтому Π² любимой IDE/Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅ Ρƒ мСня Π΅ΡΡ‚ΡŒ Π·Π°Ρ€Π°Π½Π΅Π΅ Π·Π°Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ сниппСтов для часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… запросов, ΠΈ остаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²ΠΏΠ΅Ρ‡Π°Ρ‚Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² шаблон.

Π’ ΠΈΡ‚ΠΎΠ³Π΅ Ρ‚Π°ΠΊΠΎΠΉ способ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ ΠΈ поиска ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π³ΠΎΡ€Π°Π·Π΄ΠΎ Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΎΠΊ, экономит ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, позволяСт ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Ρƒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΈ Π² Ρ‚ΠΎΠΌ Π²ΠΈΠ΄Π΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ сСйчас Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ (ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, описано Π² постС "Экспорт Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Π‘Π” Π² любом Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅: Ρ‡Ρ‚ΠΎ ΡƒΠΌΠ΅ΡŽΡ‚ IDE Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅ IntelliJ").

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ

ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ ΠΌΡ‹ нашли ΠΈ ΠΈΠ·ΡƒΡ‡ΠΈΠ»ΠΈ Π½ΡƒΠΆΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, самоС врСмя с Π½ΠΈΠΌΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ΅. ЕстСствСнно, Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ отрывая ΠΏΠ°Π»ΡŒΡ†Π΅Π² ΠΎΡ‚ ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹.

НС сСкрСт, Ρ‡Ρ‚ΠΎ простоС ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ ΠΏΠΎΡ‡Ρ‚ΠΈ Π²ΠΎ всСх Π‘Π”:

drop table hr.persons

А Π²ΠΎΡ‚ с созданиСм Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΡƒΠΆΠ΅ поинтСрСснСС. ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈ любая Π‘Π£Π‘Π” (Π² Ρ‚ΠΎΠΌ числС ΠΈ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ NoSQL) Π² Ρ‚ΠΎΠΌ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΌ Π²ΠΈΠ΄Π΅ ΡƒΠΌΠ΅Π΅Ρ‚ "create table", ΠΈ основная Π΅Π³ΠΎ Ρ‡Π°ΡΡ‚ΡŒ Π΄Π°ΠΆΠ΅ ΠΌΠ°Π»ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ (имя, список ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ, Ρ‚ΠΈΠΏΡ‹ Π΄Π°Π½Π½Ρ‹Ρ…), Π½ΠΎ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Π΄Π΅Ρ‚Π°Π»ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°Π·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ ΠΈ зависят ΠΎΡ‚ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ устройства ΠΈ возмоТностСй ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ Π‘Π£Π‘Π”. Мой Π»ΡŽΠ±ΠΈΠΌΡ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ β€” Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Oracle Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΈ "Π³ΠΎΠ»Ρ‹Π΅" БНЀ’Ρ‹ для синтаксиса "create table" Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‚ 31 страницу. Π”Ρ€ΡƒΠ³ΠΈΠ΅ Π‘Π£Π‘Π” ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‚ Π±ΠΎΠ»Π΅Π΅ скромными возмоТностями, Π½ΠΎ каТдая ΠΈΠ· Π½ΠΈΡ… Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ мноТСством интСрСсных ΠΈ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΠΈΡ‡ ΠΏΠΎ созданию Ρ‚Π°Π±Π»ΠΈΡ† (postgres, mysql, cockroach, cassandra). Вряд Π»ΠΈ ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ графичСский "wizard" ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΉ IDE (особСнно ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠΉ) смоТСт ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΏΠΎΠΊΡ€Ρ‹Ρ‚ΡŒ всС эти способности, Π° Ссли ΠΈ смоТСт, Ρ‚ΠΎ это Π±ΡƒΠ΄Π΅Ρ‚ Π·Ρ€Π΅Π»ΠΈΡ‰Π΅ Π½Π΅ для слабонСрвных. Π’ Ρ‚ΠΎ ΠΆΠ΅ врСмя ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈ воврСмя написанный ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ create table ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π±Π΅Π· Ρ‚Ρ€ΡƒΠ΄Π° Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ всСми ΠΈΠ· Π½ΠΈΡ…, ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ ΠΈ доступ ΠΊ вашим Π΄Π°Π½Π½Ρ‹ΠΌ Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΌ, ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈ максимально ΠΊΠΎΠΌΡ„ΠΎΡ€Ρ‚Π½Ρ‹ΠΌ.

Π’Π°ΠΊΠΆΠ΅ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… Π‘Π£Π‘Π” Π΅ΡΡ‚ΡŒ свои спСцифичныС Ρ‚ΠΈΠΏΡ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… Π‘Π£Π‘Π”. ΠŸΡ€ΠΈΡ‡Π΅ΠΌ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Π΄ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Π‘Π”, Π½ΠΎ ΠΈ Π½Π°Π΄ самой Π‘Π£Π‘Π”, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ "ΡƒΠ±ΠΈΡ‚ΡŒ" процСсс, ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ-Π»ΠΈΠ±ΠΎ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ памяти, Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ трассировку, ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π² Ρ€Π΅ΠΆΠΈΠΌ "read only" ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ΅.

А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ порисуСм

Одна ΠΈΠ· самых распространСнных Π·Π°Π΄Π°Ρ‡ β€” ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΡƒ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Π‘Π”, Π½Π° красивой ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ΅ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ связи ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ. Π­Ρ‚ΠΎ ΡƒΠΌΠ΅Π΅Ρ‚ практичСски любая графичСская IDE, ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Β«command lineΒ»-ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹, спСциализированныС графичСскиС Ρ‚ΡƒΠ»Ρ‹ ΠΈ ΠΌΠΎΠ΄Π΅Π»Π»Π΅Ρ€Ρ‹. ΠšΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Π°ΠΌ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π½Π°Ρ€ΠΈΡΡƒΡŽΡ‚ "ΠΊΠ°ΠΊ ΡƒΠΌΠ΅ΡŽΡ‚", Π° Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ²Π»ΠΈΡΡ‚ΡŒ Π½Π° этот процСсс ΠΌΠΎΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ ΠΈΠ»ΠΈ Π³Π°Π»ΠΎΡ‡Π΅ΠΊ Π² интСрфСйсС.

Но эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π³ΠΎΡ€Π°Π·Π΄ΠΎ ΠΏΡ€ΠΎΡ‰Π΅, Π³ΠΈΠ±Ρ‡Π΅ ΠΈ элСгантнСС, ΠΈ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΆΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠ΄Π°. Для построСния Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌ любой слоТности Ρƒ нас Π΅ΡΡ‚ΡŒ сразу нСсколько спСциализированных языков Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ (DOT, GraphML etc), Π° ΠΊ Π½ΠΈΠΌ β€” цСлая Ρ€ΠΎΡΡΡ‹ΠΏΡŒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ (GraphViz, PlantUML, Mermaid), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΌΠ΅ΡŽΡ‚ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ инструкции ΠΈ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² самых Ρ€Π°Π·Π½Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°Ρ…. Ну Π° ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°Ρ… ΠΈ связях ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ ΠΌΡ‹ ΡƒΠΆΠ΅ Π·Π½Π°Π΅ΠΌ ΠΊΠ°ΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ.

ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅ΠΌ нСбольшой ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ это ΠΌΠΎΠ³Π»ΠΎ Π±Ρ‹ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ, с использованиСм PlantUML ΠΈ дСмонстрационной Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… для PostgreSQL (слСва SQL-запрос, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сгСнСрируСт Π½ΡƒΠΆΠ½ΡƒΡŽ ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ для PlantUML, Π° справа Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚):

«Database as Π‘ode» Experience

select '@startuml'||chr(10)||'hide methods'||chr(10)||'hide stereotypes' union all
select distinct ccu.table_name || ' --|> ' ||
       tc.table_name as val
  from table_constraints as tc
  join key_column_usage as kcu
    on tc.constraint_name = kcu.constraint_name
  join constraint_column_usage as ccu
    on ccu.constraint_name = tc.constraint_name
 where tc.constraint_type = 'FOREIGN KEY'
   and tc.table_name ~ '.*' union all
select '@enduml'

А Ссли Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡΡ‚Π°Ρ€Π°Ρ‚ΡŒΡΡ, Ρ‚ΠΎ Π½Π° основС ER-шаблона для PlantUML ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ сильно ΠΏΠΎΡ…ΠΎΠΆΠ΅Π΅ Π½Π° Π½Π°ΡΡ‚ΠΎΡΡ‰ΡƒΡŽ ER-Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΡƒ:

SQL-запрос Ρ‡ΡƒΡƒΡƒΡ‚ΡŒ послоТнСС

-- Π¨Π°ΠΏΠΊΠ°
select '@startuml
        !define Table(name,desc) class name as "desc" << (T,#FFAAAA) >>
        !define primary_key(x) <b>x</b>
        !define unique(x) <color:green>x</color>
        !define not_null(x) <u>x</u>
        hide methods
        hide stereotypes'
 union all
-- Π’Π°Π±Π»ΠΈΡ†Ρ‹
select format('Table(%s, "%s n information about %s") {'||chr(10), table_name, table_name, table_name) ||
       (select string_agg(column_name || ' ' || upper(udt_name), chr(10))
          from information_schema.columns
         where table_schema = 'public'
           and table_name = t.table_name) || chr(10) || '}'
  from information_schema.tables t
 where table_schema = 'public'
 union all
-- Бвязи ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‚Π°Π±Π»ΠΈΡ†Π°ΠΌΠΈ
select distinct ccu.table_name || ' "1" --> "0..N" ' || tc.table_name || format(' : "A %s may haven many %s"', ccu.table_name, tc.table_name)
  from information_schema.table_constraints as tc
  join information_schema.key_column_usage as kcu on tc.constraint_name = kcu.constraint_name
  join information_schema.constraint_column_usage as ccu on ccu.constraint_name = tc.constraint_name
 where tc.constraint_type = 'FOREIGN KEY'
   and ccu.constraint_schema = 'public'
   and tc.table_name ~ '.*'
 union all
-- Подвал
select '@enduml'

«Database as Π‘ode» Experience

Если Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΈΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒΡΡ, Ρ‚ΠΎ ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ инструмСнты-Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρ‹ Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΏΠΎΡ…ΠΎΠΆΠΈΠ΅ запросы. ΠŸΡ€Π°Π²Π΄Π°, запросы эти ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π³Π»ΡƒΠ±ΠΎΠΊΠΎ "Π·Π°ΡˆΠΈΡ‚Ρ‹" Π² ΠΊΠΎΠ΄ самого прилоТСния ΠΈ слоТны для понимания, Π½Π΅ говоря ΡƒΠΆΠ΅ ΠΎ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΈΡ… ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ ΠΈ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³

ΠŸΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎ слоТной Ρ‚Π΅ΠΌΠ΅ β€” ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π‘Π”. Π’ΡΠΏΠΎΠΌΠ½ΡŽ Π½Π΅Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ true story, Ρ€Π°ΡΡΠΊΠ°Π·Π°Π½Π½ΡƒΡŽ ΠΌΠ½Π΅ "ΠΎΠ΄Π½ΠΈΠΌ ΠΌΠΎΠΈΠΌ Π΄Ρ€ΡƒΠ³ΠΎΠΌ". На ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ ΠΆΠΈΠ»-Π±Ρ‹Π» Π½Π΅ΠΊΠΈΠΉ могущСствСнный DBA, ΠΈ ΠΌΠ°Π»ΠΎ ΠΊΡ‚ΠΎ ΠΈΠ· Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Π±Ρ‹Π» с Π½ΠΈΠΌ Π·Π½Π°ΠΊΠΎΠΌ Π»ΠΈΡ‡Π½ΠΎ, Π΄Π° ΠΈ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π²ΠΈΠ΄Π΅Π» ΠΊΠΎΠ³Π΄Π°-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΅Π³ΠΎ Π² Π³Π»Π°Π·Π° (нСсмотря Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ трудился ΠΎΠ½, ΠΏΠΎ слухам, Π³Π΄Π΅-Ρ‚ΠΎ Π² сосСднСм корпусС). Π’ час "X", ΠΊΠΎΠ³Π΄Π° poduction-систСма ΠΊΡ€ΡƒΠΏΠ½ΠΎΠ³ΠΎ Ρ€Π΅Ρ‚Π΅ΠΉΠ»Π΅Ρ€Π° Π½Π°Ρ‡ΠΈΠ½Π°Π»Π° Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΉ Ρ€Π°Π· "ΠΏΠ»ΠΎΡ…ΠΎ сСбя Ρ‡ΡƒΠ²ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ", ΠΎΠ½ ΠΌΠΎΠ»Ρ‡Π° присылал ΡΠΊΡ€ΠΈΠ½ΡˆΠΎΡ‚Ρ‹ Π³Ρ€Π°Ρ„ΠΈΠΊΠΎΠ² ΠΈΠ· ΠΎΡ€Π°ΠΊΠ»ΠΎΠ²ΠΎΠ³ΠΎ Enterprise Manager, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±Π΅Ρ€Π΅ΠΆΠ½ΠΎ выдСлял ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹Π΅ мСста красным ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ΠΎΠΌ для "понятности" (это, мягко говоря, ΠΌΠ°Π»ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π»ΠΎ). И Π²ΠΎΡ‚ ΠΏΠΎ этой "Ρ„ΠΎΡ‚ΠΎΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΠ΅" ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎΡΡŒ Π»Π΅Ρ‡ΠΈΡ‚ΡŒ. ΠŸΡ€ΠΈ этом доступа ΠΊ Π΄Ρ€Π°Π³ΠΎΡ†Π΅Π½Π½ΠΎΠΌΡƒ (Π² ΠΎΠ±ΠΎΠΈΡ… смыслах этого слова) Enterprise Manager Π½ΠΈ Ρƒ ΠΊΠΎΠ³ΠΎ Π½Π΅ Π±Ρ‹Π»ΠΎ, Ρ‚.ΠΊ. систСма слоТная ΠΈ дорогая, Π²Π΄Ρ€ΡƒΠ³ "Ρ€Π°Π·Ρ€Π°Π±Ρ‹ Ρ‡Π΅Π³ΠΎ-Π½ΠΈΡ‚ΡŒ Π½Π°Ρ‚Ρ‹ΠΊΠ°ΡŽΡ‚ ΠΈ всС ΠΏΠΎΠ»ΠΎΠΌΠ°ΡŽΡ‚". ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ "эмпиричСским" ΠΏΡƒΡ‚Π΅ΠΌ Π½Π°Ρ…ΠΎΠ΄ΠΈΠ»ΠΈ мСсто ΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ Ρ‚ΠΎΡ€ΠΌΠΎΠ·ΠΎΠ² ΠΈ выпускали ΠΏΠ°Ρ‚Ρ‡. Если Π³Ρ€ΠΎΠ·Π½ΠΎΠ΅ письмо ΠΎΡ‚ DBA Π½Π΅ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ Π² блиТайшСС врСмя, Ρ‚ΠΎ всС с ΠΎΠ±Π»Π΅Π³Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Π²Ρ‹Π΄Ρ‹Ρ…Π°Π»ΠΈ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π»ΠΈΡΡŒ ΠΊ своим Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ Π·Π°Π΄Π°Ρ‡Π°ΠΌ (Π΄ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ Письма).

Но процСсс ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ вСсСло ΠΈ Π΄Ρ€ΡƒΠΆΠ΅Π»ΡŽΠ±Π½ΠΎ, Π° самоС Π³Π»Π°Π²Π½ΠΎΠ΅ β€” доступно ΠΈ ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΠΎ для всСх. Π₯отя Π±Ρ‹ базовая Π΅Π³ΠΎ Ρ‡Π°ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ основным систСмам ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ бСзусловно ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ ΠΈ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях Π½Π΅Π·Π°ΠΌΠ΅Π½ΠΈΠΌΡ‹). Π›ΡŽΠ±Π°Ρ Π‘Π£Π‘Π” свободно ΠΈ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ Π±Π΅Π·Π²ΠΎΠ·ΠΌΠ΅Π·Π΄Π½ΠΎ Π³ΠΎΡ‚ΠΎΠ²Π° ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΎ своСм Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ состоянии ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Π’ Ρ‚ΠΎΠΉ ΠΆΠ΅ самой "ΠΊΡ€ΠΎΠ²Π°Π²ΠΎΠΉ" Oracle DB практичСски Π»ΡŽΠ±ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈΠ· систСмных прСдставлСний, начиная ΠΎΡ‚ процСссов ΠΈ сСссий ΠΈ заканчивая состояниСм Π±ΡƒΡ„Π΅Ρ€Π½ΠΎΠ³ΠΎ кСша (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, DBA Scripts, Ρ€Π°Π·Π΄Π΅Π» "Monitoring"). Π’ Postgresql Ρ‚Π°ΠΊΠΆΠ΅ Π΅ΡΡ‚ΡŒ цСлая Ρ€ΠΎΡΡΡ‹ΠΏΡŒ систСмных прСдставлСний для ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π‘Π”, Π² частности Ρ‚Π°ΠΊΠΈΠ΅ Π½Π΅Π·Π°ΠΌΠ΅Π½ΠΈΠΌΡ‹Π΅ Π² повсСднСвной ΠΆΠΈΠ·Π½ΠΈ любого DBA, ΠΊΠ°ΠΊ pg_stat_activity, pg_stat_database, pg_stat_bgwriter. Π’ MySQL для этого ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° Π΄Π°ΠΆΠ΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ схСма performance_schema. А Π’ Mongo встроСнный ΠΏΡ€ΠΎΡ„Π°ΠΉΠ»Π΅Ρ€ Π°Π³Ρ€Π΅Π³ΠΈΡ€ΡƒΠ΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π² ΡΠΈΡΡ‚Π΅ΠΌΠ½ΡƒΡŽ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ system.profile.

Π’.ΠΎ., Π²ΠΎΠΎΡ€ΡƒΠΆΠΈΠ²ΡˆΠΈΡΡŒ ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ сборщиком ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊ (Telegraf, Metricbeat, Collectd), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΌΠ΅Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ кастомныС sql-запросы, Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ΠΌ этих ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊ (InfluxDB, Elasticsearch, Timescaledb) ΠΈ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ (Grafana, Kibana), ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ достаточно Π»Π΅Π³ΠΊΡƒΡŽ ΠΈ Π³ΠΈΠ±ΠΊΡƒΡŽ систСму ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π°, которая Π±ΡƒΠ΄Π΅Ρ‚ тСсно ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π° с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ общСсистСмными ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ°ΠΌΠΈ (ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΡ‹ΠΌΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΡ‚ сСрвСра ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΎΡ‚ ОБ ΠΈ ΠΏΡ€.). Как, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, это сдСлано Π² pgwatch2, Π³Π΄Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ связка InfluxDB + Grafana ΠΈ Π½Π°Π±ΠΎΡ€ запросов ΠΊ систСмным прСдставлСниям, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ кастомныС запросы.

Π˜Ρ‚ΠΎΠ³ΠΎ

И это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ΅Ρ€Π΅Ρ‡Π΅Π½ΡŒ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ с нашСй Π‘Π” посрСдством ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ SQL-ΠΊΠΎΠ΄Π°. Π£Π²Π΅Ρ€Π΅Π½, ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π΅Ρ‰Π΅ мноТСство ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΉ, ΠΏΠΈΡˆΠΈΡ‚Π΅ Π² коммСнтариях. А ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ (ΠΈ самоС Π³Π»Π°Π²Π½ΠΎΠ΅ Π·Π°Ρ‡Π΅ΠΌ) это всС Π·Π°Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π² свой CI/CD pipeline ΠΌΡ‹ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π°Π·.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ