商品数据库设计
我们参考网上现有的sku-spu电商数据库进行设计参考设计文章
CREATE TABLE `tb_brand` (
`id` bigint(20) NOT NULL COMMENT '品牌id',
`name` varchar(64) NOT NULL COMMENT '品牌名称',
`image` varchar(256) DEFAULT '' COMMENT '品牌图片地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=325403 DEFAULT CHARSET=utf8 COMMENT='品牌表,一个品牌下有多个商品(spu),一对多关系';
CREATE TABLE `tb_spec_group` (
`id` bigint(20) NOT NULL COMMENT '规格组Id',
`category_id` bigint(20) NOT NULL COMMENT '商品分类Id (一个分类下有多个规格组)',
`name` varchar(32) NOT NULL COMMENT '规格组名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT='规格参数的分组表,每个商品分类下有多个规格参数组';
CREATE TABLE `tb_spec_param` (
`id` bigint(20) NOT NULL COMMENT '参数Id',
`category_id` bigint(20) NOT NULL COMMENT '商品分类Id (参数所属的商品分类)',
`group_id` bigint(20) NOT NULL COMMENT '规则组Id (参数所属的规格组)',
`name` varchar(128) NOT NULL COMMENT '参数名',
`numeric` tinyint(1) NOT NULL COMMENT '是否是数字类型参数 (true或false)',
`unit` varchar(128) DEFAULT '' COMMENT '数字类型参数的单位 (非数字类型可以为空)',
`generic` tinyint(1) NOT NULL COMMENT '是否是SKU通用规格 (true或false)',
`searching` tinyint(1) NOT NULL COMMENT '是否用于搜索过滤 (true或false)',
`segments` varchar(1024) DEFAULT '' COMMENT '区间 (数值类型参数的预设区间值,如果需要搜索,则添加分段间隔值,如CPU频率间隔:0.5-1.0)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COMMENT='规格参数组下的参数名';
CREATE TABLE `tb_spu` (
`id` bigint(20) NOT NULL COMMENT 'SPU Id',
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '商品名称',
`sub_title` varchar(256) DEFAULT '' COMMENT '副标题 (一般是促销信息)',
`cid1` bigint(20) NOT NULL COMMENT '1级分类Id',
`cid2` bigint(20) NOT NULL COMMENT '2级分类Id',
`cid3` bigint(20) NOT NULL COMMENT '3级分类Id',
`brand_id` bigint(20) NOT NULL COMMENT '品牌Id (商品所属的品牌)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=187 DEFAULT CHARSET=utf8 COMMENT='spu表描述的是一个抽象性的商品,比如 iphone8';
CREATE TABLE `tb_spu_detail` (
`spu_id` bigint(20) NOT NULL COMMENT 'SPU Id',
`description` text COMMENT '商品描述信息',
`generic_spec` varchar(2048) NOT NULL DEFAULT '' COMMENT '通用规格键值对 (json格式)',
`special_spec` varchar(1024) NOT NULL DEFAULT '' COMMENT '特有规格可选值 (json格式)',
`packing_list` varchar(1024) DEFAULT '' COMMENT '包装清单',
`after_service` varchar(1024) DEFAULT '' COMMENT '售后服务',
PRIMARY KEY (`spu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `tb_sku` (
`id` bigint(20) NOT NULL COMMENT 'SKU Id',
`spu_id` bigint(20) NOT NULL COMMENT 'SPU Id',
`title` varchar(256) NOT NULL COMMENT '商品标题',
`images` varchar(1024) DEFAULT '' COMMENT '商品图片 (多个图片用,号分割)',
`stock` int(8) unsigned DEFAULT '9999' COMMENT '库存',
`price` bigint(16) NOT NULL DEFAULT '0' COMMENT '销售价格 (单位为分)',
`indexes` varchar(256) DEFAULT '' COMMENT '特有规格参数在SPU规格模板中对应的下标组合(如1_0_0)',
`own_spec` varchar(1024) DEFAULT '' COMMENT 'SKU的特有规格参数键值对 (json格式,反序列化时请使用linkedHashMap,保证有序)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27359021564 DEFAULT CHARSET=utf8 COMMENT='sku表,该表表示具体的商品实体,如黑色的 64g的iphone 8'
商品数据库数据模拟
我们使用c#的aosu framework框架进行数据模拟
首先是配置源数据和ORMAPING
使用DB2DB工具可以将MYSQL中的数据迁移到SQLSERVER中
配置项目的数据源和ORmaping
该段代码生成一个带有商品三层分类的树,并调用方法循环生成模拟数据
private void button1_Click(object sender, EventArgs e)
{
ParamUtil pu = Aosu.Data2.Import.ItemCate.PickParamUtil<ALocalDataLoader>("select * from ItemCate");
if (pu.IsOK())
{
if (true)
{
//获取分类表信息
List<Aosu.Data2.Import.ItemCate> list2 = pu.DSUtil().GetList<Aosu.Data2.Import.ItemCate>();//.GetTree<Aosu.Data2.Import.ItemCate>("ID4Parent");
List<DAO> list = new List<DAO>();
string fieldName = "ID4Parent";
string keyfield = "ID4Cate";
SortedList<string, Aosu.Data2.Import.ItemCate> tmpDic = new SortedList<string, Aosu.Data2.Import.ItemCate>();
list2.ForEach(delegate (Aosu.Data2.Import.ItemCate t)
{
tmpDic[t[keyfield].ToString()] = t;
});
foreach (Aosu.Data2.Import.ItemCate item in list2)
{
if (string.IsNullOrEmpty($"{item[fieldName]}") || !tmpDic.Keys.Contains(item[fieldName].ToString()))
{
list.Add(item);
continue;
}
//try
//{
tmpDic[item[fieldName].ToString()].ChildrenList.Add(item);
//}
//catch (Exception){
//}
item.ParentList.Clear();
//try
//{
item.ParentList.Add(tmpDic[item[fieldName].ToString()]);
//}
//catch (Exception){
//}
}
addGoodComplex(list);
}
else
{
List<Aosu.Data2.Import.ItemCate> ltree = pu.DSUtil().GetTree<Aosu.Data2.Import.ItemCate>("ID4Cate,ID4Parent");
}
}
}
生成模拟数据的方法
int brandid = 1;
int spuid = 1;
int detailid = 1;
int skuid = 1;
int groupid = 1;
int paramid = 1;
#region 成员方法放在此处
void addGoodComplex(List<DAO> tree,int x=0)
{
//品牌名称数组
string[] Brandname = new string[3]
{
"华为","小米","苹果"
};
//品牌图片地址数组
string[] Brandurl = new string[3]
{
"./img/huawei.jpg","./img/xiaomi.jpg","./img/apple.jpg"
};
//商品图片地址数组
string[] goodurl = new string[3]
{
"./img/1.jpg","./img/2.jpg","./img/3.jpg"
};
//使用json转化地址字符串
Jayrock.Json.JsonTextWriter writer2 = new Jayrock.Json.JsonTextWriter();
writer2.WriteStartArray();
writer2.WriteStringArray(goodurl);
writer2.WriteEndArray();
string skuurl=writer2.ToString();
//遍历商品分类树
foreach (var child in tree)
{
if (child.ChildrenList.Count > 0)
{
//获取第一层id,便于生成三级分类
x = child.GetValue<int>("ID4Parent");
//递归调用方法
addGoodComplex(child.ChildrenList,x);
}
else
{
for (int a = 0; a <= 2; a++)
{
//记录层级中的分类id
int d3 = child.GetValue<int>("ID4Cate");
int d2 = child.GetValue<int>("ID4Parent");
int d1 = x;
string str4name = child.GetValue<string>("CateName");
//创建品牌信息表
ParamUtil pu = Aosu.Data2.Import.tb_brand.PickParamUtil<ALocalDataLoader>();
pu.DSUtil().Create<Aosu.Data2.Import.tb_brand>()
.Set_ID(brandid)
.Set_NAME(Brandname[a])
.Set_IMAGE(Brandurl[a])
.Add2Table()
.As<Aosu.Data2.Import.tb_brand>()
.Persistent<ALocalDataLoader>()
;
//根据不同品牌进行循环
for(int b = 0; b <= 2; b++)
{
Jayrock.Json.JsonTextWriter writer1 = new Jayrock.Json.JsonTextWriter();
writer1.WriteStartObject();
string[] spec_value=new string[9];
string[] idlist=new string[3];
int count_spec = 0;
//循环生成与sku相关的参数组表
for (int c = 0; c <= 2; c++)
{
ParamUtil pu4 = Aosu.Data2.Import.tb_spec_group.PickParamUtil<ALocalDataLoader>();
pu4.DSUtil().Create<Aosu.Data2.Import.tb_spec_group>()
.Set_ID(groupid)
.Set_NAME("参数组" + groupid.ToString())
.Set_CATEGORY_ID(d3)
.Add2Table()
.As<Aosu.Data2.Import.tb_spec_group>()
.Persistent<ALocalDataLoader>();
writer1.WriteMember(groupid.ToString());
idlist[c]= groupid.ToString();
string[] list = new string[3];
//循环生成与sku相关的参数名表
for (int d = 0; d <= 2; d++)
{
ParamUtil pu5 = Aosu.Data2.Import.tb_spec_param.PickParamUtil<ALocalDataLoader>();
//生成随机数用于数量属性
Random rand = new Random();
int myran = rand.Next(1, 1000);
//生成随机数用于单位属性
pu5.DSUtil().Create<Aosu.Data2.Import.tb_spec_param>()
.Set_ID(paramid)
.Set_CATEGORY_ID (d3)
.Set_GROUP_ID (groupid)
.Set_NAME("参数名" + paramid.ToString())
.Set_NUMERIC(true)
.Set_UNIT(myran)
.Set_SEARCHING(true)
.Set_GENERIC(true)
.Add2Table()
.As<Aosu.Data2.Import.tb_spec_param>()
.Persistent<ALocalDataLoader>();
list.SetValue(myran.ToString(),d);
spec_value[count_spec] = myran.ToString();
count_spec++;
paramid++;
}
writer1.WriteStringArray(list);
groupid++;
}
//生成spu特殊参数json格式字符串
writer1.WriteEndObject();
string SPECIAL_SPEC=writer1.ToString();
//使用jayrock创建json实例
Jayrock.Json.JsonTextWriter writer = new Jayrock.Json.JsonTextWriter();
writer.WriteStartObject();
//生成spu相关的参数表
for (int e = 0; e <9; e++)
{
ParamUtil pu6 = Aosu.Data2.Import.tb_spec_group.PickParamUtil<ALocalDataLoader>();
pu6.DSUtil().Create<Aosu.Data2.Import.tb_spec_group>()
.Set_ID(groupid)
.Set_NAME("参数组" + groupid.ToString())
.Set_CATEGORY_ID(d3)
.Add2Table()
.As<Aosu.Data2.Import.tb_spec_group>()
.Persistent<ALocalDataLoader>();
ParamUtil pu7 = Aosu.Data2.Import.tb_spec_param.PickParamUtil<ALocalDataLoader>();
//生成随机数用于数量属性
Random rand = new Random();
int myran = rand.Next(1, 1000);
//生成随机数用于单位属性
pu7.DSUtil().Create<Aosu.Data2.Import.tb_spec_param>()
.Set_ID(paramid)
.Set_CATEGORY_ID(d3)
.Set_GROUP_ID(groupid)
.Set_NAME("参数名" + paramid.ToString())
.Set_NUMERIC(true)
.Set_UNIT(myran)
.Set_SEARCHING(true)
.Set_GENERIC(true)
.Add2Table()
.As<Aosu.Data2.Import.tb_spec_param>()
.Persistent<ALocalDataLoader>();
writer.WriteMember(paramid.ToString());
writer.WriteString("参数名" + paramid.ToString());
groupid++;
paramid++;
}
writer.WriteEndObject();
string GENERIC_SPEC =writer.ToString();
//spu表模拟信息
ParamUtil pu2 = Aosu.Data2.Import.tb_spu.PickParamUtil<ALocalDataLoader>();
pu2.DSUtil().Create<Aosu.Data2.Import.tb_spu>()
.Set_ID(spuid)
.Set_NAME(str4name + spuid.ToString())
.Set_SUB_TITLE("满999.00另加20.00元,或满1999.00另加30.00元,或满2999.00另加40.00元,即可在购物车换购热销商品")
.Set_CID1(d1)
.Set_CID2(d2)
.Set_CID3(d3)
.Set_BRAND_ID(brandid)
.Add2Table()
.As<Aosu.Data2.Import.tb_spu>()
.Persistent<ALocalDataLoader>();
ParamUtil pu3 = Aosu.Data2.Import.tb_spu_detail.PickParamUtil<ALocalDataLoader>();
pu3.DSUtil().Create<Aosu.Data2.Import.tb_spu_detail>()
.Set_SPU_ID(detailid)
.Set_DESCRIPTION("我是一个即熟悉又不会再熟悉的人。熟悉产品的人都会说,他们都不会说我。而我的第一个产品,就是我们的国宝大熊猫。国宝大大的、黑黑的,它是用一种黑色和白色相间的药材做成的,所以它的外表很漂亮。国宝大熊猫的外形有两种:一种是我们国宝的,另一种是我们国宝的。")
.Set_GENERIC_SPEC(GENERIC_SPEC)
.Set_SPECIAL_SPEC(SPECIAL_SPEC)
.Set_AFTER_SERVICE("厂家服务本商品质保周期为1年质保,在此时间范围内可提交维修申请,具体请以厂家服务为准。 本产品提供上门安装调试、提供上门检测和维修等售后服务,自收到商品之日起,如您所购买家电商品出现质量问题,请先联系厂家进行检测,凭厂商提供的故障检测证明,在“我的京东-客户服务-返修退换货”页面提交退换申请,将有专业售后人员提供服务。京东承诺您:30天内产品出现质量问题可退货,180天内产品出现质量问题可换货,超过180天按国家三包规定享受服务。您可以查询本品牌在各地售后服务中心的联系方式,请点击这儿查询......品牌官方网站:http://www.haier.com/cn/售后服务电话:4006-999-999")
.Set_PACKING_LIST("手机 * 1,充电线*1")
.Add2Table()
.As<Aosu.Data2.Import.tb_spu_detail>()
.Persistent<ALocalDataLoader>();
int Currentid = groupid;
for(int i = 0; i <3; i++)
{
string Currentvalue1 = spec_value[i];
for (int j = 3; j < 6; j++)
{
string Currentvalue2 = spec_value[j];
for (int k = 6; k < 9; k++)
{
string Currentvalue3 = spec_value[k];
//生成ownspec
Jayrock.Json.JsonTextWriter writer4 = new Jayrock.Json.JsonTextWriter();
writer4.WriteStartObject();
writer4.WriteMember(idlist[0]);
writer4.WriteNumber(Currentvalue1);
writer4.WriteMember(idlist[1]);
writer4.WriteNumber(Currentvalue2);
writer4.WriteMember(idlist[2]);
writer4.WriteNumber(Currentvalue3);
writer4.WriteEndObject();
string OWN_SPEC=writer4.ToString();
ParamUtil pu9 = Aosu.Data2.Import.tb_sku.PickParamUtil<ALocalDataLoader>();
Random rand = new Random();
int price =rand.Next(0,10000);
Random rand1 = new Random();
int stock = rand.Next(10, 1000);
pu9.DSUtil().Create<Aosu.Data2.Import.tb_sku>()
.Set_ID(skuid)
.Set_SPU_ID(spuid)
.Set_TITLE("【腊八节好物开抢】55英寸莱茵护眼金属电视,券后到手价1199元 莱茵护眼双认证,4KHDR高清画质,远场语音,180天延保【查看音乐电视MUS-送麦克风】")
.Set_IMAGES(skuurl)
.Set_PRICE(price)
.Set_STOCK(stock)
.Set_INDEXES(SPECIAL_SPEC)
.Set_OWN_SPEC(OWN_SPEC)
.Add2Table()
.As<Aosu.Data2.Import.tb_sku>()
.Persistent<ALocalDataLoader>();
skuid++;
}
}
}
spuid++;
detailid++;
}
brandid++;
}//GetValue需要进行数据类型转换
}
}
}
#endregion
至此模拟的商品数据库生成成功