数据库-库表设计【分享一些库表设计经验】

数据库-库表设计【分享一些库表设计经验】

2023年7月27日发(作者:)

数据库-库表设计【分享⼀些库表设计经验】本⽂的核⼼内容:记录积累⼀些库表设计⽅案与技巧1)数据库实体与实体间的对应关系2)数据库表的菜单【分类】设计:如省市关联、图书的⼀、⼆级分类。3)数据库表设计之树形结构的表4)数据库表设计之购物车,利⽤Session暂时存储购物车信息。实体与实体间的对应关系⼀对⼀⼀对⼀,⼀般⽤于对主表的补充。假设A表为⽤户信息表,存储了⽤户的姓名、性别、年龄等基本信息。⽤户的家庭住址信息也属于⽤户的基本信息。我们可以选择将⽤户的家庭住址信息放到⽤户信息表,也可以单独建⼀张表,存储⽤户的家庭住址信息,以⽤户信息表的主键作为关联。需不需要拆分取决:表信息的关联程度、表的字段个数限度。⼀对多⼀对多,是最常见的⼀种设计。就是 A 表的⼀条记录,对应 B 表的多条记录,且 A 的主键作为 B 表的外键。举⼏个 例⼦:1.

1. 班级表 与 学⽣表,⼀个班级对应多个学⽣,或者多个学⽣对应⼀个班级。2. ⾓⾊表 与 ⽤户表,⼀个⾓⾊对应多个⽤户,或者多个⽤户对应⼀个⾓⾊。1.

1. 商品表 与 图⽚表,⼀个商品对应多张图⽚,或者多张图⽚对应⼀个商品。多对多构建⼀张关系表将两张表进⾏关联,形成多对多的形式。例如:1.

1. ⽼师表、学⽣表;⼀个学⽣可以选修多个⽼师的课程、同时⼀个⽼师也可以教多个学⽣。--教师表CREATE TABLE #Teacher(TeacherId int, Name nvarchar(20));INSERT INTO #Teacher VALUES(1, '张⽼师'), (2, '王⽼师');--学⽣表CREATE TABLE #Student(StudentId int, Name nvarchar(20));INSERT INTO #Student VALUES(1, '⼩张'), (2, '⼩赵');--⽼师学⽣关系表CREATE TABLE #Teacher_Student(StudentId int, TeacherId int);INSERT INTO #Teacher_Student VALUES(1, 1), (1, 2),(2, 1), (2, 2);⼀:数据库表的菜单【分类】设计:如省市关联、图书的⼀、⼆级分类BookType ⼀级分类: 少⼉、外语、计算机BookClass ⼆级分类: 少⼉[0-2岁、3-6岁、7-10岁、11-14岁、⼉童⽂学] 外语[英语、⽇语、韩语、俄语、德语] 计算机[计算机理论、计算机考试、数据库、⼈⼯智能、程序设计]BookInf 图书详情 : 图书信息的详细字段。。。基于以上关系:我们建表有两种⽅法①:建⽴三张表 ⼀级分类表,⼆级分类表、图书详情表⼀级分类ID->作为⼆级分类的外键⼆级分类ID->作为图书详情的外键这⼀种依赖外键,实体模型也⽐较简单。(不再过多描述)查询语句:可以采⽤ left join on 或者 等值连接 将⼆级分类的外键与⼀级分类的主键等值连接即可查询。②:建⽴两张表 ⼀级分类和⼆级分类合并成⼀张表 图书详情表(引⽤TypeID为外键)

TypeID 指⼀级⼆级分类的ID(唯⼀标识、主键) 序列⾃增从1开始。TypeName 指⼀级⼆级分类的名字ParentID 指⼆级分类所属⼀级分类TypeID (若为⼀级分类则填”0”与⼆级分类加以区分)countNumber 指⼀级图书包含⼆级图书的个数 ⼆级分类所包含详细图书的个数 数据库查询⼀级分类信息的SQLselect typeid,typename,parentid,countnumber

from t_booktype where parentid='0'数据查询⼆级分类信息(利⽤表的⾃连接)select ,me,id,umber

from t_booktype child ,t_booktype parent

where id=⼆:MySQL 表中存储树形结构数据由上⾯设计技巧引出,如果数据层级有多级呢?简⾔之就像⼀棵树⼀样,我们如何存储树形的数据到数据库。存储⽗节点存储于数据库中,最简单直接的⽅法,就是存储每个元素的⽗节点ID,即parent_Id->⽗节点Id。这种⽅式⽅便了插⼊,但是在某些情况下的查询会束⼿⽆策。我们可以增加两个字段(deep,is_leaf)帮助我们更快的查询。deep=1表⽰⽗节点,deep>1 表⽰⼦节点。idparent_iddeep //当前树的深度is_leaf //是否叶⼦节点查询所有⽗节点deSQL如下:select * from tree where deep=1查询某个⽗节点下的所有⼦节点:select * from tree where parent_id=""

