声明:之所以定位在"中小型"商城系统,而非“大型”(指淘宝、拍拍这类巨无霸),理由很简单----我一直都呆在(创业型的)小公司,没见过这些大家伙是怎么设计的:)

正文:

之前发表过一篇"商城系统中【商品扩展属性】的表单生成及客户端验证",部分童鞋对于后台数据库的设计比较感兴趣,于是今天把这部分也补上。

一、产品分类设计
越来越多的商城系统都热衷于选择“无限级分类”的设计,我也不例外,因为它方便扩展。这部分就不详细展开了,详见

无限级分类(非递归算法/存储过程版/GUID主键)完整数据库示例_(1)表结构 
无限级分类(非递归算法/存储过程版/GUID主键)完整数据库示例_(2)插入记录

无限级分类(非递归算法/存储过程版/GUID主键)完整数据库示例_(3)删除记录

无限级分类(非递归算法/存储过程版/GUID主键)完整数据库示例_(4)显示记录

稍微啰唆几句:
1.1 我习惯于把所有表加上前缀T_(即Table的第一个字母),把所有字段加上前缀F_(即Field的第一个字母),把视图加上前缀V_(即View的第一个字母)...,这样最大的好处是在写linq to Sql时,智能提示(感应)会很爽,所有相关的东西全部列在一起,省去记忆脑细胞无数

1.2 这是我06年时从动网论坛剥下来的表结构(当然我又做了一些改造),它的最大特点在于:通过添加一些辅助字段完全避开了无限分类中的递归问题。
1.3 之所以用guid做为主键,主要是考虑到数据库迁移时的方便,当然guid主键会带来一些性能上的损失(二害相权,取其轻也),为了改进可将guid改为comb主键(详见 “Integer GUID和Comb做主键的效率测试”)
1.4 考虑到很多人为了各种原因喜欢把分类页生成静态页,而为了url地址的简短/友好,guid主键有些长,所以我又添加了一个辅助字段F_AutoId,这样生成的静态页可以从类似"43A6162C-308A-4112-86F8-6E6B6B76FC6E.html"变成"1234.html"

二、产品分类--产品关联设计

如果“产品:分类”是1:1关系(即:一个产品只能归到一个分类下),则直接在产品表(T_Product)中增加一个字段(F_ClsId)即可。
如果“产品:分类”是1:N关系(即:一个产品能同时归到多个分类下),则必须新建一个表(T_ProductInClass),建二个字段(F_ClsId,F_ProductId),并把这二个字段设置为联合主键即可。

注:1:1还是1:N取决于需求,没有谁好谁坏之说。

三、扩展属性
终于到了正题了,对于产品的扩展属性,因为(在产品分类未选择之前)无法事先确定产品的扩展属性有哪些,所以这部分属性显然不适合通过在T_Product中预留一大堆字段来解决(而且这样性能也不好)

考虑到扩展属性总是基于分类的(比如:电脑类的产品应该具有"CPU频率、内存容量、显示器尺寸、硬盘大小"等扩展属性,而服装类产品应该具有“颜色、尺码、品牌、面料”等扩展属性),所以可以新建一个"分类扩展表"用于存储分类的扩展属性基础定义。

