`

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

 
阅读更多

正文:

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

 

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

无限级分类(非递归算法/存储过程版/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频率、内存容量、显示器尺寸、硬盘大小"等扩展属性,而服装类产品应该具有“颜色、尺码、品牌、面料”等扩展属性),所以可以新建一个"分类扩展表"用于存储分类的扩展属性基础定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE [dbo].[T_ClassAppend](
 [F_Id] [uniqueidentifier] NOT NULL,--主键
 [F_ClsId] [uniqueidentifier] NOT NULL,--关联外键(分类ID)
 [F_DisplayName] [nvarchar](50) NOT NULL,--(扩展属性)显示名称(比如:品牌,内存大小,颜色之类)
 [F_FieldName] [nvarchar](50) NOT NULL,--(扩展属性)字段名称(比如:Brand,Memoery,Color之类)
 [F_ValueType] [nvarchar](50) NOT NULL,--字段类型(比如:字符串,整数,日期之类)
 [F_ValueLength] [int] NOT NULL,--属性值长度(比如:50)
 [F_InputType] [nvarchar](50) NOT NULL,--输入类型(比如:文本框,文本域,下拉框,复选框之类)
 [F_DefaultValue] [nvarchar](500) NOT NULL,--默认值
 [F_IsRequired] [tinyint] NOT NULL,--是否必须填写
 [F_isShow] [tinyint] NOT NULL,--显否显示
 [F_Orders] [int] NOT NULL,--排序号
 [F_AutoId] [int] IDENTITY(1,1) NOT NULL,--辅助自动ID(预留)
 CONSTRAINT [PK_T_ClassAppend] PRIMARY KEY CLUSTERED
(
 [F_Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) 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 (注:该兄是搜索引擎方面的资深人士,值得信赖!)的解决方案来实现站内搜索引擎。

 

后记:早上写得匆忙,有些细节没写详细,现在补上。

 

看到回复中有些朋友觉得这种设计表太多,太复杂,这个嘛...其实我觉得还好啦,只是在原来的分类表T_Class的基础上,增加了一个T_ClassAppend表而已,至于那一堆的T_Product_XXX 表,我写了一个分类管理器来自动生成,不用手动来做,另外再封装一些逻辑(比如根据分类ID自动返回扩展属性表名之类),对于普通开发人员来讲,开发难度只是轻微增加而已.

上图为分类管理器的界面。

 

继续更新:

看到越来越多的人回复来讨论这个问题,很是高兴(相互交流才能进步),特地又加了一张图,建议大家先在完全明白我的意图之后,再讨论如何改进,不然大家你用你的说法,我用我的说法,但其实完全有可能只是同一个问题的不同说法,这样沟通起来比较费劲。

其实我的想法很简单:

将商品的共用属性(比如:价格,商品名称,商品编码这些肯定要有的东西)与扩展属性(即:根据分类不同而不同的非共用属性,比如电脑类的"CPU/硬盘容量...",充值卡类的"面值/适用地区...",服装类的"尺码/颜色...")分开保存而已,相当于原本应该保存一张表T_Product中的东西,拆分成二部分。但由于每个分类的特性不同,每个类对应的产品都有不同的扩展属性值,所以不适合把所有产品的扩展属性保存在同一张表中,如果这样可以的话,干嘛还要费心把共用属性与扩展属性分开,搞拆分这么麻烦?)

共用属性保存到 T_Product表,而扩展属性保存到 T_Product_N 表(其中N 与 某一个分类记录的ID对应)

在逻辑上可以认为,每条产品记录的全部属性,都是 "T_Product中的一条记录" + "T_Product_N(N为该产品所属分类的对应Id)中的一条记录" 共同描述的

 

至于表的个数,其实只增加了“ 1 + N ” 张表(1即多出来的分类扩展属性定义表,而N即为T_Class中产品分类的记录条数),所以只要分类数不变,产品扩展表的数量也是一定的。

 

至于大家提到的品牌问题,品牌其实最适合与分类当作平行处理,毕竟很多时候搞活动做专题,都是以品牌作为主要选择依据的(如果当成扩展属性处理,并非行不通,只是不适合)

 

另外之所以会引出搜索问题,其实反过来考虑很容易理解,如果不做拆分,按传统方式,用Sql语句直接搜索T_Product表即可。但现在把属性分成了二部分,所以很难确定用户搜索时,是想搜索共用属性,还是扩展属性?所以有上面提到搜索的二种情况。

 

最后谈一下数据库查询的问题,看到'小菁菁'同学的观点:数据库就是为了查询方便。基本上,这个没错!但是如果您遇到过单表千万级数量的情况,而且基于某些要求又无法利用索引。(比如最纠结的like该不该用的老问题:如果不用like,强制用=来处理,当然速度会快很多,但是查询就不准确,比如用户就记得产品描述中的几个字,别的都不记得,这时候站在用户的立场,无疑模糊查询是最好的,但是在海量数据情况下,这样做又几乎是灾难)。在这些特定情况下,关系型数据库(不管是sqlserver还是oracle)的查询能力都是无能为力的,如果您去百度一下关于搜索引擎的数据库设计,几乎看不到采用关系型数据库做为查询核心的。推荐几篇我以前收集的搜索引擎架构文章给您参考下http://www.cnblogs.com/yjmyzz/archive/2009/06/18/1506083.html

 

当然"学无先后,达者为先"。如果大家有更好的解决方案,欢迎回贴指导。

 

最后YY一句,就这种拍脑袋的设计,07年时曾经受住了日均IP10万的访问量,当时日均IP从中国站长站监测的结果,已经达到了同期中国新蛋日均IP的1.5倍(当然还有其它优化措施,这个就不一一展开了)

分享到:
评论

相关推荐

    考勤系统数据库课程设计.doc

    1.3数据库系统设计及范式分析 数据库设计主要是进行数据库的逻辑设计,即将数据按一定的分类、分组系统和逻辑 层次组织起来,是面向用户的。数据库设计时需要综合企业各个部门的存档数据和数据 需求,分析各个数据...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    在系统设计和开发过程中,要充分考虑系统当前和将来可能承受的工作量,使系统的处理能力和响应时间能够满足信息处理的需求。 2、 系统的开放性和系统的可扩充性:系统在开发过程中,应该充分考虑以后的可扩充性。...

    韩式服装网店发布系统源码下载

    服装网站管理系统正式版助中国大中小型服装公司走上信息化道路,服装网站管理系统正式版助中国服装走上网络,建立网上品牌,实现服装公司电子商务,服装网站管理系统正式版为中国服装实现网上 销售,提高工作效率,节省...

    贴心猫(TiexinCat) v4.5.zip

    适用于:网店,医院,学校,企业站,个人网站,企业内部Intranet,中小型行业门户站点等…… 安全-高效-轻量-免费-共享 PC版-手机版-微信接口一站搞定 支持PHP5.2~PHP7.0/模型无限扩展/字段无限扩展/按类别扩展...

    TinyDB v2.94 修改版

    TinyDB是一个Delphi和C++Builder程序下小、快、可靠的数据库引擎,它可以存取自有格式的平面文件,不需要BDE,不需要安装和配置。采用TinyDB引擎,所有数据都可一...// 注意: TinyDB是只能支持本地库的小型数据库系统

    基于C++&QT实现的小型通讯录管理系统.zip

    Qt类库中大量的类以模块形式分类组织的,包括基本模块和扩展模块等。一个模块通常就是一个编程主题,如数据库、图表、网络等。 一、Qt核心特点 1.1.概述 Qt本身并不是一种编程语言,它本质上是一个跨平台的C++开发...

    一款超强的图形系统—C#源码C#vb.net_source_vg7.23

    这是一套是一套非常完善的图形系统,适合在电力、煤炭、化工、仿真、网络、自动化等各种工业监控软件以及图形建模、图形管理、图形分析、中小型GIS系统、工作流、中文表格、表单、工程绘图等软件项目中应用。...

    Hishop电子商务平台v1.0.924

    Hishop有四个版本,分别适用于大型及中小型的网上商场.它们分别是 Hishop 商城高级版、Hishop 商城标准版、Hishp 专营高级版、Hishop 专营标准版. 程序特点: 三级分类(标准版及试用版是二级分类) 强大的自定义...

    tuzicms_v2.5_personal_企业网站管理系统

    TC 采用MVC 设计模式实现业务逻辑与表现层的适当分离,使网页设计师能够轻松设计出理想的模板,框架式开发易用扩展,支持自定义内容模型,可面向中小型站点提供重量级网站建设方案。对于那些想要进行开发,但技术...

    Hishop电子商务平台 v2.0.111.0

    Hishop有四个版本,分别适用于大型及中小型的网上商场.它们分别是 Hishop 商城高级版、Hishop 商城标准版、Hishp 专营高级版、Hishop 专营标准版. 其中的专营高级版和专营标准版又按商品及分类数量分了多种版本. ...

    asp.net知识库

    如何使数据库中的表更有弹性,更易于扩展 存储过程——天使还是魔鬼 如何获取MSSQLServer,Oracel,Access中的数据字典信息 C#中利用GetOleDbSchemaTable获取数据库内表信息[原创] 如何解决ACCESS中SELECT TOP语句竟然...

    YCKIT v2013 SP1.zip

    博客、个人网站、企业网站、中小型门户站...等等,只要你有想象力加上PHP基础基本上都可以做,扩展模块功能也非常方便。     使用说明: 1.把所有文件上传到服务器或者放置到本地服务器 2.如果是Linux...

    一款超强的图形系统——VC源码

    这是一套是一套非常完善的图形系统,适合在电力、煤炭、化工、仿真、网络、自动化等各种工业监控软件以及图形建模、图形管理、图形分析、中小型GIS系统、工作流、中文表格、表单、工程绘图等软件项目中应用。...

    php网络开发完全手册

    13.1 关系型数据库与关系型数据库系统的 13.1 介绍 204 13.2 关系型数据库系统的结构与运行过程 205 13.2.1 关系型数据库系统的层次结构 205 13.2.2 关系型数据库系统的运行过程 206 13.3 常用的关系型数据库的介绍 ...

    一款超强的图形系统——Delphi源码Delphi-source-VG7.23

    这是一套是一套非常完善的图形系统,适合在电力、煤炭、化工、仿真、网络、自动化等各种工业监控软件以及图形建模、图形管理、图形分析、中小型GIS系统、工作流、中文表格、表单、工程绘图等软件项目中应用。...

    软件工程知识点

    概要设计中首先需要进行的是系统构架设计,然后是软件结构、数据结构等方面的设计。主要有以下几个方面的设计任务:制定规范、系统构架设计、软件结构设计、公共数据结构设计、安全性设计、故障处理设计、可维护性...

    我国GIS软件的发展现状

    地理信息系统(GIS)是一门实践性很强的学科,它既有理论和方法研究的一面,又有技术和产品开发的一面。从产品的角度看,GIS主要包括数据产品和软件产品(或部分软硬件一体化的产品)。地理信息产业是信息产业的一个...

    NopCommerce 1.6 中文源码包.rar

    •产品分类(前端) •支付宝(中国)支付模块(测试版) •能够使用HTML编辑器上传图片(管理区) •更多的SEO友好 •新的运送状态 - 发货 •新产品属性的控件类型的支持 - 多行文本框 •性能优化 •允许...

    07FLY-CRM-v2版客户管理系统-PHP

    07FLY-CRM是一款国产开源的通用型客户管理系统,适用各类行业,主要针对中小型销售/售后服务团队。该系统支持客户资料自定义配置、查询以及支持二次开发接口。如果你想拥有一个简单实用、接地气的客户管理系统,也许...

Global site tag (gtag.js) - Google Analytics