Введение

Как я обнаружил, очень эффективно обобщать знания после прохождения какого-то курса или изучения чего-то нового.
Так вы сможете еще раз вспомнить, что выучили, структурировать свои знания и, конечно же, поделитесь своими знаниями с другими.
Недавно прошел курс по postgresql на Udemy. Кстати, это был один из лучших онлайн-курсов, которые я когда-либо проходил. Вот ссылка, если вам тоже интересно. Курс охватывает postgresqlот самого начала до продвинутого уровня знаний.
Итак, эта статья — мои заметки о postgresql.

Что такое база данных и как она работает внутри?

Ну, база данных — это специальная программа (кстати, postgresql написан на языке программирования C. Код тоже с открытым исходным кодом, его можно посмотреть на GitHub ), который отвечает за хранение данных. База данных состоит из таблиц, а таблицы состоят из строк и столбцов. Вы можете спросить: Почему я не могу хранить данные просто в файле? И ответ: Можно!.
Вы определенно можете хранить свои данные в файле в любом формате, который хотите (например, JSON), но база данных делает это более эффективно, а также имеет множество полезных инструментов для работы с данными.
Хорошо. Как postgresql работает внутри? Есть сервер и клиент. Сервер Postgresql ожидает запросов от клиента postgresql и выполняет эти запросы. Сервер хранит данные в специальном формате в специальных файлах. (Я не буду писать об этом в этой статье, но эта тема хорошо описана в этом курсе Удеми). Не очень важно знать, как postgresql хранит данные внутри. Все, что нам нужно знать — есть сервер, который управляет базами данных и каким-то образом хранит данные. И есть клиент (например, pgadmin) — программа, которая отправляет запросы к серверу postgresql.SQL (язык структурированных запросов) — это язык для выполнения запросов к базе данных( на сервер, который управляет базами данных) от клиента. С помощью клиента вы можете выполнять операции CRUD (создавать, читать, обновлять, удалять) с вашими данными в базе данных.
Postgresql может иметь множество баз данных. Базы данных состоят из таблиц. Базы данных могут иметь много таблиц. Таблицы состоят из столбцов и строк. Столбцы отвечают за сохраняемое имя и тип данных. Строки — это записи (фрагменты данных), которые хранятся в таблице.

Основные операции

В этом разделе я буду писать об основных запросах. Надеюсь, вы уже знакомы с синтаксисом SQL.

CREATE DATABASE имя_базы_данных;
создает базу данных с именем имя_базы_данных

СОЗДАТЬ ТАБЛИЦУ citys(
название VARCHAR(50),
страна VARCHAR(50),
население INTEGER,
район INTEGER
);

создает таблицу городов со столбцами имя(строка[50]), страна(строка[50]), население(целое), площадь(целое)

