Class Table Inheritance (Наследование с таблицами классов)

Паттерн проектирования Class Table Inheritance

Паттерн проектирования Class Table Inheritance

Описание Class Table Inheritance

Представляет иерархию наследования классов в виде структуры БД, когда одна таблица отвечает одному классу.

Одно из самых заметных несоответствий между объектной и реляционной моделью - отсутствие в РБД поддержки наследования. Иногда необходима структура БД, точно соответсвующая объектной модели и позволяющая наращивать дерево наследования. Паттерн Class Table Inheritance (Наследование с таблицами классов) предоставляет такие возможности, используя одну таблицу на один класс из структуры наследования.

Примеры реализации

SQL Схема

-- Базовая таблица для всех пользователей
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Таблица для клиентов
CREATE TABLE customers (
    user_id INT PRIMARY KEY,
    phone VARCHAR(20),
    address TEXT,
    loyalty_points INT DEFAULT 0,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

-- Таблица для сотрудников
CREATE TABLE employees (
    user_id INT PRIMARY KEY,
    employee_id VARCHAR(20) UNIQUE NOT NULL,
    department VARCHAR(50),
    salary DECIMAL(10,2),
    hire_date DATE,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

-- Таблица для менеджеров
CREATE TABLE managers (
    user_id INT PRIMARY KEY,
    employee_id VARCHAR(20) UNIQUE NOT NULL,
    department VARCHAR(50),
    salary DECIMAL(10,2),
    hire_date DATE,
    team_size INT DEFAULT 0,
    budget DECIMAL(12,2),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

-- Вставка данных
-- Создание клиента
INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com');
SET @user_id = LAST_INSERT_ID();
INSERT INTO customers (user_id, phone, address, loyalty_points) 
VALUES (@user_id, '+1234567890', '123 Main St', 100);

-- Создание менеджера
INSERT INTO users (name, email) VALUES ('Bob Johnson', 'bob@company.com');
SET @user_id = LAST_INSERT_ID();
INSERT INTO managers (user_id, employee_id, department, salary, hire_date, team_size, budget) 
VALUES (@user_id, 'MGR001', 'IT', 95000.00, '2022-06-01', 5, 500000.00);

-- Запросы
-- Получить всех клиентов с их данными
SELECT u.*, c.phone, c.address, c.loyalty_points 
FROM users u 
JOIN customers c ON u.id = c.user_id;

-- Получить всех сотрудников (включая менеджеров)
SELECT u.*, e.employee_id, e.department, e.salary, e.hire_date 
FROM users u 
JOIN employees e ON u.id = e.user_id
UNION
SELECT u.*, m.employee_id, m.department, m.salary, m.hire_date 
FROM users u 
JOIN managers m ON u.id = m.user_id;

Использована иллюстрация с сайта Мартина Фаулера.

Источник