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

如何设计MySQL表以存储动态添加的Challan多行商品数据?

数据库表设计方案:存储动态添加的Challan产品行

结合你提供的前端代码和业务需求,这里给你一套适合的MySQL数据库表设计方案,用来存储动态添加的多行产品数据:

核心思路:主表+明细子表(一对多关系)

一个Challan(送货/缴款单)对应多个产品行,这是典型的一对多关系,所以我们需要拆分出两张表:一张存储Challan的全局信息(主表),另一张存储每个产品行的明细(子表),通过外键关联两者。


1. Challan主表(challans)

用来存储每个Challan的基础信息,比如单据编号、创建时间、关联客户等:

CREATE TABLE challans (
    challan_id INT AUTO_INCREMENT PRIMARY KEY,
    challan_number VARCHAR(50) UNIQUE NOT NULL, -- 业务唯一的单据编号,可自动生成
    customer_id INT NULL, -- 可选:如果需要关联客户信息,可关联客户表的主键
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP, -- 单据创建时间,自动填充
    created_by INT NULL -- 可选:如果有用户系统,记录创建人ID
);

2. Challan产品明细表(challan_items)

用来存储每个Challan下的产品行数据,每一行对应前端添加的一个产品:

CREATE TABLE challan_items (
    item_id INT AUTO_INCREMENT PRIMARY KEY,
    challan_id INT NOT NULL, -- 外键,关联主表的challan_id
    product_code VARCHAR(50) NOT NULL, -- 产品编码,关联你已有的product表的code字段
    hsn_no VARCHAR(50) NOT NULL, -- HSN编码,对应前端的hsnNo输入框
    quantity INT NOT NULL, -- 产品数量,对应前端的qty输入框
    amount DECIMAL(10,2) NOT NULL, -- 金额,对应前端的amount输入框
    -- 外键约束,保证数据一致性
    FOREIGN KEY (challan_id) REFERENCES challans(challan_id) ON DELETE CASCADE,
    FOREIGN KEY (product_code) REFERENCES product(code) ON DELETE RESTRICT
);
  • ON DELETE CASCADE:如果主Challan被删除,对应的所有产品明细也会自动删除(根据业务需求可调整为RESTRICT,禁止删除有明细的主单)
  • ON DELETE RESTRICT:如果某个产品已被添加到Challan明细中,禁止删除该产品(避免数据丢失)

关键注意事项(结合你的前端代码)

你的当前前端代码有一个小问题:表单元素的name属性是单个值(比如name="code"),动态添加多行后,提交表单时只会保留最后一行的数值。必须修改为数组格式的name,这样后端才能接收所有行的数据:

修改前端代码中的name属性:

<!-- 把select的name从"code"改成"code[]" -->
<select class="form-control productID" name="code[]" style="width: 429px;">

<!-- hsnNo的name从"hsnNo$j"改成"hsnNo[]" -->
<input type='text' name='hsnNo[]' readonly>

<!-- qty的name从"qty$j"改成"qty[]" -->
<input type='text' name='qty[]' readonly>

<!-- amount的name从"amount"改成"amount[]" -->
<input type="number" format="2" name="amount[]">

后端存储流程示例

当用户提交表单时,后端PHP代码需要先插入主表,再批量插入明细:

// 1. 插入Challan主表,获取新生成的challan_id
$challanNumber = "CH-" . date("Y") . "-" . sprintf("%04d", $nextSequence); // 自定义生成单据编号
$sql = "INSERT INTO challans (challan_number) VALUES (?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $challanNumber);
$stmt->execute();
$challanId = $conn->insert_id; // 获取主表的自增ID

// 2. 遍历所有产品行,插入明细子表
$codes = $_POST['code'];
$hsnNos = $_POST['hsnNo'];
$qtys = $_POST['qty'];
$amounts = $_POST['amount'];

foreach ($codes as $index => $code) {
    $hsnNo = $hsnNos[$index];
    $qty = $qtys[$index];
    $amount = $amounts[$index];

    // 预处理SQL,避免SQL注入
    $sql = "INSERT INTO challan_items (challan_id, product_code, hsn_no, quantity, amount) VALUES (?, ?, ?, ?, ?)";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("issid", $challanId, $code, $hsnNo, $qty, $amount);
    $stmt->execute();
}

为什么这样设计?

  • 符合数据库范式:避免重复存储Challan的全局信息(比如单据编号、创建时间),减少数据冗余
  • 数据一致性:通过外键约束,保证明细行一定属于某个存在的Challan,且产品一定是已存在的
  • 扩展性强:后续如果需要添加更多Challan字段(比如备注、状态),只需修改主表;添加产品明细字段(比如单价、折扣),只需修改子表
  • 查询方便:可以轻松查询某个Challan的所有产品,或者统计某个产品的所有出库记录

内容的提问来源于stack exchange,提问作者Digitech Solution

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:26:24