ВСТАВИТЬ В города (название, страна, население, площадь)
ЗНАЧЕНИЯ
(«Токио», «Япония», 38505000, 8223)
(«Киев», « Украина', 4000000, 10000);

добавить 2 записи в таблицу

ВЫБРАТЬ * ИЗ городов
выбирает все записи из таблицы городов

ВЫБЕРИТЕ имя, область ИЗ городов;
выбирает столбец имени и области из таблицы городов

ВЫБРАТЬ население/район ИЗ городов;
возвращает население/район для каждой записи

Также есть операторы:
+, -, *, /, %, ^(показатель степени), |/(квадратный корень), @(абсолютное значение)

ВЫБЕРИТЕ население/район КАК плотность населения ИЗ городов;
Ключевое слово КАК используется для создания псевдонима

ОБНОВИТЬ города УСТАНОВИТЬ население = 300000, ГДЕ имя = 'Токио';
устанавливает население = 300000 в записях, где имя = Токио в таблице городов.

УДАЛИТЬ ИЗ городов, ГДЕ name=’Tokyo’;
удаляет записи, где name=Tokyo, из таблицы городов.

Операции со строками:
SELECT name || ', ' || страна ИЗ городов;
возврат -› «Киев, Украина»

|| — конкатенация
CONCAT(str, str) — также конкатенация
LOWER( )/UPPER() — изменить нижний/верхний регистр
LENGTH()— длина строки

Фильтрация записей

Вот запрос:
ВЫБЕРИТЕ название, район ИЗ городов, ГДЕ район › 4000;
ИЗ городов
— выполняется первый блок.
ГДЕ область › 4000 — выполняется второй блок.
SELECT имя, область — выполняется третий блок .

Оператор WHERE фильтрует записи по условию.

Операторы сравнения:
=,,,‹= ,›=,IN, ‹› (не равно), !=(не равно), МЕЖДУ,НЕ В
И, ИЛИ

Примеры:
ВЫБРАТЬ название, район ИЗ городов, ГДЕ район МЕЖДУ 2000 И 5000;
выбирает название и район из таблицы городов, где район › 2000 и ‹ 5000
ВЫБЕРИТЕ название, район ИЗ городов, ГДЕ название В ("Гастроном", "Киев") и район = 90;

Работа с таблицами

Существует 4 типа отношений между таблицами:
Отношение "один ко многим". Пример. У пользователя Instagram много фотографий.
Отношение "многие к одному". Пример. Многие фотографии связаны с одним пользователем.
Отношение "один к одному". Пример. У одной лодки один капитан.
Отношение "многие ко многим". Пример: У многих учеников много разных классов.

Первичные ключи и внешние ключи:
Первичный ключ — однозначно идентифицирует запись в таблице. (id)
Внешний ключ — идентифицирует запись (обычно в другой таблице), с которой связана эта строка.

SERIAL означает, что это значение будет автоматически увеличиваться
Пользователи CREATE TABLE (id SERIAL PRIMARY KEY, имя VARCHAR(50));

CREATE TABLE photos(
id SERIAL PRIMARY KEY,
url VARCHAR(100),
user_id INTEGER REFERENCES users(id) # сделать внешний ключ. Пример один-один отношения
);

Параметры удаления:
Что происходит, когда мы удаляем запись, на которую ссылается другой пользователь.
Пример: фотографии имеют поле user_id, которое ссылается на пользователя. Представьте, что мы удаляем пользователя.
1. ПРИ УДАЛЕНИИ ОГРАНИЧЕНИЯ -> выдает ошибку
2. ПРИ УДАЛЕНИИ НЕТ ДЕЙСТВИЙ -› выбросить ошибку
3. НА УДАЛИТЬ КАСКАД-› удалить фото тоже
4. ON DELETE SET NULL -› установить для 'user_id' фотографии значение NULL
5. ON DELETE SET DEFAULT -› Установить 'user_id' фотографии на значение по умолчанию, если оно предоставлено.

СОЗДАТЬ ТАБЛИЧНЫЕ фотографии (
id SERIAL PRIMARY KEY,
url VARCHAR(200),
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE
);

СОЕДИНЕНИЕ и агрегирование
СОЕДИНЕНИЕ — получение значений путем объединения строк из разных связанных таблиц.
Агрегирование – рассматривает многие строк и вычисляет одно значение.

ВЫБЕРИТЕ комментарии.id КАК comment_id, photos.id ИЗ фотографий КАК p
ПРИСОЕДИНЯЙТЕ комментарии к p.id = comments.photos_id;

Объединяет записи две таблицы при условии p.id = comments.photos_id

4 различных типа соединений:
a. Внутреннее соединение (ключевое слово JOIN)
Объединяет таблицы вместе по условию (comments.user_id == users.id)
если comments.user_id или есть пользователь с id=5, но no comment.user_id=5,
эти записи отображаться не будут.

b. Left Join (ключевое слово LEFT JOIN)
таблицы: фотографии, пользователи
если в таблицах фотографий есть записи, которые не представлены в пользователях,
они все равно представлены в соединении.
фотографии (url: «url», user_id: NULL) по-прежнему будут представлены

c. Правое соединение (ключевое слово RIGHT JOIN)
напротив левого соединения.
d. Полное соединение (ключевое слово FULL JOIN)
объединяет все записи в таблице. отсутствующие записи обнуляются.

ВЫБЕРИТЕ user_id , комментарий
ИЗ комментариев
СГРУППИРОВАТЬ ПО user_id
Создайте список всех уникальных значений user_id. Группирует все записи в таблице по группам user_id.

Агрегирующие функции:
1. COUNT()
2. SUM()
3. AVG()
4. MIN()
5 .МАКС()

ВЫБЕРИТЕ МАКС(id) ИЗ комментариев;
выбирает макс. идентификатор таблицы комментариев.

ВЫБЕРИТЕ COUNT(user_id) ИЗ фотографий;
подсчитывает количество записей с user_id. Записи, в которых user_id=NULL, не учитываются.

ВЫБЕРИТЕ СЧЕТЧИК(*) ИЗ фотографий;
подсчитывает количество всех записей (включая NULL)

ВЫБРАТЬ photo_id, COUNT(*)
ИЗ комментариев
ГДЕ photo_id ‹ 3
СГРУППИРОВАТЬ ПО photo_id
ИМЕЕТ COUNT(*) › 2;
WHERE
— фильтрует набор строк.
HAVING — фильтрует набор групп.

Сортировка
ВЫБРАТЬ * ОТ пользователей ORDER BY id ASC;
выбрать все записи пользователей, отсортированные по идентификатору в порядке возрастания.
SELECT * FROM users ORDER BY id DESC;
выбрать все записи пользователей, отсортированные по идентификатору в порядке убывания.
SELECT * FROM users OFFSET 40;
начать с 40-й записи.

SELECT * FROM users LIMIT 5;
выберите первые 5 записей.

Объединения и пересечения
(ВЫБЕРИТЕ * ИЗ ПРОДУКТОВ СОРТИРОВАТЬ ПО ЦЕНЕ DESC LIMIT 4) ОБЪЕДИНЕНИЕ (ВЫБЕРИТЕ * ИЗ ПРОДУКТОВ ORDER BY price/weight DESC LIMIT 4)
удалит дубликаты из 2 выбранных запросов.

(выражение) UNION ALL (выражение)
дубликаты не удаляются.

ОБЪЕДИНЕНИЕ— объединяет результаты двух запросов и удаляет дубликаты
ОБЪЕДИНЯЕТ ВСЕ— объединяет результаты двух запросов и не удаляет дубликаты
INTERSECT — найти общие строки в результатах двух запросов. Удалить дубликаты
Пересекать все — найти общие строки в результатах двух запросов. Без удаления дубликатов
ИСКЛЮЧАЯ — найти строки, которые присутствуют в первом запросе, но отсутствуют во втором запросе. Удалить дубликаты
ИСКЛЮЧАЯ – найти строки, которые присутствуют в первом запросе, но отсутствуют во втором запросе. Не удаляет дубликаты

Сборка запросов с подзапросами
ВЫБЕРИТЕ имя, цену
ИЗ товаров
ГДЕ цена › (ВЫБЕРИТЕ МАКС(цену) ИЗ товаров ГДЕ отдел='Игрушки');

Выбрать отдельные записи
ОТЛИЧНЫЕ — выбрать все уникальные значения внутри столбцов.
ВЫБРАТЬ ОТДЕЛЬНЫЕ отделы ОТ продуктов;
ВЫБЕРИТЕ ОТДЕЛЬНОЕ отделение, название ИЗ продуктов;
выберите все уникальные комбинации

Вспомогательные операторы, ключевые слова и функции
SELECT GREATEST(200, 10, 30)
возвращает 200

ВЫБРАТЬ НАИМЕНЕЕ(1,2,45,6,8,2554)
выбирает 1

ВЫБЕРИТЕ название, цену,
СЛУЧАЙ
КОГДА цена › 600, ТОГДА «высокая»
КОГДА цена › 300, ТОГДА «средняя»
ИНАЧЕ «дешевая»
КОНЕЦ
ИЗ продуктов;

Проверка данных и ограничения
а. Значение не NULL
a.1 при создании таблицы
CREATE table products (
id SERIAL PRIMARY KEY,
price INTEGER NOT NULL
);

a.2 После создания таблицы
ALTER TABLE products
ALTER COLUMN price
SET NOT NULL;

обновление значений в базе данных
ОБНОВИТЬ товары
УСТАНОВИТЬ цену = 1000
ГДЕ цена IS NULL;

б. значения столбца по умолчанию
СОЗДАТЬ таблицу продуктов (
id SERIAL PRIMARY KEY,
цена DEFAULT 1000
);

в. уникальные значения
CREATE table products (
id SERIAL PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE
);

если мы хотим изменить существующую таблицу.
ALTER TABLE products ADD UNIQUE (name);

д. удалить ограничения
ALTER TABLE products DROP CONSTRAINT products_name_key(name_of_constraint);

напр. Валидация
CREATE TABLE products (
id SERIAL PRIMARY KEY,
price INTEGER CHECK (цена › 0)
);

Продукты ALTER TABLE ДОБАВИТЬ ПРОВЕРКУ (цена › 0);

Внутренние ресурсы Postgres
ПОКАЗАТЬ каталог_данных;
показать, где postgres хранит данные

ВЫБЕРИТЕ oid, имя_даты FROM pg_database;
распечатать идентификатор всех баз данных в postgres

SELECT * FROM pg_class;
распечатать идентификатор таблиц.

Примечания

Тип данных INTEGER ограничен 4 байтами. Таким образом макс. целочисленное значение = 2147483647