Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Database First!
О распространённых ошибках
использования РСУБД
Николай Самохвалов
@postgresmen
ru@postgresql.org
О чём и зачем этот доклад
БД — сердце IT-системы
РСУБД и SQL занимают лидирующие позиции.
И это надолго
Не использовать по...
О докладчике
• ФУПМ МФТИ / ИСП РАН / «Базы данных»
• MoiKrug (2005), MirTesen (2007), Postila (2013)
• PostgreSQL-консалти...
Проблемы использования SQL & РСУБД
• боязнь и незнание возможностей РСУБД/SQL:
• для контроля данных
• для манипулирования...
Ошибка №1:
неиспользование ограничений
целостности
Последствия ошибки №1
1. Отсутствие Primary Key (PK):
• дубликаты, грязные данные;
• нарушение реляционной модели и вытека...
Последствия ошибки №1
1. Отсутствие Primary Key (PK):
• дубликаты, грязные данные;
• нарушение реляционной модели и вытека...
Последствия ошибки №1
1. Отсутствие Primary Key (PK):
• дубликаты, грязные данные;
• нарушение реляционной модели и вытека...
Последствия ошибки №1
1. Отсутствие Primary Key (PK)
2. Только суррогатный PK,
но нет Unique Key(s) (UKs)
3. Не используют...
Последствия ошибки №1
1. Отсутствие Primary Key (PK)
2. Только суррогатный PK, но нет Unique Key(s) (UKs)
3. Не используют...
Последствия ошибки №1
1. Отсутствие Primary Key (PK)
2. Только суррогатный PK, но нет Unique Key(s) (UKs)
3. Не используют...
Ещё более фундаментальное — типы данных
0. Типы данных
● недостаточно жёсткие ограничения текста (text, varchar(5000) и т....
Ещё более фундаментальное — типы данных
0. Типы данных
● недостаточно жёсткие ограничения текста (text, varchar(5000) и т....
Ещё более фундаментальное — типы данных
0. Типы данных
● недостаточно жёсткие ограничения текста (text, varchar(5000) и т....
Ещё более фундаментальное — типы данных
0. Типы данных
● недостаточно жёсткие ограничения текста (text, varchar(5000) и т....
А что если проверять данные в приложении?
Data Checks (format, constraints, etc)
in App (Ruby or Python or PHP or …)
А что если проверять данные в приложении? Oops
Data Checks (format, constraints, etc)
in App (Ruby or Python or PHP or …)
Проверка данных только в приложении — не надо так!
Data Checks (format, constraints, etc)
in App (Ruby or Python or PHP or...
Проверка данных — а как правильно?
App (Ruby or Python or PHP or …)
CHECKS
Проверка данных — а как правильно?
App (Ruby or Python or PHP or …)
CHECKS
Контроль данных
средствами СУБД:
- чёткая типиз...
Немного о JSON(b) – от неструктурированных данных
к слабоструктурированным (semi-structured)
Немного о JSON(b) – от неструктурированных данных
к слабоструктурированным (semi-structured)
Делаем ключ color обязательным
Немного о JSON(b) – от неструктурированных данных
к слабоструктурированным (semi-structured)
Делаем ключ color обязательны...
Откуда взялось недоверие к СУБД?
Роль MySQL в росте страхов и невежества
Роль MySQL в росте страхов и невежества
Роль MySQL в росте страхов и невежества
Роль MySQL и MariaDB в росте страхов и невежества
Не допускаем ошибку №1
0. Полноценно используем типы данных
a. citext для регистронезависимых сравнений
b. varchar(XX) пос...
Ошибка №2:
неиспользование возможностей SQL
для манипуляции данными
Пример 2.1: инкремент
● Начинающий РНР-программист, задача массовой отправки писем.
● Последовательный перебор по возраста...
Пример 2.1: инкремент
Что получим, если потоков несколько?
3 потока, каждый
«отправил» по 100 писем
2.1) Что не так? Транзакция 1
Транзакция 2, использует
значение из первой
2.1) СУБД сама может сделать инкремент!
Единственная транзакция,
очень короткая,
UPDATE с RETURNING,
до каких-либо действий
2.1) СУБД сама может сделать инкремент!
3 потока, каждый
«отправил» по 100 писем
Пример 2.2: обновление/удаление группы строк
Задача той самой «чистки» трубочиста. Ruby, опытный СТО.
Пример 2.2: обновление/удаление группы строк
Задача той самой «чистки» трубочиста. Ruby, опытный СТО.
Зачем-то «тянем» IDs...
Пример 2.2: обновление/удаление группы строк
…и генерим длинный список из ID…
(а что, если их миллионы?)
Зачем-то «тянем» ...
Пример 2.2: обновление/удаление группы строк
Полностью IDs, которые оставим
Пример 2.2: обновление/удаление группы строк
Полностью
А это мы хотим «забрать с собой»
Пример 2.2: обновление/удаление группы строк
Полностью
А это мы хотим «забрать с собой»
… и забираем
Пример 2.2: обновление/удаление группы строк
Полностью
Само удаление с перечислением ID
через запятую. Предварительно убра...
Пример 2.2: более правильное решение — CTE
Используем CTE (Common Table Expressions):
Пример 2.2: как это делать с CTE
Boilerplate:
Пример 2.2: как это делать с CTE
Boilerplate:
Не забыли: PK, NOT NULL
Пример 2.2: как это делать с CTE
Boilerplate:
Используем типы
правильно: int2,
timestamp with time zone
Пример 2.2: как это делать с CTE
Boilerplate:
ЗАБЫЛИ!!
Natural Key — пара (year, month)
(т.к. «успокоились» на суррогатном...
Пример 2.2: как это делать с CTE
Вставляем данные:
Пример 2.2: как это делать с CTE
Вставляем данные: У природы нет плохой
погоды
(особенно с 2000-то года)
Пример 2.2: как это делать с CTE
Вставляем данные:
Но на самом деле есть.
Май 2017, ураган.
Пример 2.2: как это делать с CTE
Вставляем данные:
Ooops! INSERT вместо
UPDATE...
Пример 2.2: как это делать с CTE
Получили грязные данные, дубликаты:
Пример 2.2: как это делать с CTE
Получили грязные данные, дубликаты:
Пример 2.2: как это делать с CTE
UK уже не создать, поздно пить «Боржоми»:
Время собирать камни дубликаты. С помощью четыр...
Пример 2.2: как это делать с CTE. Action!
Пример 2.2: как это делать с CTE. Action!
IDs, которые оставим
Пример 2.2: как это делать с CTE. Action!
А это мы хотим «забрать с собой»
Пример 2.2: как это делать с CTE. Action!
А это мы хотим «забрать с собой»
… и забираем
Пример 2.2: как это делать с CTE. Action!
Так получаем IDs, которые будем удалять:
все IDs группы за вычетом keep_id
Пример 2.2: как это делать с CTE. Action!
Так получаем IDs, которые будем удалять:
все IDs группы за вычетом keep_id
… и в...
Пример 2.2: как это делать с CTE. Action!
У UPDATE и DELETE есть RETURNING *
Пример 2.2: как это делать с CTE. Action!
У UPDATE и DELETE есть RETURNING *
…которые дают нам получить 2 числа
— количест...
Пример 2.2: как это делать с CTE. Action!
Результат:
Пример 2.2: как это делать с CTE. Action!
Результат:
Пример 2.2: O CTE и современном SQL
Внимание: если строк удаляем/обновляем много,
может понадобиться поэтапная работа с па...
Пример 2.2: O CTE и современном SQL
О современном SQL
Максим Богук:
● «Неклассические приемы оптимизации запросов» (2014)
...
Пример 2.3: тянем данные на клиент
 Часто (Machine Learning, Data Science) – вытягивание огромного количества
данных на кл...
MADlib: Machine Learning inside your DBMS
- A lot of ML algorithms implemented (more in each release):
- PL/Python
- Very ...
MADlib: Machine Learning inside your DBMS
Source: Apache MADlib: Distributed In-Database Machine Learning for Fun and Prof...
Data Manipulation Logic
in App (Ruby or Python or PHP or …)
Something*
* ElasticSearch, Sphix, Analytics DBMS, etc
Пример ...
Пример 2.4
Data Manipulation Logic
in App (Ruby or Python or PHP or …)
Something*
* ElasticSearch, Sphix, Analytics DBMS, ...
Пример 2.4
Data Manipulation Logic
in App (Ruby or Python or PHP or …)
Something*
* ElasticSearch, Sphix, Analytics DBMS, ...
Пример 2.4
App (Ruby or Python or PHP or …)
Something*
* ElasticSearch, Sphix, Analytics DBMS, etc
Data
Manipulation
Use:
...
Database First! Что важно помнить
● Делать вообще всё в СУБД можно, но в некоторых случаях неоправданно
○ пример: работа с...
Database First! Что важно помнить
● Делать вообще всё в СУБД можно, но в некоторых случаях неоправданно
○ пример: работа с...
Database First! Что важно помнить
● Делать вообще всё в СУБД можно, но в некоторых случаях неоправданно
○ пример: работа с...
Database First! Что важно помнить
● Делать вообще всё в СУБД можно, но в некоторых случаях неоправданно
○ пример: работа с...
Database First! Checklist
➜ Типы данных
✓ varchar(N) построже
✓ int8 для PK больших таблиц
✓ int2, где диапазон мал
✓ time...
Thank you!
Twitter: @postgresmen (new Postgres tweets daily!)
ru@postgresql.org
http://RuPostgres.org
http://Postgres.chat
Database First! О распространённых ошибках использования РСУБД / Николай Самохвалов (Postila)
Upcoming SlideShare
Loading in …5
×

Database First! О распространённых ошибках использования РСУБД / Николай Самохвалов (Postila)

1,177 views

Published on

РИТ++ 2017, HighLoad Junior
Зал Сингапур, 5 июня, 13:00

Тезисы:
http://junior.highload.ru/2017/abstracts/2702.html

Любой Full Stack Developer сегодня обязан иметь в своём арсенале опыт и умение работы хотя бы с одной популярной РСУБД. Но без понимания основ — того, какие задачи решают СУБД, как происходит работа с данными, какие есть базовые возможности для этой работы, — такие умения превращаются в воздушный замок, быстро разрушающийся при росте проекта.

Этот доклад — попытка разбудить интерес слушателей к тщательному изучению основ теории и практики реляционных баз данных и к применению всей мощи РСУБД по прямому назначению.
...

Published in: Engineering
  • Be the first to comment

Database First! О распространённых ошибках использования РСУБД / Николай Самохвалов (Postila)

  1. 1. Database First! О распространённых ошибках использования РСУБД Николай Самохвалов @postgresmen ru@postgresql.org
  2. 2. О чём и зачем этот доклад БД — сердце IT-системы РСУБД и SQL занимают лидирующие позиции. И это надолго Не использовать полноценно их возможности — глупость* ___________________ * Получается глупо, потому что: 1) качество хуже, 2) производительность ниже, 3) потом всё равно придётся исправлять (возможно, уже не вам)
  3. 3. О докладчике • ФУПМ МФТИ / ИСП РАН / «Базы данных» • MoiKrug (2005), MirTesen (2007), Postila (2013) • PostgreSQL-консалтинг с 2007 в России, с 2013 в Калифорнии • #RuPostgres (http://rupostgres.org) — вторая крупнейшая митап-группа в мире • Postgres-твиттер (3500+ подписчиков): @postgresmen • ПК конференций HLj, BackendConf, Highload++, PgDay Russia
  4. 4. Проблемы использования SQL & РСУБД • боязнь и незнание возможностей РСУБД/SQL: • для контроля данных • для манипулирования данными • архитектурные ошибки, связанные с этими страхами и невежеством
  5. 5. Ошибка №1: неиспользование ограничений целостности
  6. 6. Последствия ошибки №1 1. Отсутствие Primary Key (PK): • дубликаты, грязные данные; • нарушение реляционной модели и вытекающие проблемы (аномалии данных, неожиданные результаты JOIN и т.д.) • рано или поздно приходится чистить (долго, дорого)
  7. 7. Последствия ошибки №1 1. Отсутствие Primary Key (PK): • дубликаты, грязные данные; • нарушение реляционной модели и вытекающие проблемы (аномалии данных, неожиданные результаты JOIN и т.д.) • рано или поздно приходится чистить (долго, дорого) 2. Только «суррогатный» PK, но нет Unique Key(s) (UKs): • «скрытые» дубликаты, опять грязные данные и проблемы • опять необходимость чистки (долго, дорого)
  8. 8. Последствия ошибки №1 1. Отсутствие Primary Key (PK): • дубликаты, грязные данные; • нарушение реляционной модели и вытекающие проблемы (аномалии данных, неожиданные результаты JOIN и т.д.) • рано или поздно приходится чистить (долго, дорого) 2. Только «суррогатный» PK, но нет Unique Key(s) (UKs): • «скрытые» дубликаты, опять грязные данные и проблемы • опять необходимость чистки (долго, дорого) Числовые PK вида 1, 2, … («суррогатные») — это иллюзия правильного проектирования, легко забыть о потенциальных ключах!
  9. 9. Последствия ошибки №1 1. Отсутствие Primary Key (PK) 2. Только суррогатный PK, но нет Unique Key(s) (UKs) 3. Не используются Foreign Keys (FKs): • orphans (осиротевшие записи) → аномалии, ошибки 404, 500 • …и опять: придётся чистить!
  10. 10. Последствия ошибки №1 1. Отсутствие Primary Key (PK) 2. Только суррогатный PK, но нет Unique Key(s) (UKs) 3. Не используются Foreign Keys (FKs) 4. Не используются NOT NULLs: • неполные данные, бессмысленные записи, аномалии • опять. придётся. чистить.
  11. 11. Последствия ошибки №1 1. Отсутствие Primary Key (PK) 2. Только суррогатный PK, но нет Unique Key(s) (UKs) 3. Не используются Foreign Keys (FKs) 4. Не используются NOT NULLs 5. Не используются CHECK constraints: • мусор, некорректные данные • опять. придётся. чистить.
  12. 12. Ещё более фундаментальное — типы данных 0. Типы данных ● недостаточно жёсткие ограничения текста (text, varchar(5000) и т.п.) легко приводят к проблемам отображения (вёрстка и т.п.)
  13. 13. Ещё более фундаментальное — типы данных 0. Типы данных ● недостаточно жёсткие ограничения текста (text, varchar(5000) и т.п.) легко приводят к проблемам вёрстки ● varchar(250) или text превратить в varchar(50) — долго, дорого!
  14. 14. Ещё более фундаментальное — типы данных 0. Типы данных ● недостаточно жёсткие ограничения текста (text, varchar(5000) и т.п.) легко приводят к проблемам вёрстки ● varchar(250) или text превратить в varchar(50) — долго, дорого! ● PK типа integer в больших таблицах — бомба замедленного действия: ○ максимум 2147483647 (2.1 млрд) ○ перейти на int8 (aka bigint) — долго, дорого!
  15. 15. Ещё более фундаментальное — типы данных 0. Типы данных ● недостаточно жёсткие ограничения текста (text, varchar(5000) и т.п.) легко приводят к проблемам вёрстки ● varchar(250) или text превратить в varchar(50) — долго, дорого! ● PK типа integer в больших таблицах — бомба замедленного действия: ○ максимум 2147483647 (2.1 млрд) ○ перейти на int8 (aka bigint) — долго, дорого! ● Регистрозависимое поле email (varchar вместо citext и нет lower()): ○ аккаунты-дубликаты, жалобы «не могу войти»
  16. 16. А что если проверять данные в приложении? Data Checks (format, constraints, etc) in App (Ruby or Python or PHP or …)
  17. 17. А что если проверять данные в приложении? Oops Data Checks (format, constraints, etc) in App (Ruby or Python or PHP or …)
  18. 18. Проверка данных только в приложении — не надо так! Data Checks (format, constraints, etc) in App (Ruby or Python or PHP or …)
  19. 19. Проверка данных — а как правильно? App (Ruby or Python or PHP or …) CHECKS
  20. 20. Проверка данных — а как правильно? App (Ruby or Python or PHP or …) CHECKS Контроль данных средствами СУБД: - чёткая типизация, - все виды ограничений целостности
  21. 21. Немного о JSON(b) – от неструктурированных данных к слабоструктурированным (semi-structured)
  22. 22. Немного о JSON(b) – от неструктурированных данных к слабоструктурированным (semi-structured) Делаем ключ color обязательным
  23. 23. Немного о JSON(b) – от неструктурированных данных к слабоструктурированным (semi-structured) Делаем ключ color обязательным Без ключа color JSON-значение не принимается
  24. 24. Откуда взялось недоверие к СУБД?
  25. 25. Роль MySQL в росте страхов и невежества
  26. 26. Роль MySQL в росте страхов и невежества
  27. 27. Роль MySQL в росте страхов и невежества
  28. 28. Роль MySQL и MariaDB в росте страхов и невежества
  29. 29. Не допускаем ошибку №1 0. Полноценно используем типы данных a. citext для регистронезависимых сравнений b. varchar(XX) построже c. int8 в таблицах, которые вырастут, — сразу d. int2 для экономии, когда знаем, что диапазон значений точно будет мал e. timestamptz вместо timestamp f. tstzrange, int4range, int8range, numrange + exclusion constraint A Tour of PostgreSQL Data Types (2013), Tour de (PostgreSQL) Data Types (2017) 1. PK – обязательно 2. Максимально используем UKs (особенно если PK суррогатный — выявляем наш “natural key” и добавляем unique index!) 3. Используем FKs 4. Используем NOT NULLs 5. Используем CHECK constraints
  30. 30. Ошибка №2: неиспользование возможностей SQL для манипуляции данными
  31. 31. Пример 2.1: инкремент ● Начинающий РНР-программист, задача массовой отправки писем. ● Последовательный перебор по возрастанию User ID, сохранение «указателя» на last User ID в БД. ● Ошибки отправки отдельных писем не должны останавливать процесс.
  32. 32. Пример 2.1: инкремент Что получим, если потоков несколько? 3 потока, каждый «отправил» по 100 писем
  33. 33. 2.1) Что не так? Транзакция 1 Транзакция 2, использует значение из первой
  34. 34. 2.1) СУБД сама может сделать инкремент! Единственная транзакция, очень короткая, UPDATE с RETURNING, до каких-либо действий
  35. 35. 2.1) СУБД сама может сделать инкремент! 3 потока, каждый «отправил» по 100 писем
  36. 36. Пример 2.2: обновление/удаление группы строк Задача той самой «чистки» трубочиста. Ruby, опытный СТО.
  37. 37. Пример 2.2: обновление/удаление группы строк Задача той самой «чистки» трубочиста. Ruby, опытный СТО. Зачем-то «тянем» IDs на клиент
  38. 38. Пример 2.2: обновление/удаление группы строк …и генерим длинный список из ID… (а что, если их миллионы?) Зачем-то «тянем» IDs на клиент
  39. 39. Пример 2.2: обновление/удаление группы строк Полностью IDs, которые оставим
  40. 40. Пример 2.2: обновление/удаление группы строк Полностью А это мы хотим «забрать с собой»
  41. 41. Пример 2.2: обновление/удаление группы строк Полностью А это мы хотим «забрать с собой» … и забираем
  42. 42. Пример 2.2: обновление/удаление группы строк Полностью Само удаление с перечислением ID через запятую. Предварительно убрали из массива все [keep_id]
  43. 43. Пример 2.2: более правильное решение — CTE Используем CTE (Common Table Expressions):
  44. 44. Пример 2.2: как это делать с CTE Boilerplate:
  45. 45. Пример 2.2: как это делать с CTE Boilerplate: Не забыли: PK, NOT NULL
  46. 46. Пример 2.2: как это делать с CTE Boilerplate: Используем типы правильно: int2, timestamp with time zone
  47. 47. Пример 2.2: как это делать с CTE Boilerplate: ЗАБЫЛИ!! Natural Key — пара (year, month) (т.к. «успокоились» на суррогатном PK...)
  48. 48. Пример 2.2: как это делать с CTE Вставляем данные:
  49. 49. Пример 2.2: как это делать с CTE Вставляем данные: У природы нет плохой погоды (особенно с 2000-то года)
  50. 50. Пример 2.2: как это делать с CTE Вставляем данные: Но на самом деле есть. Май 2017, ураган.
  51. 51. Пример 2.2: как это делать с CTE Вставляем данные: Ooops! INSERT вместо UPDATE...
  52. 52. Пример 2.2: как это делать с CTE Получили грязные данные, дубликаты:
  53. 53. Пример 2.2: как это делать с CTE Получили грязные данные, дубликаты:
  54. 54. Пример 2.2: как это делать с CTE UK уже не создать, поздно пить «Боржоми»: Время собирать камни дубликаты. С помощью четырёхэтажного CTE: Выборка данных Правка created у тех, что останутся + RETURNING * Удаление лишних + RETURNING * Анализ результата (сколько UPDATEd, сколько DELETEd)
  55. 55. Пример 2.2: как это делать с CTE. Action!
  56. 56. Пример 2.2: как это делать с CTE. Action! IDs, которые оставим
  57. 57. Пример 2.2: как это делать с CTE. Action! А это мы хотим «забрать с собой»
  58. 58. Пример 2.2: как это делать с CTE. Action! А это мы хотим «забрать с собой» … и забираем
  59. 59. Пример 2.2: как это делать с CTE. Action! Так получаем IDs, которые будем удалять: все IDs группы за вычетом keep_id
  60. 60. Пример 2.2: как это делать с CTE. Action! Так получаем IDs, которые будем удалять: все IDs группы за вычетом keep_id … и вот так используем, с UNNEST, чтобы получить список ID для удаления
  61. 61. Пример 2.2: как это делать с CTE. Action! У UPDATE и DELETE есть RETURNING *
  62. 62. Пример 2.2: как это делать с CTE. Action! У UPDATE и DELETE есть RETURNING * …которые дают нам получить 2 числа — количество затронутых строк
  63. 63. Пример 2.2: как это делать с CTE. Action! Результат:
  64. 64. Пример 2.2: как это делать с CTE. Action! Результат:
  65. 65. Пример 2.2: O CTE и современном SQL Внимание: если строк удаляем/обновляем много, может понадобиться поэтапная работа с пачками строк! (чтобы не блокировать много и надолго; а также давать возможность отработать VACUUM-у) – нам нужен цикл вызовов извне (что угодно: bash, pyhon, ruby, php, etc)
  66. 66. Пример 2.2: O CTE и современном SQL О современном SQL Максим Богук: ● «Неклассические приемы оптимизации запросов» (2014) ● How to teach an elephant to rock'n'roll (2017) Markus Winand: ● http://use-the-index-luke.com/ ● http://modern-sql.com/ Внимание: если строк удаляем/обновляем много, может понадобиться поэтапная работа с пачками строк! (чтобы не блокировать много и надолго; а также давать возможность отработать VACUUM-у) – нам нужен цикл вызовов извне (что угодно: bash, pyhon, ruby, php, etc)
  67. 67. Пример 2.3: тянем данные на клиент  Часто (Machine Learning, Data Science) – вытягивание огромного количества данных на клиент / app server для анализа (R, Python) Имитация: • 1 млн строк • клиент (psql) в Германии • сервер (Postgres 9.6) — в США SeqScan, получение 1 числа: ~3 сек SeqScan, получение 10000000 чисел: ~22 сек
  68. 68. MADlib: Machine Learning inside your DBMS - A lot of ML algorithms implemented (more in each release): - PL/Python - Very easy and quick start to do machine learning with your Postgres data http://madlib.incubator.apache.org/
  69. 69. MADlib: Machine Learning inside your DBMS Source: Apache MADlib: Distributed In-Database Machine Learning for Fun and Profit Details: MADlib Design Document
  70. 70. Data Manipulation Logic in App (Ruby or Python or PHP or …) Something* * ElasticSearch, Sphix, Analytics DBMS, etc Пример 2.4
  71. 71. Пример 2.4 Data Manipulation Logic in App (Ruby or Python or PHP or …) Something* * ElasticSearch, Sphix, Analytics DBMS, etc
  72. 72. Пример 2.4 Data Manipulation Logic in App (Ruby or Python or PHP or …) Something* * ElasticSearch, Sphix, Analytics DBMS, etc
  73. 73. Пример 2.4 App (Ruby or Python or PHP or …) Something* * ElasticSearch, Sphix, Analytics DBMS, etc Data Manipulation Use: - functions, triggers, - Foreign Data Wrappers (FDW), - Logical Decoding
  74. 74. Database First! Что важно помнить ● Делать вообще всё в СУБД можно, но в некоторых случаях неоправданно ○ пример: работа с внешними API с непредсказуемым временем — оккупация CPU мастера может быть фатальной ошибкой)
  75. 75. Database First! Что важно помнить ● Делать вообще всё в СУБД можно, но в некоторых случаях неоправданно ○ пример: работа с внешними API с непредсказуемым временем — оккупация CPU мастера может быть фатальной ошибкой) ● CTE в PostgreSQL – optimization fence ○ планировщик «не знает», какие есть возможности (индексы) у «соседнего этажа» ○ это может быть как и проблемой, так и помощью в ускорении запросов
  76. 76. Database First! Что важно помнить ● Делать вообще всё в СУБД можно, но в некоторых случаях неоправданно ○ пример: работа с внешними API с непредсказуемым временем — оккупация CPU мастера может быть фатальной ошибкой) ● CTE в PostgreSQL – optimization fence ○ планировщик «не знает», какие есть возможности (индексы) у «соседнего этажа» ○ это может быть как и проблемой, так и помощью в ускорении запросов ● Иногда всё же очень нужна «внешняя сила» ○ пример: дробление UPDATE/DELETE на батчи. Должен кто-то вызывать нас
  77. 77. Database First! Что важно помнить ● Делать вообще всё в СУБД можно, но в некоторых случаях неоправданно ○ пример: работа с внешними API с непредсказуемым временем — оккупация CPU мастера может быть фатальной ошибкой) ● CTE в PostgreSQL – optimization fence ○ планировщик не знает, какие есть возможности (индексы) у «соседнего этажа» ○ это может быть как и проблемой, так и помощью в ускорении запросов ● Иногда всё же очень нужна «внешняя сила» ○ пример: дробление UPDATE/DELETE на батчи. Нужны вызовы извне цикле! ● SQL- и PL/pgSQL-код важно правильно «готовить»: ○ Code Style, подсветка кода (есть плагин vim для PL/pgSQL) ○ версионирование и «миграции» (sqitch, liquibase, etc) ○ тестировать (pgtap) ○ мониторить (pg_stat_statements.track = all) ○ дебажить (простые raise notice; pl/pgsql profiler, debugger)
  78. 78. Database First! Checklist ➜ Типы данных ✓ varchar(N) построже ✓ int8 для PK больших таблиц ✓ int2, где диапазон мал ✓ timestamptz вместо timestamp ✓ tstzrange, int4range, etc + exclusion constraint A Tour of PostgreSQL Data Types (2013), Tour de (PostgreSQL) Data Types (2017) ➜ Манипуляции с данными — прежде всего с помощью средств СУБД!!! ✓ если ничего не мешает, ищем/меняем данные средствами СУБД ✓ можно ли «гонять» меньше данных по сети, поручить работу по подготовке данных СУБД? ✓ много ли строк меняются запросом? нужна ли работа частями? ✓ хранимки — не зло, PL/pgSQL — прекрасен, используем; но можно ли обойтись SQL (или SQL-функцией)? ✓ используем современный SQL: CTE, lateral join, работа с массивами, JSONb, агрегация, оконные функции «Неклассические приемы оптимизации запросов» (2014), How to teach an elephant to rock'n'roll (2017) Cайты: Use-the-Index-Luke.com, Modern-SQL.com Twitter: @postgresmen ➜ Ограничения целостности (constraints): ✓ 5 главных: PK, UK, FK, NOT NULL, CHECK; ✓ а какой у таблицы Natural Key? Создаем UK(s); ✓ интервалы/геометрия? + exclusion constraint; ✓ сложные случаи (проверка данных в нескольких таблицах, денормализация, etc) – используем хранимки, триггеры PostgreSQL Documentation
  79. 79. Thank you! Twitter: @postgresmen (new Postgres tweets daily!) ru@postgresql.org http://RuPostgres.org http://Postgres.chat

×