πŸŽ“ ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹ΠΉ SQL: сСкрСты профСссионалов

РассказываСм ΠΎ слоТных стратСгиях ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ запросов, ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Ρ… Ρ‚ΠΈΠΏΠ°Ρ… соСдинСний ΠΈ тонкостях использования SELECT.

Π—Π½Π°Π½ΠΈΠ΅ ΠΈΠ·Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… Π½ΠΈΠΆΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π²Π°ΠΌ:

  • Π‘ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ слоТныС ΠΈ эффСктивныС запросы.
  • ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ….

ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ запросов

ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ SQL-запросов β€” ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ Π½Π°Π²Ρ‹ΠΊ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ администратора Π‘Π” ΠΈ бэкСнд-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°. ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Π°Ρ оптимизация Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ Π·Π° Ρ€Π°ΠΌΠΊΠΈ индСксации ΠΈ Ρ€Π΅Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ½Π³Π° запросов β€” пСрСчислим ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ запросы ΠΏΠΎ-настоящСму эффСктивными.

1. План выполнСния запроса

План выполнСния запроса ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π΅ΡˆΠ°ΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ β€” ΠΎΠ½ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ Π΄Π²ΠΈΠΆΠΎΠΊ SQL выполняСт запрос, ΠΈ раскрываСт ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ½Ρ‹Π΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹.

  • EXPLAIN β€” прСдоставляСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ запрос, позволяя Π²Ρ‹ΡΠ²Π»ΡΡ‚ΡŒ нСэффСктивныС участки:
EXPLAIN SELECT column1, column2 FROM table_name WHERE condition;
  • ANALYZE β€” ΠΏΡ€ΠΈ использовании вмСстС с EXPLAIN выполняСт запрос ΠΈ прСдоставляСт статистику ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ выполнСния. Π­Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΎΡ†Π΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ запроса:
EXPLAIN ANALYZE SELECT column1, column2 FROM table_name WHERE condition;
πŸ’» Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста»

2. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ подзапросов

Π’ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… случаях подзапросы ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π½Π° Π±ΠΎΠ»Π΅Π΅ эффСктивныС соСдинСния ΠΈΠ»ΠΈ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹Π΅ Ρ‚Π°Π±Π»ΠΈΡ‡Π½Ρ‹Π΅ выраТСния с ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ WITH.

  • Π—Π°ΠΌΠ΅Π½Π° подзапросов соСдинСниями:
-- ΠŸΠΎΠ΄Π·Π°ΠΏΡ€ΠΎΡ
SELECT * FROM table1 WHERE column1 IN (SELECT column1 FROM table2);

-- Π­ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ‚Π½ΠΎΠ΅ соСдинСниС
SELECT table1.* FROM table1 INNER JOIN table2 ON table1.column1 = table2.column1;
  • ИспользованиС ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹Ρ… Ρ‚Π°Π±Π»ΠΈΡ‡Π½Ρ‹Ρ… Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ:
WITH CTE AS (
    SELECT column1, column2 FROM table_name WHERE condition
)
SELECT * FROM CTE WHERE another_condition;

3. Π‘Ρ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΠΈ индСксирования

ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ стратСгии индСксирования Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ использованиС составных индСксов ΠΈ ΠΏΠΎΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ… индСксов.

  • Боставной индСкс Π²ΠΊΠ»ΡŽΡ‡Π°eΡ‚ нСсколько столбцов ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ запросы, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡŽ ΠΏΠΎ этим столбцам:
CREATE INDEX idx_composite ON table_name (column1, column2);
  • ΠŸΠΎΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ индСкс Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ всС столбцы, ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌΡ‹Π΅ запросом, ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ:
CREATE INDEX idx_covering ON table_name (column1, column2, column3);

4. ΠŸΠ°Ρ€Ρ‚ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ (сСкционированиС)

