111 lines
6.7 KiB
SQL
111 lines
6.7 KiB
SQL
-- Схема БД проекта «Бюджет» (MariaDB/InnoDB).
|
||
-- Модель согласована в .claude/memory/бюджет_текущий_план.md — сверяться туда при любых изменениях.
|
||
|
||
SET NAMES utf8mb4;
|
||
|
||
CREATE TABLE users (
|
||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
login VARCHAR(64) NOT NULL,
|
||
password VARCHAR(255) NOT NULL,
|
||
name VARCHAR(128) NOT NULL,
|
||
email VARCHAR(128) NULL,
|
||
date_add DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
last_login DATETIME NULL,
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uq_users_login (login)
|
||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||
|
||
CREATE TABLE accounts (
|
||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
user_id INT UNSIGNED NOT NULL,
|
||
type_acc ENUM ('cash', 'bank', 'savings') NOT NULL,
|
||
title VARCHAR(128) NOT NULL,
|
||
summa DECIMAL(15, 2) NOT NULL DEFAULT 0,
|
||
currency CHAR(3) NOT NULL DEFAULT 'RUB', -- ISO 4217; курс — Services\CurrencyRate (ЦБ РФ), не хранится тут
|
||
description VARCHAR(255) NULL, -- свободное поле, например "счёт жены" — без отдельной структуры
|
||
include_in_total TINYINT(1) NOT NULL DEFAULT 1, -- чисто ручной переключатель пользователя, не системное правило по типу/валюте (дефолт 0 для savings — просто стартовое значение)
|
||
is_delete TINYINT(1) NOT NULL DEFAULT 0,
|
||
`order` INT NOT NULL DEFAULT 0,
|
||
PRIMARY KEY (id),
|
||
KEY ix_accounts_user_id (user_id),
|
||
CONSTRAINT fk_accounts_user FOREIGN KEY (user_id) REFERENCES users (id)
|
||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||
|
||
-- Ставка savings-счёта хранится историей, а не полем в accounts — старые периоды не должны
|
||
-- меняться задним числом при смене ставки; та же структура пригодится для кредитов позже.
|
||
CREATE TABLE account_rates (
|
||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
account_id INT UNSIGNED NOT NULL,
|
||
rate_percent DECIMAL(5, 2) NOT NULL,
|
||
valid_from DATE NOT NULL,
|
||
valid_to DATE NULL,
|
||
PRIMARY KEY (id),
|
||
KEY ix_account_rates_account_id (account_id),
|
||
CONSTRAINT fk_account_rates_account FOREIGN KEY (account_id) REFERENCES accounts (id)
|
||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||
|
||
-- Необязательная надстройка над savings-счётом: без записи здесь — просто копилка без цели.
|
||
CREATE TABLE goals (
|
||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
account_id INT UNSIGNED NOT NULL,
|
||
target_summa DECIMAL(15, 2) NOT NULL,
|
||
deadline DATE NOT NULL,
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uq_goals_account_id (account_id),
|
||
CONSTRAINT fk_goals_account FOREIGN KEY (account_id) REFERENCES accounts (id)
|
||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||
|
||
CREATE TABLE categories (
|
||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
user_id INT UNSIGNED NOT NULL,
|
||
parent_id INT UNSIGNED NULL,
|
||
title VARCHAR(128) NOT NULL,
|
||
type ENUM ('income', 'expense') NOT NULL,
|
||
is_delete TINYINT(1) NOT NULL DEFAULT 0, -- архивация вместо удаления, тот же приём что у accounts — сохраняет историю транзакций
|
||
`order` INT NOT NULL DEFAULT 0,
|
||
PRIMARY KEY (id),
|
||
KEY ix_categories_user_id (user_id),
|
||
KEY ix_categories_parent_id (parent_id),
|
||
CONSTRAINT fk_categories_user FOREIGN KEY (user_id) REFERENCES users (id),
|
||
-- удаление родителя не должно тянуть за собой подкатегории — они просто станут верхнего уровня
|
||
CONSTRAINT fk_categories_parent FOREIGN KEY (parent_id) REFERENCES categories (id) ON DELETE SET NULL
|
||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||
|
||
-- categorie_id NULL — обычный transfer (в т.ч. пополнение копилки/цели): деньги просто
|
||
-- переехали между своими счетами, план/факт по категориям это не видит (см. бюджет_текущий_план.md).
|
||
-- account_f_id/account_in_id: income заполняет только _in, expense — только _f, transfer — оба.
|
||
CREATE TABLE transactions (
|
||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
user_id INT UNSIGNED NOT NULL,
|
||
categorie_id INT UNSIGNED NULL,
|
||
account_f_id INT UNSIGNED NULL,
|
||
account_in_id INT UNSIGNED NULL,
|
||
date DATE NOT NULL,
|
||
summa DECIMAL(15, 2) NOT NULL,
|
||
currency CHAR(3) NULL, -- валюта операции (обычно = валюте счёта списания); NULL = рубли
|
||
rate_to_rub DECIMAL(10, 4) NULL, -- курс ЦБ РФ, зафиксированный на момент операции; NULL для рублёвых
|
||
type ENUM ('income', 'expense', 'transfer') NOT NULL,
|
||
PRIMARY KEY (id),
|
||
KEY ix_transactions_user_date (user_id, date),
|
||
KEY ix_transactions_categorie_id (categorie_id),
|
||
KEY ix_transactions_account_f_id (account_f_id),
|
||
KEY ix_transactions_account_in_id (account_in_id),
|
||
CONSTRAINT fk_transactions_user FOREIGN KEY (user_id) REFERENCES users (id),
|
||
CONSTRAINT fk_transactions_categorie FOREIGN KEY (categorie_id) REFERENCES categories (id),
|
||
CONSTRAINT fk_transactions_account_f FOREIGN KEY (account_f_id) REFERENCES accounts (id),
|
||
CONSTRAINT fk_transactions_account_in FOREIGN KEY (account_in_id) REFERENCES accounts (id)
|
||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||
|
||
-- Факт не хранится — считается на лету суммой transactions по категории за месяц.
|
||
CREATE TABLE budgets (
|
||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
categorie_id INT UNSIGNED NOT NULL,
|
||
plan_summ DECIMAL(15, 2) NOT NULL,
|
||
year SMALLINT UNSIGNED NOT NULL,
|
||
month TINYINT UNSIGNED NOT NULL,
|
||
type ENUM ('income', 'expense') NOT NULL,
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uq_budgets_categorie_period (categorie_id, year, month),
|
||
CONSTRAINT fk_budgets_categorie FOREIGN KEY (categorie_id) REFERENCES categories (id)
|
||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|