Какие типы связей между таблицами существуют в реляционных базах данных?

Ответ

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

  1. Один к одному (One-to-One, 1:1) Одна запись в таблице А соответствует не более чем одной записи в таблице Б, и наоборот.

    • Пример: Пользователи и ПаспортныеДанные. У одного пользователя может быть только один паспорт.
    • Реализация: Внешний ключ (foreign key) в одной из таблиц, который ссылается на первичный ключ другой и имеет ограничение UNIQUE.
    // Пример для GORM ORM
    type User struct {
        gorm.Model
        Name     string
        Passport Passport // У пользователя есть один паспорт
    }
    
    type Passport struct {
        gorm.Model
        Number string
        UserID uint // Внешний ключ
    }
  2. Один ко многим (One-to-Many, 1:N) Одна запись в таблице А может быть связана с несколькими записями в таблице Б, но запись из Б связана только с одной записью из А. Это самый распространенный тип связи.

    • Пример: Авторы и Книги. У одного автора может быть много книг, но у книги — только один автор.
    • Реализация: Внешний ключ добавляется в таблицу на стороне "многих" (Книги), который ссылается на первичный ключ таблицы на стороне "одного" (Авторы).
    type Author struct {
        gorm.Model
        Name  string
        Books []Book // У автора много книг
    }
    
    type Book struct {
        gorm.Model
        Title    string
        AuthorID uint // Внешний ключ
    }
  3. Многие ко многим (Many-to-Many, N:M) Одна запись в таблице А может быть связана с несколькими записями в таблице Б, и наоборот.

    • Пример: Студенты и Курсы. Студент может посещать много курсов, и на одном курсе может учиться много студентов.
    • Реализация: Создается третья, связующая (junction) таблица, которая содержит внешние ключи к обеим таблицам (например, student_id и course_id).
    type Student struct {
        gorm.Model
        Name    string
        Courses []*Course `gorm:"many2many:student_courses;"`
    }
    
    type Course struct {
        gorm.Model
        Name     string
        Students []*Student `gorm:"many2many:student_courses;"`
    }

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

Ответ 18+ 🔞

А, ну это ж классика, блядь! Эти ваши связи в базах данных, ёпта. Сидишь такой, проектируешь, а потом бац — и пиздец, всё разваливается, потому что связал как попало. Слушай сюда, разжую, как есть.

Вот представь, у тебя есть таблицы. Как они друг с другом общаются? Всего три основных сценария, и от выбора зависит, не накроется ли твоя схема медным тазом.

1. Один к одному (1:1) Типа редкая, хитрая жопа. Как будто у человека и его тени. Одна запись в одной таблице — ровно одна запись в другой, и наоборот. Больше не положено, ёпта.

  • Пример из жизни, блядь: Пользователь и его Паспорт. Ну не может же у одного чела быть два паспорта в одной системе (или может, но это уже криминал, нахуй). И паспорт этот привязан только к нему одному.
  • Как делается: Кидаешь внешний ключ в одну из таблиц и ставишь ограничение UNIQUE, чтобы второй раз не прилепили. Всё, пиздец просто.
// GORM, например
type User struct {
    gorm.Model
    Name     string
    Passport Passport // Вот он, один единственный, блядь
}

type Passport struct {
    gorm.Model
    Number string
    UserID uint // Ссылается на юзера, и всё тут
}

2. Один ко многим (1:N) А вот это, сука, хлеб наш насущный! Самый частый гость. Одна запись — а к ней целая орава других.

  • Пример: Автор и его Книги. Ну ясен пень, один Толстой (ну или кто там) мог написать овердохуища книг. А вот обратно — у "Войны и мира" один автор, а не комитет, блядь.
  • Как делается: В таблицу на стороне "многих" (в Книги) добавляешь внешний ключ, который тычет в Автора. И всё, логично же, ёпта!
type Author struct {
    gorm.Model
    Name  string
    Books []Book // Вот она, орава, блядь!
}

type Book struct {
    gorm.Model
    Title    string
    AuthorID uint // А вот и папочка, один для всех
}

3. Многие ко многим (N:M) А вот тут начинается веселье, ёбана! Полный бардак, но структурированный. Одна запись из А может быть связана с кучей из Б, и наоборот. Как студенты и курсы в универе.

  • Пример: Студенты и Курсы. Один студент ходит на кучу пар, а на одну пару приходит толпа таких же, небось, невыспавшихся.
  • Как делается: Тут без третьей, связующей таблицы — нихуя не получится. Она, эта сводница, хранит пары ключей: student_id и course_id. И по этим связям всё и крутится.
type Student struct {
    gorm.Model
    Name    string
    Courses []*Course `gorm:"many2many:student_courses;"` // Магия, блядь!
}

type Course struct {
    gorm.Model
    Name     string
    Students []*Student `gorm:"many2many:student_courses;"` // И тут магия!
}

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