ΠŸΠ°Ρ€Ρ‚ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ (Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ большой Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π½Π° Π±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π»ΠΊΠΈΠ΅) ΡƒΠ»ΡƒΡ‡ΡˆΠ°Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ (Π·Π° счСт сокращСния объСма Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠ°Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ), Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π°Ρ€Ρ…ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅.

  • Π”ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π½ΠΎΠ΅ сСкционированиС эффСктивно для Π΄Π°Π½Π½Ρ‹Ρ… с Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ ΠΈΠ»ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ (Π΄Π°Ρ‚Ρ‹ ΠΈΠ»ΠΈ Π½ΠΎΠΌΠ΅Ρ€Π° Π·Π°ΠΊΠ°Π·ΠΎΠ²):
CREATE TABLE orders (
    order_id INT,
    order_date DATE,
    ...
) PARTITION BY RANGE (order_date) (
    PARTITION p0 VALUES LESS THAN ('2024-01-01'),
    PARTITION p1 VALUES LESS THAN ('2025-01-01'),
    ...
);
  • Π‘Π΅ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ Ρ…ΡΡˆΡƒ распрСдСляСт Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ количСству ΠΏΠ°Ρ€Ρ‚ΠΈΡ†ΠΈΠΉ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ…Π΅Ρˆ-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для достиТСния равномСрности, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΈ вставкС ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ:
CREATE TABLE users (
    user_id INT,
    username VARCHAR(255),
    ...
) PARTITION BY HASH(user_id) PARTITIONS 4;
  • Π‘Π΅ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ списку примСняСтся, ΠΊΠΎΠ³Π΄Π° значСния столбца ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ катСгориям ΠΈΠ»ΠΈ Π³Ρ€ΡƒΠΏΠΏΠ°ΠΌ:
CREATE TABLE sales (
    sale_id INT,
    region VARCHAR(255),
    ...
) PARTITION BY LIST (region) (
    PARTITION p0 VALUES IN ('North', 'South'),
    PARTITION p1 VALUES IN ('East', 'West')
);

5. ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ прСдставлСния

ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ прСдставлСния физичСски хранят Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния запроса ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ пСриодичСски ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒΡΡ. Π­Ρ‚ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠ°Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ для слоТных запросов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ часто.

  • Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ прСдставлСния:
CREATE MATERIALIZED VIEW sales_summary AS
SELECT region, SUM(sales_amount) AS total_sales
FROM sales
GROUP BY region;
  • ОбновлСниС ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ прСдставлСния:
REFRESH MATERIALIZED VIEW sales_summary;

ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ прСдставлСния Π² MySQL

MySQL Π½Π΅ располагаСт встроСнной ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… прСдставлСний, Π½ΠΎ ΠΏΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ Ρ‚Π°ΠΊΡƒΡŽ Ρ„ΠΈΡ‡Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ, двумя способами β€” с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈ Π·Π°ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π·Π°Π΄Π°Π½ΠΈΠΉ, Π»ΠΈΠ±ΠΎ с использованиСм Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΎΠ².

Π‘ использованиСм Ρ‚Π°Π±Π»ΠΈΡ† ΠΈ Π·Π°ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ

Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² создании Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, хранящСй Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ запроса, ΠΈ Π΅Π΅ пСриодичСском ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π·Π°ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… событий (cron-Π·Π°Π΄Π°Π½ΠΈΠΉ).

Π‘Π½Π°Ρ‡Π°Π»Π° создайтС Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ для хранСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ²:

CREATE TABLE MaterializedActiveCustomers AS
SELECT CustomerID, CustomerName, ContactName, Country
FROM Customers
WHERE Status = 'Active';

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π·Π°ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ событиС для пСриодичСского обновлСния Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ событиС MySQL для обновлСния Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ час:

CREATE EVENT UpdateMaterializedActiveCustomers
ON SCHEDULE EVERY 1 HOUR
DO
BEGIN
    DELETE FROM MaterializedActiveCustomers;
    INSERT INTO MaterializedActiveCustomers
    SELECT CustomerID, CustomerName, ContactName, Country
    FROM Customers
    WHERE Status = 'Active';
END;

Π­Ρ‚ΠΎ событиС ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ час ΠΎΡ‡ΠΈΡ‰Π°Π΅Ρ‚ ΠΈ Π·Π°Π½ΠΎΠ²ΠΎ заполняСт Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ MaterializedActiveCustomers послСдними Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ.

Π‘ использованиСм Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΎΠ²

