CREATE SCHEMA IF NOT EXISTS shop; ------------------------------------------------------------ -- 1. Таблицы-справочники и основные сущности ------------------------------------------------------------ -- 1.1. Клиенты CREATE TABLE shop.client ( id BIGSERIAL PRIMARY KEY, name TEXT NOT NULL, address TEXT ); COMMENT ON TABLE shop.client IS 'Таблица клиентов магазина'; COMMENT ON COLUMN shop.client.id IS 'Уникальный идентификатор клиента'; COMMENT ON COLUMN shop.client.name IS 'Имя или наименование клиента'; COMMENT ON COLUMN shop.client.address IS 'Адрес клиента'; ------------------------------------------------------------ -- 1.2. Категории (основная таблица) ------------------------------------------------------------ CREATE TABLE shop.category ( id BIGSERIAL PRIMARY KEY, parent_id BIGINT REFERENCES shop.category(id) ON DELETE SET NULL, name TEXT NOT NULL ); CREATE INDEX idx_category_parent_id ON shop.category(parent_id); COMMENT ON TABLE shop.category IS 'Таблица категорий товаров (иерархическая структура)'; COMMENT ON COLUMN shop.category.id IS 'Уникальный идентификатор категории'; COMMENT ON COLUMN shop.category.parent_id IS 'Ссылка на родительскую категорию (NULL для корневых категорий)'; COMMENT ON COLUMN shop.category.name IS 'Наименование категории'; ------------------------------------------------------------ -- 1.3. Closure Table для категорий ------------------------------------------------------------ CREATE TABLE shop.category_closure ( ancestor_id BIGINT NOT NULL REFERENCES shop.category(id) ON DELETE CASCADE, descendant_id BIGINT NOT NULL REFERENCES shop.category(id) ON DELETE CASCADE, depth INT NOT NULL, PRIMARY KEY (ancestor_id, descendant_id) ); -- Быстрый поиск всех потомков (по предку) CREATE INDEX idx_category_closure_ancestor_depth ON shop.category_closure (ancestor_id, depth); -- Быстрый поиск всех предков (по потомку) CREATE INDEX idx_category_closure_descendant_depth ON shop.category_closure (descendant_id, depth); COMMENT ON TABLE shop.category_closure IS 'Closure Table для эффективной работы с иерархией категорий'; COMMENT ON COLUMN shop.category_closure.ancestor_id IS 'ID категории-предка в иерархии'; COMMENT ON COLUMN shop.category_closure.descendant_id IS 'ID категории-потомка в иерархии'; COMMENT ON COLUMN shop.category_closure.depth IS 'Глубина связи: 0 - сам себе предок, 1 - прямой потомок, 2+ - непрямой потомок'; ------------------------------------------------------------ -- 1.4. Номенклатура (товары) ------------------------------------------------------------ CREATE TABLE shop.product ( id BIGSERIAL PRIMARY KEY, category_id BIGINT NOT NULL REFERENCES shop.category(id) ON DELETE RESTRICT, name TEXT NOT NULL, quantity NUMERIC(18,3) NOT NULL DEFAULT 0, price NUMERIC(18,2) NOT NULL ); CREATE INDEX idx_product_category_id ON shop.product(category_id); COMMENT ON TABLE shop.product IS 'Таблица товаров (номенклатура)'; COMMENT ON COLUMN shop.product.id IS 'Уникальный идентификатор товара'; COMMENT ON COLUMN shop.product.category_id IS 'Ссылка на категорию товара'; COMMENT ON COLUMN shop.product.name IS 'Наименование товара'; COMMENT ON COLUMN shop.product.quantity IS 'Количество товара на складе'; COMMENT ON COLUMN shop.product.price IS 'Цена товара'; ------------------------------------------------------------ -- 1.5. Заказы ------------------------------------------------------------ CREATE TABLE shop.customer_order ( id BIGSERIAL PRIMARY KEY, client_id BIGINT NOT NULL REFERENCES shop.client(id) ON DELETE RESTRICT, order_date TIMESTAMP NOT NULL DEFAULT NOW(), status TEXT NOT NULL DEFAULT 'NEW' ); CREATE INDEX idx_customer_order_client_id ON shop.customer_order(client_id); CREATE INDEX idx_customer_order_order_date ON shop.customer_order(order_date); COMMENT ON TABLE shop.customer_order IS 'Таблица заказов клиентов'; COMMENT ON COLUMN shop.customer_order.id IS 'Уникальный идентификатор заказа'; COMMENT ON COLUMN shop.customer_order.client_id IS 'Ссылка на клиента, сделавшего заказ'; COMMENT ON COLUMN shop.customer_order.order_date IS 'Дата и время создания заказа (по умолчанию - текущее время)'; COMMENT ON COLUMN shop.customer_order.status IS 'Статус заказа: NEW - новый, и другие возможные статусы'; ------------------------------------------------------------ -- 1.6. Позиции заказа ------------------------------------------------------------ CREATE TABLE shop.customer_order_item ( id BIGSERIAL PRIMARY KEY, order_id BIGINT NOT NULL REFERENCES shop.customer_order(id) ON DELETE CASCADE, product_id BIGINT NOT NULL REFERENCES shop.product(id) ON DELETE RESTRICT, quantity NUMERIC(18,3) NOT NULL, price_at_time NUMERIC(18,2) NOT NULL, -- один товар одна позиция в заказе UNIQUE (order_id, product_id) ); CREATE INDEX idx_order_item_order_id ON shop.customer_order_item(order_id); CREATE INDEX idx_order_item_product_id ON shop.customer_order_item(product_id); COMMENT ON TABLE shop.customer_order_item IS 'Таблица позиций (состав) заказов'; COMMENT ON COLUMN shop.customer_order_item.id IS 'Уникальный идентификатор позиции в заказе'; COMMENT ON COLUMN shop.customer_order_item.order_id IS 'Ссылка на заказ, к которому относится позиция'; COMMENT ON COLUMN shop.customer_order_item.product_id IS 'Ссылка на товар в позиции заказа'; COMMENT ON COLUMN shop.customer_order_item.quantity IS 'Количество товара в позиции'; COMMENT ON COLUMN shop.customer_order_item.price_at_time IS 'Цена товара на момент создания заказа (фиксируется при оформлении)';