【发布时间】:2018-08-07 10:38:17
【问题描述】:
我正在创建一个电子商务网站,并试图弄清楚如何让用户能够为产品选择合适的选项。
目前我有一个产品表,其中包括一个 ID 列,其中的属性适用。
然后我的属性表有一个“名称”列和“属性 1”-“属性 15”列。因此,如果名称为“Size”,则“attribute1”-“attribute15”列将具有“small”、“medium”、“large”等值。有一些空白列,具体取决于产品有多少属性(最多 15 个)。
然后在我的后端我有一个定价表格。因此,例如,如果一个产品有两个属性(尺寸和颜色),它将在表单中具有每个组合。例如:黑色 - 小号、黑色 - 中号、黑色 - 大号、蓝色 - 小号、蓝色 - 中号、蓝色 - 大号等。
每个组合都有一个复选框和一个价格输入。如果我选中该复选框,则表示该组合可用并且我存储价格值。所以我的定价表有一个产品 ID,可能有多个属性 ID,还有一个 1-15 列来说明这个价格是针对该属性的哪个选项。
目前我的产品页面首先查询我的产品表以查看适用的属性。它为其中的每一个创建一个下拉列表,但并非所有这些都适用,因为该组合可能不可用。例如,我们可以有一个“小黑色项目”和一个“大黑色项目”,但没有“中黑色项目”。所以我正在寻找一种方法,如果他们在颜色下拉列表中选择黑色,则在其他下拉列表中没有中等选项。
在 foreach 循环中,我从定价表中获取带有价格的 ID 和列,然后搜索属性表以显示该属性的下拉列表,如下所示:
$attribute_id = $attribute[0];
$attribute_column = $attribute[1];
$params = [$attribute_id];
$sql = "SELECT * FROM attributes WHERE id=?";
$stmt = DB::run($sql,$params);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$attribute_title = $row["name"];
}
$attribute_list .= $attribute_title.'<br />';
$attribute_list .= "<select name='attribute_price' class='attribute_price'>";
$attribute_list .= "<option value='0'>Choose an option...</option>";
$params = [$attribute_id];
$sql = "SELECT * FROM attributes WHERE id=?";
$stmt = DB::run($sql,$params);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
for($i=1; $i<=15; $i++){
$column = 'attribute'.$i;
$product_attribute = $row["$column"];
if($product_attribute != ""){
$attribute_list .= "<option value='";
$attribute_list .= $attribute_id.'-'.$column;
$attribute_list .= "'>$product_attribute</option>";
}
}
}
$attribute_list .= "</select>";
目前,他们可以从该组属性中选择任何选项,即使它可能不适用于该产品。如果他们这样做,只会说该组合不可用。
有没有更好的方法只显示适用于该产品的属性?
【问题讨论】:
-
不知道现在是否可以更改您的架构,但是拥有“适用于其属性的 ID 的列”的设计确实很糟糕。解决这个问题的“正常”方法是你有一个
products表、一个attributes表和一个productAttributes表。productAttributes表通常只是 productIds 与 attributeIds 的匹配。该方法至关重要的原因是,您可以使用JOINs 拉回所有适当的数据。 -
另一种思考方式是,您的数据中存在 多对多 关系。 (1 个产品可以有很多属性。1 个属性可以应用到很多产品。)当您意识到您有一个多对多关系时,就需要第三个查找表,位于这两个值之间。
-
@AdamDavis,感谢您的评论。是的,我知道你的意思,最初我们的网站只允许一个属性,所以我们曾经有一个类别,例如每种颜色和里面你过去只能选择一个尺寸。我们正在重做这一切的工作方式,所以我希望不必重新创建所有表格,因为它们已经填充了数千种产品。