You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL数据库架构设计:如何规避many-to-many关系关联产品与库存组件

MySQL集合-库存组件架构设计方案(避免直接多对多关系)

核心表结构设计

1. 原始库存表(raw_inventory)

存储所有原始库存组件的基础信息,作为组件的唯一数据源:

CREATE TABLE raw_inventory (
    inv_id VARCHAR(50) PRIMARY KEY, -- 示例值:inv_1、inv_2
    inv_name VARCHAR(100) NOT NULL,
    current_stock INT DEFAULT 0,
    unit_cost DECIMAL(10,2) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

2. 集合产品表(collections)

存储集合产品的基础信息,每个集合是独立的销售单元:

CREATE TABLE collections (
    coll_id VARCHAR(50) PRIMARY KEY, -- 示例值:coll_a、coll_b
    coll_name VARCHAR(100) NOT NULL,
    sale_price DECIMAL(10,2) NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

3. 集合-组件关联表(collection_component_map)

通过拆分为两个一对多关系替代直接多对多:每个集合对应多条关联记录(每个组件一条),每个组件也可对应多条关联记录(属于多个集合),同时支持扩展组件数量等信息:

CREATE TABLE collection_component_map (
    map_id INT AUTO_INCREMENT PRIMARY KEY, -- 自增主键,唯一标识每条关联
    coll_id VARCHAR(50) NOT NULL,
    inv_id VARCHAR(50) NOT NULL,
    component_quantity INT DEFAULT 1, -- 每个集合包含该组件的数量
    FOREIGN KEY (coll_id) REFERENCES collections(coll_id) ON DELETE CASCADE,
    FOREIGN KEY (inv_id) REFERENCES raw_inventory(inv_id) ON DELETE CASCADE,
    UNIQUE KEY unique_coll_inv (coll_id, inv_id) -- 避免同一集合重复关联同一组件
);

数据插入示例

按照你的需求插入初始数据:

-- 插入原始库存组件
INSERT INTO raw_inventory (inv_id, inv_name, current_stock, unit_cost)
VALUES 
('inv_1', '组件1', 100, 10.00),
('inv_2', '组件2', 80, 15.00),
('inv_3', '组件3', 50, 20.00);

-- 插入集合产品
INSERT INTO collections (coll_id, coll_name, sale_price)
VALUES 
('coll_a', '两件套组合', 40.00),
('coll_b', '三件套组合', 60.00);

-- 插入集合与组件的关联关系
INSERT INTO collection_component_map (coll_id, inv_id, component_quantity)
VALUES 
('coll_a', 'inv_1', 1),
('coll_a', 'inv_2', 1),
('coll_b', 'inv_1', 1),
('coll_b', 'inv_2', 1),
('coll_b', 'inv_3', 1);

需求实现:追踪组件需求(销量)

若需统计每个组件的总需求,可结合销售记录表计算。先创建销售记录表:

CREATE TABLE sales (
    sale_id INT AUTO_INCREMENT PRIMARY KEY,
    coll_id VARCHAR(50) NOT NULL,
    sale_quantity INT NOT NULL,
    sale_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (coll_id) REFERENCES collections(coll_id)
);

统计每个组件的总需求(销量对应的组件用量):

SELECT 
    ri.inv_id,
    ri.inv_name,
    SUM(ccm.component_quantity * s.sale_quantity) AS total_demand
FROM sales s
JOIN collection_component_map ccm ON s.coll_id = ccm.coll_id
JOIN raw_inventory ri ON ccm.inv_id = ri.inv_id
GROUP BY ri.inv_id, ri.inv_name;

方案优势说明

直接的多对多关系扩展性差(无法记录组件数量等额外信息),此方案通过中间表拆解为两个一对多关系:

  • collections 到 collection_component_map 是一对多(一个集合对应多个组件关联记录)
  • raw_inventory 到 collection_component_map 是一对多(一个组件对应多个集合关联记录)

既满足关联需求,又保留扩展性(后续可在中间表添加装配顺序、组件备注等字段),同时避免了数据冗余与不一致问题。

关于单表方案的问题

你之前考虑的单表方案(集合与组件同存一表)会导致大量数据冗余:比如inv_1会在coll_a和coll_b的记录中重复出现,组件信息更新时需修改多条记录,极易出现数据不一致,不建议使用。

内容的提问来源于stack exchange,提问作者Kelsey Butler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:38:15