Initial commit
This commit is contained in:
commit
38b382bdc9
190 files changed
+37216
No files matched your search
@@ -0,0 +1,385 @@
|
||||
-- Схема базы данных для интернет-магазина
|
||||
-- PostgreSQL
|
||||
|
||||
-- Таблица ресурсов
|
||||
CREATE TABLE IF NOT EXISTS resources (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(50) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица действий
|
||||
CREATE TABLE IF NOT EXISTS actions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(50) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица прав доступа
|
||||
CREATE TABLE IF NOT EXISTS permissions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(100) UNIQUE NOT NULL,
|
||||
resource_id INTEGER NOT NULL REFERENCES resources(id) ON DELETE RESTRICT,
|
||||
action_id INTEGER NOT NULL REFERENCES actions(id) ON DELETE RESTRICT,
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(resource_id, action_id)
|
||||
);
|
||||
|
||||
-- Таблица ролей
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(50) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица связи ролей и прав (многие-ко-многим)
|
||||
CREATE TABLE IF NOT EXISTS role_permissions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
role_id INTEGER NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
permission_id INTEGER NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(role_id, permission_id)
|
||||
);
|
||||
|
||||
-- Таблица пользователей
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email VARCHAR(255) UNIQUE,
|
||||
password_hash VARCHAR(255),
|
||||
first_name VARCHAR(100),
|
||||
last_name VARCHAR(100),
|
||||
phone VARCHAR(20),
|
||||
telegram_id BIGINT UNIQUE,
|
||||
role_id INTEGER REFERENCES roles(id) ON DELETE SET NULL,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица аватаров пользователей
|
||||
CREATE TABLE IF NOT EXISTS user_avatars (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
image_url TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(user_id)
|
||||
);
|
||||
|
||||
-- Таблица категорий товаров
|
||||
CREATE TABLE IF NOT EXISTS categories (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
slug VARCHAR(255) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
parent_id INTEGER REFERENCES categories(id) ON DELETE SET NULL,
|
||||
image_url VARCHAR(500),
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица товаров
|
||||
CREATE TABLE IF NOT EXISTS products (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
slug VARCHAR(255) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
short_description TEXT,
|
||||
sku VARCHAR(100) UNIQUE NOT NULL,
|
||||
price DECIMAL(10, 2) NOT NULL CHECK (price >= 0),
|
||||
compare_at_price DECIMAL(10, 2) CHECK (compare_at_price >= 0),
|
||||
cost_price DECIMAL(10, 2) CHECK (cost_price >= 0),
|
||||
discount_percent DECIMAL(5, 2) DEFAULT 0 CHECK (discount_percent >= 0 AND discount_percent <= 100),
|
||||
category_id INTEGER REFERENCES categories(id) ON DELETE SET NULL,
|
||||
stock_quantity INTEGER DEFAULT 0 CHECK (stock_quantity >= 0),
|
||||
weight DECIMAL(8, 2),
|
||||
dimensions VARCHAR(100),
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
is_featured BOOLEAN DEFAULT FALSE,
|
||||
rating DECIMAL(3, 2) DEFAULT 0 CHECK (rating >= 0 AND rating <= 5),
|
||||
review_count INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица изображений товаров
|
||||
CREATE TABLE IF NOT EXISTS product_images (
|
||||
id SERIAL PRIMARY KEY,
|
||||
product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE CASCADE,
|
||||
image_url TEXT NOT NULL,
|
||||
alt_text VARCHAR(255),
|
||||
is_primary BOOLEAN DEFAULT FALSE,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица адресов доставки
|
||||
CREATE TABLE IF NOT EXISTS addresses (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
first_name VARCHAR(100) NOT NULL,
|
||||
last_name VARCHAR(100) NOT NULL,
|
||||
phone VARCHAR(20),
|
||||
country VARCHAR(100) NOT NULL,
|
||||
city VARCHAR(100) NOT NULL,
|
||||
street VARCHAR(255) NOT NULL,
|
||||
building VARCHAR(50),
|
||||
apartment VARCHAR(50),
|
||||
postal_code VARCHAR(20),
|
||||
is_default BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица статусов заказов
|
||||
CREATE TABLE IF NOT EXISTS order_statuses (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(50) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
color VARCHAR(20),
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица способов оплаты
|
||||
CREATE TABLE IF NOT EXISTS payment_methods (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(50) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица статусов платежей
|
||||
CREATE TABLE IF NOT EXISTS payment_statuses (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(50) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
color VARCHAR(20),
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица заказов
|
||||
CREATE TABLE IF NOT EXISTS orders (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
order_number VARCHAR(50) UNIQUE NOT NULL,
|
||||
status_id INTEGER NOT NULL REFERENCES order_statuses(id) ON DELETE RESTRICT,
|
||||
subtotal DECIMAL(10, 2) NOT NULL CHECK (subtotal >= 0),
|
||||
tax_amount DECIMAL(10, 2) DEFAULT 0 CHECK (tax_amount >= 0),
|
||||
shipping_cost DECIMAL(10, 2) DEFAULT 0 CHECK (shipping_cost >= 0),
|
||||
discount_amount DECIMAL(10, 2) DEFAULT 0 CHECK (discount_amount >= 0),
|
||||
total_amount DECIMAL(10, 2) NOT NULL CHECK (total_amount >= 0),
|
||||
shipping_address_id INTEGER REFERENCES addresses(id) ON DELETE SET NULL,
|
||||
billing_address_id INTEGER REFERENCES addresses(id) ON DELETE SET NULL,
|
||||
payment_method_id INTEGER REFERENCES payment_methods(id) ON DELETE SET NULL,
|
||||
payment_status_id INTEGER REFERENCES payment_statuses(id) ON DELETE RESTRICT,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица элементов заказа
|
||||
CREATE TABLE IF NOT EXISTS order_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
order_id INTEGER NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
|
||||
product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE RESTRICT,
|
||||
product_name VARCHAR(255) NOT NULL,
|
||||
product_sku VARCHAR(100) NOT NULL,
|
||||
quantity INTEGER NOT NULL CHECK (quantity > 0),
|
||||
price DECIMAL(10, 2) NOT NULL CHECK (price >= 0),
|
||||
subtotal DECIMAL(10, 2) NOT NULL CHECK (subtotal >= 0),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица корзины
|
||||
CREATE TABLE IF NOT EXISTS cart_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE CASCADE,
|
||||
quantity INTEGER NOT NULL CHECK (quantity > 0),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(user_id, product_id)
|
||||
);
|
||||
|
||||
-- Таблица отзывов
|
||||
CREATE TABLE IF NOT EXISTS reviews (
|
||||
id SERIAL PRIMARY KEY,
|
||||
product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE CASCADE,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
|
||||
title VARCHAR(255),
|
||||
comment TEXT,
|
||||
is_approved BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(product_id, user_id)
|
||||
);
|
||||
|
||||
-- Таблица платежей
|
||||
CREATE TABLE IF NOT EXISTS payments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
order_id INTEGER NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
|
||||
payment_method_id INTEGER NOT NULL REFERENCES payment_methods(id) ON DELETE RESTRICT,
|
||||
transaction_id VARCHAR(255) UNIQUE,
|
||||
amount DECIMAL(10, 2) NOT NULL CHECK (amount >= 0),
|
||||
status_id INTEGER NOT NULL REFERENCES payment_statuses(id) ON DELETE RESTRICT,
|
||||
payment_date TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Функция для автоматического обновления updated_at
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Функция для обновления рейтинга товара при добавлении/изменении отзыва
|
||||
CREATE OR REPLACE FUNCTION update_product_rating()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
UPDATE products
|
||||
SET
|
||||
rating = (
|
||||
SELECT COALESCE(AVG(rating), 0)
|
||||
FROM reviews
|
||||
WHERE product_id = COALESCE(NEW.product_id, OLD.product_id)
|
||||
AND is_approved = TRUE
|
||||
),
|
||||
review_count = (
|
||||
SELECT COUNT(*)
|
||||
FROM reviews
|
||||
WHERE product_id = COALESCE(NEW.product_id, OLD.product_id)
|
||||
AND is_approved = TRUE
|
||||
)
|
||||
WHERE id = COALESCE(NEW.product_id, OLD.product_id);
|
||||
|
||||
RETURN COALESCE(NEW, OLD);
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Функция для генерации номера заказа
|
||||
CREATE OR REPLACE FUNCTION generate_order_number()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
IF NEW.order_number IS NULL OR NEW.order_number = '' THEN
|
||||
NEW.order_number := 'ORD-' || TO_CHAR(NOW(), 'YYYYMMDD') || '-' || LPAD(NEW.id::TEXT, 6, '0');
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Функция для получения ID статуса заказа по slug
|
||||
CREATE OR REPLACE FUNCTION get_order_status_id(status_slug VARCHAR)
|
||||
RETURNS INTEGER AS $$
|
||||
DECLARE
|
||||
status_id INTEGER;
|
||||
BEGIN
|
||||
SELECT id INTO status_id
|
||||
FROM order_statuses
|
||||
WHERE slug = status_slug AND is_active = TRUE
|
||||
LIMIT 1;
|
||||
|
||||
RETURN status_id;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Функция для получения ID статуса платежа по slug
|
||||
CREATE OR REPLACE FUNCTION get_payment_status_id(status_slug VARCHAR)
|
||||
RETURNS INTEGER AS $$
|
||||
DECLARE
|
||||
status_id INTEGER;
|
||||
BEGIN
|
||||
SELECT id INTO status_id
|
||||
FROM payment_statuses
|
||||
WHERE slug = status_slug AND is_active = TRUE
|
||||
LIMIT 1;
|
||||
|
||||
RETURN status_id;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Функция для получения ID способа оплаты по slug
|
||||
CREATE OR REPLACE FUNCTION get_payment_method_id(method_slug VARCHAR)
|
||||
RETURNS INTEGER AS $$
|
||||
DECLARE
|
||||
method_id INTEGER;
|
||||
BEGIN
|
||||
SELECT id INTO method_id
|
||||
FROM payment_methods
|
||||
WHERE slug = method_slug AND is_active = TRUE
|
||||
LIMIT 1;
|
||||
|
||||
RETURN method_id;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Комментарии к таблицам
|
||||
COMMENT ON TABLE resources IS 'Ресурсы системы (products, orders, categories и т.д.)';
|
||||
COMMENT ON TABLE actions IS 'Действия над ресурсами (view, create, edit, delete и т.д.)';
|
||||
COMMENT ON TABLE permissions IS 'Права доступа к ресурсам системы';
|
||||
COMMENT ON TABLE roles IS 'Роли пользователей системы';
|
||||
COMMENT ON TABLE role_permissions IS 'Связь ролей и прав доступа (многие-ко-многим)';
|
||||
COMMENT ON TABLE users IS 'Пользователи системы (покупатели и администраторы)';
|
||||
COMMENT ON TABLE categories IS 'Категории товаров с поддержкой иерархии';
|
||||
COMMENT ON TABLE order_statuses IS 'Статусы заказов';
|
||||
COMMENT ON TABLE payment_methods IS 'Способы оплаты';
|
||||
COMMENT ON TABLE payment_statuses IS 'Статусы платежей';
|
||||
COMMENT ON TABLE products IS 'Товары магазина';
|
||||
COMMENT ON TABLE product_images IS 'Изображения товаров';
|
||||
COMMENT ON TABLE addresses IS 'Адреса доставки пользователей';
|
||||
COMMENT ON TABLE orders IS 'Заказы покупателей';
|
||||
COMMENT ON TABLE order_items IS 'Элементы заказа (товары в заказе)';
|
||||
COMMENT ON TABLE cart_items IS 'Корзина покупок';
|
||||
COMMENT ON TABLE reviews IS 'Отзывы на товары';
|
||||
COMMENT ON TABLE payments IS 'Платежи по заказам';
|
||||
|
||||
-- Таблица настроек системы
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
key VARCHAR(100) UNIQUE NOT NULL,
|
||||
value TEXT,
|
||||
description TEXT,
|
||||
type VARCHAR(50) DEFAULT 'string' CHECK (type IN ('string', 'boolean', 'number', 'json')),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
COMMENT ON TABLE settings IS 'Настройки системы';
|
||||
COMMENT ON COLUMN settings.key IS 'Уникальный ключ настройки';
|
||||
COMMENT ON COLUMN settings.value IS 'Значение настройки (текст)';
|
||||
COMMENT ON COLUMN settings.type IS 'Тип значения: string, boolean, number, json';
|
||||
|
||||
Reference in new issue
Block a user