ΠŸΡ€ΠΈ этом ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π΅ для синхронизации Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹-прСдставлСния с основными Ρ‚Π°Π±Π»ΠΈΡ†Π°ΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹. По ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ этот способ слоТнСС, ΠΈ ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ ΠΌΠ΅Π½Π΅Π΅ эффСктивСн для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Π½Π°Π±ΠΎΡ€ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ….

Π‘Π½Π°Ρ‡Π°Π»Π° создайтС Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ:

CREATE TABLE MaterializedActiveCustomers AS
SELECT CustomerID, CustomerName, ContactName, Country
FROM Customers
WHERE Status = 'Active';

Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ для обновлСния ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹:

DELIMITER //

CREATE TRIGGER after_customer_insert
AFTER INSERT ON Customers
FOR EACH ROW
BEGIN
    IF NEW.Status = 'Active' THEN
        INSERT INTO MaterializedActiveCustomers (CustomerID, CustomerName, ContactName, Country)
        VALUES (NEW.CustomerID, NEW.CustomerName, NEW.ContactName, NEW.Country);
    END IF;
END //

CREATE TRIGGER after_customer_update
AFTER UPDATE ON Customers
FOR EACH ROW
BEGIN
    IF OLD.Status = 'Active' AND NEW.Status != 'Active' THEN
        DELETE FROM MaterializedActiveCustomers WHERE CustomerID = OLD.CustomerID;
    ELSEIF NEW.Status = 'Active' THEN
        REPLACE INTO MaterializedActiveCustomers (CustomerID, CustomerName, ContactName, Country)
        VALUES (NEW.CustomerID, NEW.CustomerName, NEW.ContactName, NEW.Country);
    END IF;
END //

CREATE TRIGGER after_customer_delete
AFTER DELETE ON Customers
FOR EACH ROW
BEGIN
    DELETE FROM MaterializedActiveCustomers WHERE CustomerID = OLD.CustomerID;
END //

DELIMITER ;

Π­Ρ‚ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ обСспСчат Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ MaterializedActiveCustomers ΠΏΡ€ΠΈ измСнСниях Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Customers.

ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ использования соСдинСний

ΠŸΡ€ΠΎΡΡ‚Ρ‹Π΅ соСдинСния ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ‚Π°Π±Π»ΠΈΡ† сразу, Π° ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ Π΄Π΅Π»Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ слоТныС Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒ ряд Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… манипуляций.

1. БамосоСдинСния

Π’Π°ΠΊΠΈΠ΅ соСдинСния ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ строки ΠΈΠ· ΠΎΠ΄Π½ΠΎΠΉ ΠΈ Ρ‚ΠΎΠΉ ΠΆΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ€Π°Π·Π½Ρ‹Π΅ псСвдонимы. Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΠ·Π²Π»Π΅ΠΊΠ°ΡŽΡ‚ΡΡ сотрудники ΠΈ ΠΈΠΌΠ΅Π½Π° ΠΈΡ… ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ΠΎΠ²:

SELECT a.employee_id, a.name, b.name AS manager_name
FROM employees a
INNER JOIN employees b ON a.manager_id = b.employee_id;

2. Π›Π°Ρ‚Π΅Ρ€Π°Π»ΡŒΠ½Ρ‹Π΅ соСдинСния

ΠšΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово LATERAL позволяСт подзапросам ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° столбцы ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Ρ‚Π°Π±Π»ΠΈΡ†, ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Π² FROM. Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строки ΠΈΠ· table1 выполняСтся подзапрос, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ ΠΎΠ΄Π½Ρƒ строку ΠΈΠ· table2, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ b.column1 = a.column1, ΠΎΡ‚ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΏΠΎ b.column2 Π² порядкС убывания:

SELECT a.*, b.*
FROM table1 a
LEFT JOIN LATERAL (
    SELECT *
    FROM table2 b
    WHERE b.column1 = a.column1
    ORDER BY b.column2 DESC
    LIMIT 1
) b ON TRUE;

3. ΠŸΠΎΠ»Π½Ρ‹Π΅ внСшниС соСдинСния с COALESCE

