> For the complete documentation index, see [llms.txt](https://yuliyas-organization-3.gitbook.io/prokhodim-sobesedovanie-na-golang-razrabotchika/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yuliyas-organization-3.gitbook.io/prokhodim-sobesedovanie-na-golang-razrabotchika/bazy-dannykh.md).

# Базы данных

### Общие вопросы:

<details>

<summary>Классификация баз  данных</summary>

Классификация баз данных включает несколько аспектов, в зависимости от типа хранимой информации, модели данных и других факторов. Из предоставленных источников можно выделить следующие основные классификации баз данных:

1. **По типу хранимой информации**:
   * **Фактографические базы данных**: Хранят информацию об объектах предметной области в виде "фактов".
   * **Документальные базы данных**: Содержат информацию с неопределенной или переменной структурой данных, такие как документы.
   * **Лексикографические базы данных**: Включают классификаторы, словари и другие справочные материалы\[2]\[3].
2. **По модели данных**:
   * **Иерархические и сетевые модели данных**: Традиционные модели данных, которые используются для организации информации в иерархической или сетевой структуре.
   * **Реляционная модель данных**: Основана на отношениях между данными и является одной из наиболее распространенных моделей данных\[3]\[4].
3. **По форме представляемой информации**:
   * **Фактографические, документальные и мультимедийные базы данных**: Отличаются по форме представления информации и специфике хранимых данных\[3].

Таким образом, классификация баз данных включает различные аспекты, такие как тип хранимой информации, модель данных и форма представления информации, что позволяет эффективно организовывать и управлять данными в информационных системах.

Citations: \[1] <https://webonto.ru/klassifikatsiya-baz-dannyih/> \[2] <http://cs.petrsu.ru/studies/filatova\\_information/CMD\\_1996566\\_M/my\\_files/Inform/DataBase/a-2.htm> \[3] <https://inftis.narod.ru/db/db-2.htm> \[4] <https://otus.ru/nest/post/587/> \[5] <https://selectel.ru/blog/databases-types/>

</details>

<details>

<summary>Почему реляционные базы называются реляционными</summary>

Реляционные базы данных называются "реляционными" из-за того, что данные в них организованы в виде взаимосвязанных таблиц, где каждая таблица содержит информацию об определенном объекте или сущности\[1]\[2]\[4]\[5].

Ключевые особенности реляционных баз данных:

\- Данные хранятся в таблицах, состоящих из строк (записей) и столбцов (полей)\[1]\[2]\[3]\[5]

\- Между таблицами устанавливаются связи (отношения) на основе общих данных, называемых внешними ключами\[4]\[5]

\- Связи между таблицами позволяют выполнять сложные запросы, объединяя данные из нескольких таблиц\[5]

\- Использование реляционной модели было предложено Эдгаром Коддом из IBM в 1970 году\[4]

Таким образом, термин "реляционный" указывает на наличие предустановленных отношений между хранящимися данными в виде таблиц\[1]. Эта структура обеспечивает гибкость, целостность и эффективность при работе с информацией в базах данных\[2]\[3].

Citations:

\[1] <https://gb.ru/blog/relyatsionnaya-baza-dannykh/>

\[2] <https://help.reg.ru/support/servery-vps/oblachnyye-bazy-dannykh/zakaz-i-upravleniye-uslugoy-oblachnyye-bazy-dannykh/relyatsionnyye-bazy-dannykh>

\[3] <https://www.oracle.com/cis/database/what-is-a-relational-database/>

\[4] <https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F\\_%D0%B1%D0%B0%D0%B7%D0%B0\\_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85>

\[5] <https://itglobal.com/ru-ru/company/glossary/relyaczionnaya-baza-dannyh/>

</details>

<details>

<summary>Нормализация в БД, зачем нужна</summary>

Нормализация баз данных необходима для устранения избыточности данных, повышения производительности и удобства управления данными\[1]\[2]\[4].

Основные преимущества нормализации:

1\. \*\*Уменьшение объема базы данных\*\* за счет отдельных таблиц для категорий и повторяющихся элементов\[1]\[4]

2\. \*\*Упрощение поиска и повышение удобства работы с базой\*\*, например, для поиска по заданной категории можно обратиться к отдельной таблице категорий\[1]\[2]

3\. \*\*Снижение вероятности ошибок и аномалий\*\*, так как связанные данные в нормальных формах взаимосвязаны, и изменение или удаление данных в одной таблице автоматически отразится на остальных\[1]\[2]\[4]

4\. \*\*Повышение производительности\*\* за счет оптимизации нормализованной базы данных, состоящей из связанных таблиц, для решения конкретных задач\[2]\[4]

Таким образом, нормализация данных в реляционных базах данных позволяет структурировать информацию, сократить избыточность и повысить эффективность работы с данными\[1]\[2]\[4]\[5].

Citations:

\[1] <https://practicum.yandex.ru/blog/chto-takoe-normalizaciya-dannyh/>

\[2] <https://info-comp.ru/database-normalization>

\[3] <https://help.reg.ru/support/servery-vps/oblachnyye-bazy-dannykh/zakaz-i-upravleniye-uslugoy-oblachnyye-bazy-dannykh/relyatsionnyye-bazy-dannykh>

\[4] <https://appmaster.io/ru/blog/chto-takoe-normalizatsiia-dannykh>

\[5] <https://club.shelek.ru/viewart.php?id=177>

</details>

<details>

<summary>Зачем нужна денормализация БД?</summary>

Денормализация базы данных — это процесс преднамеренного введения избыточности в структуру базы данных для улучшения производительности и упрощения запросов. В отличие от нормализации, которая стремится минимизировать избыточность и устранить аномалии при обновлении данных, денормализация может быть полезной в определенных сценариях. Давайте рассмотрим, зачем может понадобиться денормализация базы данных и какие преимущества она может предоставить.

#### Зачем нужна денормализация?

1. **Улучшение производительности чтения**:
   * Денормализация может значительно улучшить производительность операций чтения, особенно в системах, где чтение данных происходит гораздо чаще, чем запись. Это достигается за счет уменьшения количества соединений (JOIN) между таблицами, что снижает нагрузку на базу данных и ускоряет выполнение запросов.
2. **Упрощение запросов**:
   * Денормализация может упростить структуру запросов, делая их более прямолинейными и менее сложными. Это особенно полезно в аналитических системах, где часто требуются сложные запросы для агрегации и анализа данных.
3. **Снижение нагрузки на сервер базы данных**:
   * Уменьшение количества соединений между таблицами может снизить нагрузку на сервер базы данных, так как операции соединения могут быть ресурсоемкими. Это может привести к более эффективному использованию ресурсов сервера.
4. **Повышение доступности данных**:
   * В распределенных системах денормализация может повысить доступность данных, так как данные могут быть реплицированы и храниться в нескольких местах. Это позволяет быстрее получать доступ к данным и снижает зависимость от одного узла.
5. **Оптимизация для конкретных сценариев использования**:
   * Денормализация позволяет оптимизировать структуру базы данных для конкретных сценариев использования и типов запросов. Например, в системах управления контентом (CMS) или системах рекомендаций денормализация может значительно улучшить производительность.

#### Примеры денормализации

**Пример 1: Денормализация для улучшения производительности чтения**

Предположим, у нас есть две таблицы: `orders` и `customers`. В нормализованной базе данных для получения информации о заказе и клиенте нам нужно выполнить соединение:

```sql
SELECT orders.order_id, orders.order_date, customers.customer_name
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id;
```

В денормализованной базе данных мы можем добавить имя клиента непосредственно в таблицу `orders`, чтобы избежать соединения:

```sql
SELECT order_id, order_date, customer_name
FROM orders;
```

**Пример 2: Денормализация для аналитических запросов**

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

```sql
CREATE TABLE sales_summary AS
SELECT product_id, SUM(sales_amount) AS total_sales, COUNT(*) AS total_orders
FROM sales
GROUP BY product_id;
```

#### Недостатки денормализации

Хотя денормализация может предоставить значительные преимущества, она также имеет свои недостатки:

1. **Избыточность данных**:
   * Денормализация вводит избыточность данных, что может привести к увеличению объема хранимых данных и усложнению управления ими.
2. **Аномалии при обновлении**:
   * Избыточные данные могут привести к аномалиям при обновлении, так как изменения в одном месте могут потребовать обновления данных в нескольких местах.
3. **Сложность поддержки**:
   * Денормализованные структуры данных могут быть сложнее в поддержке и сопровождении, так как требуется больше усилий для обеспечения целостности данных.

#### Заключение

Денормализация базы данных может быть полезной для улучшения производительности чтения, упрощения запросов и оптимизации для конкретных сценариев использования. Однако она также вводит избыточность данных и может привести к аномалиям при обновлении и усложнению поддержки. Важно тщательно оценить потребности вашего проекта и взвесить преимущества и недостатки денормализации перед ее применением.

</details>

<details>

<summary>На какие критерии нужно обратить внимание при выборе NoSQL или SQL БД?</summary>

Выбор между NoSQL и SQL базами данных зависит от множества факторов, связанных с требованиями вашего приложения, архитектурой системы и бизнес-целями. Вот основные критерии, на которые следует обратить внимание при принятии решения:

#### 1. Структура данных

* **SQL (реляционные базы данных)**:
  * **Структура**: Таблицы с четко определенными схемами (строки и столбцы).
  * **Типы данных**: Хорошо подходят для структурированных данных с фиксированными отношениями.
  * **Примеры**: MySQL, PostgreSQL, Oracle, Microsoft SQL Server.
* **NoSQL (нереляционные базы данных)**:
  * **Структура**: Гибкие схемы, могут быть документами, графами, ключ-значение или столбцами.
  * **Типы данных**: Хорошо подходят для неструктурированных или полуструктурированных данных.
  * **Примеры**: MongoDB (документная), Cassandra (столбцовая), Redis (ключ-значение), Neo4j (графовая).

#### 2. Масштабируемость

* **SQL**:
  * **Вертикальная масштабируемость**: Увеличение мощности одного сервера (добавление CPU, RAM).
  * **Горизонтальная масштабируемость**: Сложнее, требует шардирования и репликации.
* **NoSQL**:
  * **Горизонтальная масштабируемость**: Легче масштабировать путем добавления новых узлов в кластер.
  * **Вертикальная масштабируемость**: Также возможна, но менее распространена.

#### 3. Согласованность данных

* **SQL**:
  * **ACID-транзакции**: Гарантируют атомарность, согласованность, изолированность и долговечность.
  * **Согласованность**: Высокая, данные всегда согласованы.
* **NoSQL**:
  * **BASE-подход**: Основывается на принципах "Basically Available, Soft state, Eventual consistency".
  * **Согласованность**: Может быть ослабленной (eventual consistency) для повышения доступности и масштабируемости.

#### 4. Типы запросов и операции

* **SQL**:
  * **Запросы**: Сложные запросы с использованием SQL (JOIN, агрегатные функции).
  * **Операции**: Поддержка сложных транзакций и аналитических запросов.
* **NoSQL**:
  * **Запросы**: Простые и быстрые запросы, часто ограниченные по функциональности.
  * **Операции**: Оптимизированы для быстрых операций чтения и записи.

#### 5. Производительность

* **SQL**:
  * **Производительность**: Высокая для сложных запросов и транзакций, но может снижаться при больших объемах данных и высокой нагрузке.
* **NoSQL**:
  * **Производительность**: Высокая для операций чтения и записи, особенно при горизонтальном масштабировании.

#### 6. Гибкость схемы

* **SQL**:
  * **Схема**: Статическая, требует четкого определения структуры данных перед использованием.
  * **Изменение схемы**: Может быть сложным и требовать миграции данных.
* **NoSQL**:
  * **Схема**: Гибкая, позволяет легко изменять структуру данных.
  * **Изменение схемы**: Проще и быстрее, подходит для динамически изменяющихся данных.

#### 7. Сообщество и поддержка

* **SQL**:
  * **Сообщество**: Широкое сообщество, множество инструментов и документации.
  * **Поддержка**: Хорошо поддерживается большинством облачных провайдеров и коммерческих решений.
* **NoSQL**:
  * **Сообщество**: Быстро растущее сообщество, но может быть менее зрелым по сравнению с SQL.
  * **Поддержка**: Поддержка зависит от конкретной базы данных, но многие NoSQL решения также хорошо поддерживаются.

#### 8. Стоимость

* **SQL**:
  * **Стоимость**: Может быть выше из-за лицензий и требований к аппаратному обеспечению.
  * **Облачные решения**: Множество доступных облачных решений с различными ценовыми моделями.
* **NoSQL**:
  * **Стоимость**: Может быть ниже, особенно при использовании открытого ПО и горизонтального масштабирования.
  * **Облачные решения**: Также множество доступных облачных решений с различными ценовыми моделями.

#### Заключение

Выбор между SQL и NoSQL базами данных зависит от конкретных требований вашего проекта. Если вам нужна строгая согласованность данных, сложные запросы и транзакции, то SQL базы данных могут быть лучшим выбором. Если вам нужна гибкость схемы, высокая производительность и масштабируемость, то NoSQL базы данных могут быть более подходящими.

</details>

<details>

<summary>Какие преимущества документоориентированных БД vs Реляционными?</summary>

Документоориентированные базы данных (NoSQL) и реляционные базы данных (SQL) имеют свои уникальные преимущества и недостатки. Выбор между ними зависит от конкретных требований вашего проекта. Давайте рассмотрим основные преимущества документоориентированных баз данных по сравнению с реляционными базами данных.

#### Преимущества документоориентированных баз данных

1. **Гибкость схемы (Schema Flexibility)**:
   * Документоориентированные базы данных, такие как MongoDB, не требуют заранее определенной схемы. Это позволяет легко изменять структуру данных без необходимости миграции схемы, что особенно полезно в условиях быстро меняющихся требований.
2. **Горизонтальное масштабирование (Horizontal Scalability)**:
   * Документоориентированные базы данных обычно лучше поддерживают горизонтальное масштабирование, что позволяет распределять данные и нагрузку на несколько серверов. Это делает их более подходящими для работы с большими объемами данных и высокими нагрузками.
3. **Производительность (Performance)**:
   * В некоторых случаях документоориентированные базы данных могут обеспечивать более высокую производительность для определенных типов операций, таких как чтение и запись больших объемов данных, благодаря отсутствию сложных операций соединения (JOIN).
4. **Удобство работы с вложенными структурами (Nested Structures)**:
   * Документоориентированные базы данных позволяют хранить сложные вложенные структуры данных (например, JSON-документы) в одном документе. Это упрощает работу с данными, которые имеют иерархическую или вложенную природу.
5. **Простота разработки (Developer-Friendly)**:
   * Документоориентированные базы данных часто предоставляют более простой и интуитивно понятный интерфейс для работы с данными, что может ускорить процесс разработки.

#### Преимущества реляционных баз данных

1. **Согласованность данных (Data Consistency)**:
   * Реляционные базы данных обеспечивают строгую согласованность данных благодаря поддержке транзакций ACID (Atomicity, Consistency, Isolation, Durability). Это делает их более подходящими для приложений, где критически важна целостность данных.
2. **Сложные запросы (Complex Queries)**:
   * Реляционные базы данных поддерживают мощный язык запросов SQL, который позволяет выполнять сложные запросы, включая операции соединения (JOIN), агрегации и подзапросы.
3. **Нормализация данных (Data Normalization)**:
   * Реляционные базы данных поддерживают нормализацию данных, что помогает избежать избыточности и аномалий при обновлении данных.
4. **Широкая поддержка и зрелость (Maturity and Support)**:
   * Реляционные базы данных существуют уже несколько десятилетий и имеют широкую поддержку со стороны сообщества и коммерческих поставщиков. Это обеспечивает наличие обширной документации, инструментов и опыта.

#### Заключение

Выбор между документоориентированными и реляционными базами данных зависит от конкретных требований вашего проекта. Документоориентированные базы данных предлагают гибкость схемы, горизонтальное масштабирование и удобство работы с вложенными структурами, что делает их подходящими для приложений с быстро меняющимися требованиями и большими объемами данных. Реляционные базы данных, с другой стороны, обеспечивают строгую согласованность данных, поддержку сложных запросов и зрелость, что делает их подходящими для приложений, где критически важна целостность данных и сложные операции с данными.

</details>

<details>

<summary>С какой БД работаете, какую библиотеку для GoLang или ORM используете?</summary>

В своей практике я работал с различными базами данных и использовал несколько библиотек и ORM для GoLang. Вот некоторые из них:

#### Базы данных

1. **PostgreSQL**: Одна из самых популярных реляционных баз данных, известная своей надежностью и мощными возможностями.
2. **MySQL**: Еще одна популярная реляционная база данных, широко используемая в веб-приложениях.
3. **SQLite**: Легковесная встраиваемая база данных, часто используемая для небольших проектов или тестирования.
4. **MongoDB**: Документо-ориентированная NoSQL база данных, известная своей гибкостью и масштабируемостью.
5. **Redis**: In-memory key-value store, часто используемый для кэширования и управления сессиями.

#### Библиотеки и ORM для GoLang

**1. GORM**

**Описание**: GORM — это ORM для Go, который предоставляет удобный интерфейс для работы с реляционными базами данных. **Плюсы**:

* Поддержка различных баз данных (PostgreSQL, MySQL, SQLite и др.).
* Автоматическое создание и миграция схем.
* Удобный интерфейс для выполнения CRUD операций. **Пример**:

```go
package main

import (
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
    "fmt"
)

type User struct {
    ID    uint
    Name  string
    Email string
}

func main() {
    dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"
    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    // Миграция схемы
    db.AutoMigrate(&User{})

    // Создание
    db.Create(&User{Name: "John", Email: "john@example.com"})

    // Чтение
    var user User
    db.First(&user, 1) // Найти пользователя с ID 1
    fmt.Println(user)

    // Обновление
    db.Model(&user).Update("Email", "john.doe@example.com")

    // Удаление
    db.Delete(&user)
}
```

**2. sqlx**

**Описание**: sqlx — это расширение стандартной библиотеки database/sql, которое добавляет дополнительные функции и удобства. **Плюсы**:

* Расширяет стандартную библиотеку database/sql.
* Поддержка структур и автоматическое сканирование результатов.
* Удобный интерфейс для выполнения SQL-запросов. **Пример**:

```go
package main

import (
    "github.com/jmoiron/sqlx"
    _ "github.com/lib/pq"
    "fmt"
)

type User struct {
    ID    int    `db:"id"`
    Name  string `db:"name"`
    Email string `db:"email"`
}

func main() {
    dsn := "user=postgres password=postgres dbname=test sslmode=disable"
    db, err := sqlx.Connect("postgres", dsn)
    if err != nil {
        panic(err)
    }

    // Создание таблицы
    db.MustExec("CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name TEXT, email TEXT)")

    // Вставка данных
    db.MustExec("INSERT INTO users (name, email) VALUES ($1, $2)", "John", "john@example.com")

    // Чтение данных
    var users []User
    db.Select(&users, "SELECT * FROM users")
    fmt.Println(users)
}
```

**3. pgx**

**Описание**: pgx — это PostgreSQL драйвер и набор инструментов для Go, который предоставляет высокую производительность и дополнительные возможности. **Плюсы**:

* Высокая производительность.
* Поддержка расширенных возможностей PostgreSQL.
* Удобный интерфейс для выполнения SQL-запросов. **Пример**:

```go
package main

import (
    "github.com/jackc/pgx/v4"
    "context"
    "fmt"
    "os"
)

func main() {
    conn, err := pgx.Connect(context.Background(), "postgres://username:password@localhost:5432/database")
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
        os.Exit(1)
    }
    defer conn.Close(context.Background())

    // Вставка данных
    _, err = conn.Exec(context.Background(), "INSERT INTO users (name, email) VALUES ($1, $2)", "John", "john@example.com")
    if err != nil {
        fmt.Fprintf(os.Stderr, "Insert failed: %v\n", err)
        os.Exit(1)
    }

    // Чтение данных
    var name, email string
    err = conn.QueryRow(context.Background(), "SELECT name, email FROM users WHERE name=$1", "John").Scan(&name, &email)
    if err != nil {
        fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
        os.Exit(1)
    }
    fmt.Println(name, email)
}
```

#### Личное мнение

Каждая из этих библиотек и ORM имеет свои преимущества и недостатки. Выбор конкретного инструмента зависит от требований проекта, предпочтений команды и специфики используемой базы данных. GORM удобен для быстрого старта и работы с реляционными базами данных, sqlx предоставляет больше контроля и гибкости, а pgx идеально подходит для высокопроизводительных приложений с PostgreSQL.

</details>