01 CREATE TABLE [dbo].[T_ClassAppend](
02  [F_Id] [uniqueidentifier] NOT NULL,--主键
03  [F_ClsId] [uniqueidentifier] NOT NULL,--关联外键(分类ID)
04  [F_DisplayName] [nvarchar](50) NOT NULL,--(扩展属性)显示名称(比如:品牌,内存大小,颜色之类)
05  [F_FieldName] [nvarchar](50) NOT NULL,--(扩展属性)字段名称(比如:Brand,Memoery,Color之类)
06  [F_ValueType] [nvarchar](50) NOT NULL,--字段类型(比如:字符串,整数,日期之类)
07  [F_ValueLength] [int] NOT NULL,--属性值长度(比如:50)
08  [F_InputType] [nvarchar](50) NOT NULL,--输入类型(比如:文本框,文本域,下拉框,复选框之类)
09  [F_DefaultValue] [nvarchar](500) NOT NULL,--默认值
10  [F_IsRequired] [tinyint] NOT NULL,--是否必须填写
11  [F_isShow] [tinyint] NOT NULL,--显否显示
12  [F_Orders] [int] NOT NULL,--排序号
13  [F_AutoId] [int] IDENTITY(1,1) NOT NULL,--辅助自动ID(预留)
14  CONSTRAINT [PK_T_ClassAppend] PRIMARY KEY CLUSTERED 
15 (
16  [F_Id] ASC
17 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
18 ) ON [PRIMARY]

保存数据后的大概样子如下:

解决了扩展属性的定义问题,接下来再来考虑产品的这些属性到底应该保存在哪里?

先回顾一下产品上传的基本逻辑,在不考虑扩展属性的传统场景下:用户进入产品发布页面,选择产品分类,然后填写其它产品属性,最终保存到数据库。

分析一下:只要用户选择了分类,我们就能得到分类ID,进而得到该类的“扩展属性定义”,也就知道了该产品应该具有哪些扩展属性,如果这时有一张特定的产品扩展属性表(来对应这些扩展属性的定义),那么直接把这些扩展属性insert进这张表即可。

技术处理:保存产品时,先得到用户选择的分类ID,然后根据上面定义的T_ClassAppend分类扩展属性定义表,去检查是否已经生成了该类的"产品扩展属性表",如果没有则动态生成一个类似T_Product_XXXX的表(注:XXXX即为分类的F_AutoId值),然后该干嘛干嘛,常规公共属性保存进T_Product,扩展属性保存进T_Product_XXXX。

注:T_Product 与 T_Product_XXXX 之间应该有(产品ID的)主外键关联

如下图:

注:图中的F_ID其实可去掉,没啥实际意义(最初我是打算用来保存记录流水号的,后来发现完全没啥必要,这一点精减工作就留给大家去做吧)

可能存在的问题:
1、产品修改时,如果从分类A改成了分类B(即发布时,产品分类选错了,在编辑时,重新指定产品分类),那么扩展属性对应的保存表名,可能会从T_Product_123 变成 T_Product_456,这时要注意先把原来的T_Product_123中的记录删除,不然时间长了,会留下一堆冗余记录。

2、分类扩展属性有变动时,比如电脑类,又新增了一项属性:"是否支持双显卡(F_IsDoubleVGA)",那么这里原来的产品扩展属性表T_Product_123,也要相应的增加一个类似F_IsDoubleVGA的字段类型

四、搜索问题的解决

这部分其实是最难解决的,不过也不是没有办法,分二种情况:

1、第一种情况

通常情况下,用户其实很少一上来就搜索扩展属性,很多场合下,用户会先浏览某感兴趣分类列表,然后再挑选商品。

这种情况就好办多了,因为用户一旦确定了分类,也就意味着能得到分类ID,进而得到最终的产品扩展属性表名(比如T_Product_123),这时搜索就简化为搜索 T_Product 与 某一个特定的T_Product_XXX

2、第二种情况

如果系统要求用户直接在搜索栏里输入 "ThinkPad 双显卡 4G内存 T系列"这类关键词,然后自动匹配出所有属性/扩展属性的商品。

那么,其实这已经演化成网站搜索引擎的需求,传统的 select... like ...在这种需求下基本上已经没啥用处了,可以考虑用lucene或园子里"盘古分词"作者eaglet (注:该兄是搜索引擎方面的资深人士,值得依赖!)的解决方案来实现站内搜索引擎。

中小型商城系统中的分类/产品属性/扩展属性的数据库设计相关推荐

  1. 中小型超市系统中的分类/产品属性/扩展属性的数据库设计

    中小型商城系统中的分类/产品属性/扩展属性的数据库设计 正文: 之前发表过一篇"商城系统中[商品扩展属性]的表单生成及客户端验证",部分童鞋对于后台数据库的设计比较感兴趣,于是今天 ...

  2. 商城系统商品属性的数据库设计思路

    京东商城的数据库是如何搭建的,那么多商品,每种商品的参数各不相同,是怎样设计数据库的? 在提及这种设计思路前,首先得了解数据表可以分为两种结构: 1\横表,也就是我们经常用到的表结构, 2\纵表,这种 ...

  3. 电商系统中的分类属性系统设计之我见(抛砖引玉)

    电商系统中的分类属性系统设计之我见(抛砖引玉)          需求原型:          目前公司在整合户外广告行业媒体.户外广告行业分为不同的大类(高速,公交,机场,地铁,商超,火车)等等大的 ...

  4. CRM系统中客户分类、客户标签的应用

    企业在选择CRM软件时,对于客户标签和客户分类的使用是不是觉得不太实用,甚至还不太能分清两者的区别,本篇文章将着重介绍客户分类和客户标签的区别和用途,希望帮助您理解两个概念,并在实际工作中充分发挥好它 ...

  5. 【Linux系统】第9节 linux系统中用户分类以及用户与组属性的修改示例

    目录 1 用户的分类 2 用户与组的相关设置文件 2.1 passwd文件 2.2 shadow文件 2.3 group文件 3 CentOS系统中用户与组的创建及属性的修改示例 3.1 相关命令 3 ...

  6. Win8系统中如何显示/隐藏文件扩展名

    后缀扩展名相信大家对它不陌生,扩展名后面的格式各式各样的种类繁多.但有的用户在Windows8系统中想隐藏后辍扩展名,却不知道在哪找到将其关闭.​ 工具/原料 ​Windows8系统 方法/步骤 打开 ...

  7. 商城系统中重复下单问题

    引起重复下单的原因 一个用户秒杀到一件商品后,又进行秒杀(这里我理解应该是秒杀场景只允许一个用户买到一个商品吧) 一个用户快速发起多次请求(多次请求的代码都执行通过了订单重复校验),这时这两条并行的代 ...

  8. 商城系统开发从0到1(sku之设计与实现)

    商城系统的一个难点就是商品规格的设计,如何设计一个可拓展,灵活性高的呢,这是一个难点和痛点.下面直接上干货! 首先是数据库设计 1.SKU表 CREATE TABLE "TB_PEM_PRO ...

  9. linux系统中db2创建表空间,为DB2数据库创建表空间

    数据库中的表空间(tablespace) 是一个逻辑层,一些数据库对象(比如表.视图和索引)驻留在这里.一个数据库可以有多个表空间.在首次创建数据库时,DB2 会自动地创建一组表空间. 在 Contr ...

最新文章

  1. linux 发行版本和 及其与linux内核之间的关系
  2. bitcoin全节点部署及bitcoind bitcoin-cli命令使用解释
  3. 编程软件python下载-Thonny(Python编程工具) v3.2.7 官方版
  4. Oracle编程入门经典 第4章 新9i示例模式
  5. netstrem获取302后的地址,可用来截图,加载实际跨域文件
  6. zookeeper是如何实现数据一致性的?
  7. MOSS数据库服务器迁移步骤
  8. 图论 —— 网络流 —— 最小割 —— 最大权闭合子图
  9. java使用btree_java数据结构之二叉树遍历的非递归实现
  10. java大文件读,java 读大文件报错
  11. Linux用户和用户组的管理-羽飞作品
  12. 出生年分数 15作者 陈越单位 浙江大学
  13. 计算机毕业设计ssm鲲龙装饰公司在线管理系统的设计与开发前台模块iub6h系统+程序+源码+lw+远程部署
  14. java与模式pdf 闫宏_Java设计模式及实践.pdf下载
  15. Arduino Mega2560简介
  16. 文章阅读总结:GPT
  17. Markdown编辑器推荐与语法教程--图片版
  18. java10以内的加减法_Java实现随机10道10以内加减法的代码详解
  19. 太经典了!NBA球员超逗的豪言壮语
  20. 如何打造智能化舆情研判预警系统

热门文章

  1. mmse评估量表_简易智能精神状态检查量表(MMSE)
  2. 逻辑卷管理 、fdisk、 VDO 、parted、 RAID磁盘阵列 、 进程管理
  3. react中使用Knob - Dial
  4. Tribon 套料软件开发,生成的dxf文件显示不全
  5. 信息系统项目管理师---第十二章 项目采购管理
  6. 现在的放假还叫放假吗?其实就是调休!
  7. Django入门笔记
  8. python数据分析-柱状图绘制及常用参数设置
  9. 做人脸识别的时候,千万别光着
  10. 工具 | 快速视频压缩与格式转换 | 格式工厂