Π­Ρ‚Π° Ρ‚Π΅Ρ…Π½ΠΈΠΊΠ° позволяСт ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ получСния NULL Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ внСшнСго соСдинСния. Ѐункция COALESCE Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· списка. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС, Ссли a.column1 Π½Π΅ являСтся NULL, возвращаСтся Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΈΠ½Π°Ρ‡Π΅ возвращаСтся b.column1:

SELECT COALESCE(a.column1, b.column1) AS column1, a.column2, b.column2
FROM table1 a
FULL OUTER JOIN table2 b ON a.column1 = b.column1;

4. ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ соСдинСний

Для Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΡ‡Π½ΠΎΠΉ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π² соСдинСниях ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ слоТныС условия. Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ соСдинСниС производится с Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ условиСм Π½Π° a.date_column, Ρ‡Ρ‚ΠΎ позволяСт ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΏΠΎ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Ρƒ Π΄Π°Ρ‚:

SELECT a.column1, b.column2
FROM table1 a
INNER JOIN table2 b ON a.column1 = b.column1 AND a.date_column BETWEEN '2023-01-01' AND '2023-12-31';

5. АнтисоСдинСния ΠΈ полусоСдинСния

Π­Ρ‚ΠΈ Ρ‚ΠΈΠΏΡ‹ соСдинСний ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ для запросов ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ соотвСтствСнно.

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ антисоСдинСниС ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ строки ΠΈΠ· Π»Π΅Π²ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… строк Π² ΠΏΡ€Π°Π²ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅:

SELECT a.*
FROM table1 a
LEFT JOIN table2 b ON a.column1 = b.column1
WHERE b.column1 IS NULL;

А здСсь полусоСдинСниС ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ строки ΠΈΠ· Π»Π΅Π²ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… сущСствуСт ΠΎΠ΄Π½Π° ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… строк Π² ΠΏΡ€Π°Π²ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅:

SELECT a.*
FROM table1 a
WHERE EXISTS (SELECT 1 FROM table2 b WHERE a.column1 = b.column1);

ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ использования SELECT

ВозмоТности ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° SELECT Π»Π΅Π³ΠΊΠΎ Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями β€” это ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Ρ€Π΅ΡˆΠ°Ρ‚ΡŒ самыС слоТныС Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΡŽ Π΄Π°Π½Π½Ρ‹Ρ….

1. ΠžΠΊΠΎΠ½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

ΠžΠΊΠΎΠ½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ вычислСния ΠΏΠΎ Π½Π°Π±ΠΎΡ€Ρƒ строк Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, связанных с Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ строкой, ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΌΠΎΡ‰Π½Ρ‹Π΅ аналитичСскиС возмоТности.

  • НумСрация строк:
SELECT column1, column2, ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column2) AS row_num
FROM table_name;
  • ΠΠ°ΠΊΠΎΠΏΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΈΡ‚ΠΎΠ³:
SELECT column1, column2, SUM(column2) OVER (ORDER BY column1) AS running_total
FROM table_name;
  • Π Π°Π½ΠΆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅:
SELECT column1, column2, RANK() OVER (PARTITION BY column1 ORDER BY column2) AS rank
FROM table_name;
  • Π‘ΠΊΠΎΠ»ΡŒΠ·ΡΡ‰Π΅Π΅ срСднСС:
SELECT column1, column2, AVG(column2) OVER (PARTITION BY column1 ORDER BY column2 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_avg
FROM table_name;

2. РСкурсивныС ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹Π΅ Ρ‚Π°Π±Π»ΠΈΡ‡Π½Ρ‹Π΅ выраТСния

Π’Π°ΠΊΠΈΠ΅ ΠžΠ’Π’ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ рСкурсивныС запросы, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с иСрархичСскими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ:

WITH RECURSIVE cte AS (
    SELECT column1, column2
    FROM table_name
    WHERE condition
    UNION ALL
    SELECT t.column1, t.column2
    FROM table_name t
    INNER JOIN cte ON t.column1 = cte.column1
)
SELECT * FROM cte;

3. JSON Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π‘Π£Π‘Π” часто Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ JSON Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹.

  • Π˜Π·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈΠ· JSON:
SELECT json_column->>'key' AS value
FROM table_name;
  • АгрСгация Π² JSON:
SELECT json_agg(row_to_json(t))
FROM (SELECT column1, column2 FROM table_name) t;
  • ОбновлСниС JSON Π΄Π°Π½Π½Ρ‹Ρ…:
UPDATE table_name
SET json_column = jsonb_set(json_column, '{key}', '"new_value"', true)
WHERE condition;

4. ΠŸΠΈΠ²ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…

ΠŸΠΈΠ²ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ строки Π² столбцы, ΠΏoзволяя Ρ€Π΅ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΡΡƒΠΌΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ для составлСния ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΎΠ². Для пивотирования ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ CASE выраТСния:

SELECT
    category,
    SUM(CASE WHEN year = 2021 THEN sales ELSE 0 END) AS sales_2021,
    SUM(CASE WHEN year = 2022 THEN sales ELSE 0 END) AS sales_2022
FROM sales_data
GROUP BY category;

5. ДинамичСский SQL

ДинамичСский SQL позволяСт Π½Π° Π»Π΅Ρ‚Ρƒ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ SQL выраТСния для выполнСния слоТных запросов.

  • Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ динамичСского SQL:
EXECUTE 'SELECT * FROM ' || table_name || ' WHERE ' || condi
  • ИспользованиС ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹Ρ… Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ:
PREPARE stmt AS SELECT * FROM table_name WHERE column1 = $1;
EXECUTE stmt('value

ПодвСдСм ΠΈΡ‚ΠΎΠ³ΠΈ

ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ SQL-Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚:

  • Π Π΅ΡˆΠ°Ρ‚ΡŒ самыС слоТныС Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ манипуляции ΠΈ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΡŽ Π΄Π°Π½Π½Ρ‹Ρ….
  • ΠžΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ… большиС ΠΎΠ±ΡŠΠ΅ΠΌΡ‹ Π΄Π°Π½Π½Ρ‹Ρ….

ПониманиС ΠΏΠ»Π°Π½ΠΎΠ² выполнСния, использованиС ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Ρ… соСдинСний, ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ слоТных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ с SELECT ΠΈ рСализация стратСгий индСксации β€” Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Π½Π°Π²Ρ‹ΠΊΠΈ для любого спСциалиста, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π³ΠΎ с Π±Π°Π·Π°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ…: администратора, бэкСнд-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ°. Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ этих Ρ‚Π΅Ρ…Π½ΠΈΠΊ Π² Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ процСсс ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΡŒ слоТных ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ… Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ….

***

ΠŸΡ€ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ использовалась публикация Advanced SQL: Mastering Query Optimization and Complex Joins.

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

eFusion
08 января 2020

11 Ρ‚ΠΈΠΏΠΎΠ² соврСмСнных Π±Π°Π· Π΄Π°Π½Π½Ρ‹Ρ…: ΠΊΡ€Π°Ρ‚ΠΊΠΈΠ΅ описания, схСмы ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π‘Π”

Π›ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π³Π΄Π΅-Ρ‚ΠΎ хранятся. Π‘ΡƒΠ΄ΡŒ это ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Π²Π΅Ρ‰Π΅ΠΉ ΠΈΠ»ΠΈ ΠΏΠ°Ρ€ΠΎΠ»ΠΈ Π² *nix. По...
Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
29 июня 2017

5 сайтов для оттачивания Π½Π°Π²Ρ‹ΠΊΠΎΠ² написания SQL-запросов

Одним ΠΈΠ· ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… Π½Π°Π²Ρ‹ΠΊΠΎΠ² ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π±Π°Π·Π°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ… являСтся ΡƒΠΌΠ΅Π½ΠΈΠ΅ ΠΏΠΈΡΠ°Ρ‚ΡŒ...
admin
23 фСвраля 2017

SQL Π·Π° 20 ΠΌΠΈΠ½ΡƒΡ‚

ΠŸΡ€Π΅Π΄Π»Π°Π³Π°Π΅ΠΌ Π²Π°ΡˆΠ΅ΠΌΡƒ вниманию ΡΡ‚Π°Ρ‚ΡŒΡŽ с ΠΊΡ€ΠΈΡ‡Π°Ρ‰ΠΈΠΌ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ "SQL Π·Π° 20 ΠΌΠΈΠ½ΡƒΡ‚". К...