查询某个⽗节点下的所有后代节点,采⽤这种库表设计⽅式,这个需要依靠程序才能实现。存储路径将存储根结点到每个节点的路径,这种数据结构,可以⼀眼就看出⼦节点的深度。要插⼊⾃⼰,然后查出⽗节点的Path,并且把⾃⼰⽣成的ID更新到path中去。如果要查询某个节点下的⼦节点,只需要根据path的路径去匹配,⽐如要查询D节点下的所有⼦节点。select * from tree where path like '1/4/%'总结我建议存储树形结构可以将两者结合起来。idparent_iddeep //当前树的深度path //根路径is_leaf //是否叶⼦节点三:购物车模块的库表设计在电商软件,必不可少的模块就是购物车。我分享两种设计⽅法:①:维护⼀张购物车表,以⽤户ID为外键⼀个⽤户⼀个购物车,⽤户注册成功的同时,为⽤户在购物车表内维护⼀个专属于⽤户的购物车。(根据我以前学到的知识,这⼀步可以为⽤户表创建Insert触发法器,当⽤户注册成功[触发器将⽤户ID作为外键插⼊购物车表],⽤户即拥有了唯⼀的购物车)T_Car字段Car_IDUser_IDCar_Status类型Varchar2(36)Varchar2(36)Varchar2(4)说明购物车编号 主键外键 ⽤户唯⼀标识购物车状态T_Shop_Item字段Shop_item_IDCar_IDProduct_IDCountPriceProductName类型Varchar2(36)Varchar2(36)Varchar2(36)Number(4)number(8,2)Varchar(30)说明购物项编号 主键购物车编号 外键商品编号 外键数量价格商品名这么实现购物车的弊端:①:⾮该⽹站的注册⽤户⽆法将商品加⼊购物车。这与现实的情况不符合。⼀般我们访问某宝,某东,我们可以以游客的⽅式将商品加⼊购物车,直到下订单、付款时才要求我们必须登录。②:每个⽤户维护⼀下购物车似乎不太明智,顾客将商品加⼊购物车到下订单,完成交易,这⼀需求对数据库更改频繁。②:所有⽤户共⽤⼀个”购物车”我们可以直接以⽤户ID为标识,区分购物车商品所属的⽤户。T_Shop_Item字段Shop_item_IDUser_IDProductID类型Varchar2(36)Varchar2(36)Varchar2(36)说明购物项编号 主键⽤户编号 外键商品编号 外键CountPriceProductNameNumber(4)number(8,2)Varchar(30)数量价格商品名即使减少了⼀张购物车表,但是这表还需要⽤户登录才能记录⽤户添加商品情况。③:利⽤Session暂时存储购物车内的东西[⽤户不登录就能添加商品到购物车;⽤户登录状态将Session中的信息存⼊⾮关系型数据库、关系型数据库。将购物车内的东西持久化存储]明确⼀点:Session -> ⼀次会话有效(在⽤户不关闭浏览器的前提下,默认存在30分钟;⽤户关闭浏览器再次打开后,未登录⽤户的购物车将清空。)解决如何⽤Session存储购物车内信息。第⼀个难点:那么如何准确区分不同的商品? (⾃然是商品ID)第⼆个难点:那么如何准确标记⼀个进⼊购物车的商品? (只有商品ID是不⾏的)商品ID,通过商品ID,我们可以查询到商品详情。(价格、名称等等)同⼀商品的购买数量。这⼀信息是不存在于商品详情的。【重点,不能忽略】这两个信息必须存储。于是我想到Map(两个原因)。①:存储两个值Map map=new HashMap();key存储 商品ID, value存储 商品数量(购买数量)②:保证商品ID(键)的唯⼀性Map的特点:键唯⼀,值可以重复。我们以商品ID为键,这样就可以保证商品的唯⼀性。我们再将map存⼊Session中就可以了。当⽤户添加商品时,只需先从Session中取出map,迭代遍历判断key是否已经存在,若存在取value值加1;若不存在则将商品ID作为key,value数量默认为1,Put进map。当⽤户(未登录)查看购物车时,只需从Session中取商品ID和数量,就可以显⽰购车内商品的详细信息,计算购物车内的商品总价格。这种存储⽅式简化了添加商品进⼊购物车和删除购物车⾥商品的操作。但是却不得不再次封装⼀个Map对象将购物车详情页⾯的信息存储进去,以供购物车展⽰页⾯显⽰数据。(这是我第⼀次考虑的存储⽅案,写到查看购物车详情页⾯才发现不合理之处。)改进版本:Map map=new HashMap ();Key ->商品idValue->购物车页⾯需要展⽰的商品详情(商品名、商品ID、商品数量、商品价格等)核⼼:value值维护不再是⼀个商品数量,⽽是我们封装的模拟购物车实体对象JSP页⾯的效果图源代码:添加商品的Action //添加商品Action public String addToCar() throws Exception{ //尝试从Session取出购物车 ValueStack vs=text().getValueStack(); Map car=(Map)lue("#");

BookService service=new BookServiceImpl();

if(car==null){

//判断购物车是否存在 //不存在则创建,将⽤户添加的商品加⼊Map 存⼊Session Map map=new HashMap(); //查询数据将商品详情查询出出来,把我们感兴趣的属性封装到Goods实体中 Book book=gleBook(bookid); Goods goods=new Goods(); kid(kid()); nt(1); ce(ce()); rentprice(rentprice()); ductname(ductname());

(bookid, goods); ue("#", map); }else{

//判断⽤户添加的商品是否已经存在于购物车⾥ //若存在根据key取出Goods->修改商品选购的数量 //不存在则是⾸次添加,数量默认为1 ,将商品Put⼊map if(nsKey(bookid)){ Goods product=(bookid); nt(nt()+1); }else{

Book book=gleBook(bookid); Goods goods=new Goods(); kid(kid()); nt(1); ce(ce()); rentprice(rentprice()); ductname(ductname());

(bookid, goods); } }

return S; }

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1690436297a349510.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信