PHP商城 商品模块 数据库 表设计

Wesley13
• 阅读 461

PHP商城 商品模块 数据库 表设计
表关系:
分类表 <= 商品表 <= SKU表(库存表)
分类表 <= 属性名 <= 属性值
商品表 <= 商品和属性关系表 => 属性名|属性值

业务逻辑:
1.同一商品不同SKU库存和售价不同.
2.不同类型的商品具有不同的属性名和属性值(如汽车和服饰),所以属性需要支持后期添加和维护.
3.在某个商品分类下通过属性筛选商品.
4.商家某件商品的销量统计,该件商品内几个不同SKU的销量统计.
5.更多...

分类表:
(商品分类编号, 分类名称, 父分类编号)
(1, 男装, 0)
(2, 裤子, 1)
(3, 外套, 1)
(4, 内裤, 1)
(5, 袜子, 1)

商品表:
(商品编号, 商品名称, 商品分类编号, 卖家编号, SPU销量, 评论数)
(1, '裤子名', 2, 1, 0)
(2, '外套名', 3, 1, 0)
(3, '内裤名', 4, 1, 0)
(4, '袜子名', 5, 1, 0)

SKU表(库存表):
(SKU编号, 商品编号, SKU属性, 价格, 库存, SKU销量)
(1, 1, [1:1,2:3], 99, 400, 0) 其中 [1:1,2:3] 表示 "颜色为黑色,尺码为X"
(2, 1, [1:1,2:4], 99, 200, 0) 其中 [1:1,2:4] 表示 "颜色为黑色,尺码为XL"
(3, 1, [1:2,2:3], 99, 300, 0) 其中 [1:2,2:3] 表示 "颜色为白色,尺码为X"
(4, 1, [1:2,2:4], 99, 100, 0) 其中 [1:2,2:4] 表示 "颜色为白色,尺码为XL"
上面只列出商品1这个分类的4个SKU.

属性名:
(属性名编号, 属性名, 商品分类编号, 父属性编号)
(1, 颜色, 2, 0)
(2, 尺码, 2, 0)
(3, 品牌, 2, 0)
上面只列出裤子这个分类的3个属性名.

属性值:
(属性值编号, 属性值, 属性名编号)
(1, 黑色, 1)
(2, 白色, 1)
(3, X,  2)
(4, XL, 2)
(5, 七匹狼, 3)
(6, 九牧王, 3)
上面只列出裤子这个分类的6个属性值.

商品和属性关系表:
(自增编号, 商品编号, 属性名编号, 属性值编号)
(1, 1, 1, 1) 商品1颜色为黑色
(2, 1, 1, 2) 商品1颜色为白色
(3, 1, 2, 3) 商品1尺码为X
(4, 1, 2, 4) 商品1尺码为XL
上面只列出商品1的4个属性关系.

商品和属性筛选表:
(商品编号, 商品具有的属性值编号)
(1, [1,2,3,4])
用SQL全文检索实现筛选.
如:
select * from 商品表 
inner join 商品和属性筛选表 
on 商品表.商品编号 = 商品和属性筛选表.商品编号
where 商品表.商品分类编号 = 2 
and 商品和属性筛选表.商品具有的属性值编号 MATCH '1 3'
order by 商品表.评论数 DESC LIMIT 10 OFFSET 20;

商品搜索表:
(商品编号, 商品标题和内容)
(1, [无需词典,二元分词])
用SQL全文检索实现搜索.

里面有这么一些表结构设计思想:
名值: id, name, value (用于实现自定义字段如属性的存储)
父子: id, pid (用于实现关系树如分类和子分类的存储)
其中"名值"的思想应该就是EAV(Entity-Attribute-Value)实体属性值模型思想.
留意过WordPress数据表的也会看到类似设计:
wp_postmeta(meta_id,post_id,meta_key,meta_value)
wp_commentmeta(meta_id,comment_id,meta_key,meta_value)
wp_usermeta(umeta_id,user_id,meta_key,meta_value)
wp_options(option_id,option_name,option_value,autoload)
"父子"存储无限极分类:
wp_term_taxonomy(term_taxonomy_id,term_id,taxonomy,parent)

上面提到的无需词典的二元分次算法示例:

<?php
function cws($str) {
    //找出字符串中的英文单词和数字
    if(preg_match_all('%[A-Za-z0-9_-]{1,}%', $str, $matches)) {
        $arr = $matches[0];
    }
    //以非中文(中文包括简体和繁体)进行正则分割
    $sections = preg_split('%[^\x{4e00}-\x{9fa5}]{1,}%u', $str);
    foreach($sections as $v) {
        //注意:foreach中多次正则匹配会降低性能
        switch(true) {
            case ($v === ''): continue; break;
            case (mb_strlen($v, 'UTF-8') < 3): $arr[] = $v; break;
            case (preg_match_all('%[\x{4e00}-\x{9fa5}]%u', $v, $matches)):
                //前后俩俩组合,实现冗余分词.
                //如"中国好声音"将被分词为: 中国 国好 好声 声音
                $size = count($matches[0]);
                for($i = 0; $i <= $size-2; $i++) {
                    $word = '';
                    for($j = 0; $j < 2; $j++) {
                        $word .= $matches[0][$i+$j]; //echo $i.' '.$j.' '.$matches[0][$i+$j]."\n";
                    }
                    $arr[] = $word; //echo "\n";
                }
                break;
        }
    }
    return array_unique($arr);
}
点赞
收藏
评论区
推荐文章
Easter79 Easter79
2年前
sql注入
反引号是个比较特别的字符,下面记录下怎么利用0x00SQL注入反引号可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景,下面具体说下1)表名payload:select\from\users\whereuser\_id1limit0,1;!(https://o
Wesley13 Wesley13
2年前
java 商家取消订单流程
商家取消订单的过程中,关联:退款、恢复库存、核减销量过程一、使用表格:req\_order\_ops       订单发起请求操作表goods\_order2        订单表goods              商品表goods\_order2\_oplog  订单日志表r
Wesley13 Wesley13
2年前
MySQL 基本操作
1、创建数据库:CREATE DATABSE  数据库名;2、切换数据库:USE DATABASE 数据库名;3、创建数据表:CREATE TABLE 表名(属性名 属性类型,...);4、插入数据:INSERT INTO 表名 VALUES(数据值,...);5、从文件中导入数据:
Wesley13 Wesley13
2年前
mysql数据过滤
1、AND操作符:select表的字段名from对应的表名where表的字段名AND表的字段名运算符值;例子:selectprod\_id,prod\_price,prod\_namefromproductswhereven\_id1003ANDprod\_price<10;2、OR操作符:sele
Wesley13 Wesley13
2年前
MYSql对外键约束及字段的一些操作
最近使用JPA项目自动生成数据表,实体类的属性修改过,对应的数据表也增加了相关的字段。现在要删掉多余的字段。1、mysqlurootproot登录2、setcharsetgbk;设置字符集3、showcratetable表名;查看对应表的所有字段及约束名称4、altertabledrop表名dr
Wesley13 Wesley13
2年前
oracle查询表数据并重新插入到本表
oracle查询表数据并重新插入到本表CreateTime2018年5月17日10:30:10Author:Marydon1.情景描述查询表中数据SELECTFROMat_aut
Wesley13 Wesley13
2年前
Oracle一张表中实现对一个字段不同值和总值的统计(多个count)
需求:统计WAIT\_ORDER表中的工单总数、未处理工单总数、已完成工单总数、未完成工单总数。表结构:为了举例子方便,WAIT\_ORDER表只有两个字段,分别是ID、STATUS,其中STATUS为工单的状态。1表示未处理,2表示已完成,3表示未完成总数。 SQL:  1.SELECT   2
Wesley13 Wesley13
2年前
ThinkPHP 根据关联数据查询 hasWhere 的使用实例
很多时候,模型关联后需要根据关联的模型做查询。场景:广告表(ad),广告类型表(ad\_type),现在需要筛选出广告类型表中id字段为1且广告表中status为1的列表先看关联的设置部分 publicfunctionadType(){return$thisbelongsTo('A
Easter79 Easter79
2年前
SpringBoot+RabbitMQ+Redis实现商品秒杀
业务分析一般而言,商品秒杀大概可以拆分成以下几步:1.用户校验校验是否多次抢单,保证每个商品每个用户只能秒杀一次2.下单订单信息进入消息队列,等待消费3.减少库存消费订单消息,减少商品库存,增加订单记录4.付款十五分钟内完成支付,修改支付状态创建表goods\_info商品库存表
Stella981 Stella981
2年前
SpringBoot+RabbitMQ+Redis实现商品秒杀
业务分析一般而言,商品秒杀大概可以拆分成以下几步:1.用户校验校验是否多次抢单,保证每个商品每个用户只能秒杀一次2.下单订单信息进入消息队列,等待消费3.减少库存消费订单消息,减少商品库存,增加订单记录4.付款十五分钟内完成支付,修改支付状态创建表goods\_info商品库存表