前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >数据库-库表设计 【分享一些库表设计经验】

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

作者头像
全栈程序员站长
发布于 2022-09-06 03:07:30
发布于 2022-09-06 03:07:30
1.8K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

本文的核心内容:记录积累一些库表设计方案与技巧

数据库实体与实体间的对应关系

1)数据库表的菜单【分类】设计:如省市关联、图书的一、二级分类。

2)数据库表设计之树形结构的表

3)表的简化方案(特定情况,例如,用户触发过的场景记录表)

4)数据库表设计之购物车,利用Session暂时存储购物车信息。


实体与实体间的对应关系

一对一

一对一,一般用于对主表的补充。假设A表为用户信息表,存储了用户的姓名、性别、年龄等基本信息。用户的家庭住址信息也属于用户的基本信息。我们可以选择将用户的家庭住址信息放到用户信息表,也可以单独建一张表,存储用户的家庭住址信息,以用户信息表的主键作为关联。

需不需要拆分取决:表信息的关联程度、表的字段个数限度。

一对多

一对多,是最常见的一种设计。就是 A 表的一条记录,对应 B 表的多条记录,且 A 的主键作为 B 表的外键。举几个 例子:

    1. 班级表 与 学生表,一个班级对应多个学生,或者多个学生对应一个班级。
    2. 角色表 与 用户表,一个角色对应多个用户,或者多个用户对应一个角色。
    1. 商品表 与 图片表,一个商品对应多张图片,或者多张图片对应一个商品。

多对多

构建一张关系表将两张表进行关联,形成多对多的形式。例如:

    1. 老师表、学生表;一个学生可以选修多个老师的课程、同时一个老师也可以教多个学生。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--教师表

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 指一级图书包含二级图书的个数

二级分类所包含详细图书的个数

数据库查询一级分类信息的SQL

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select typeid,typename,parentid,countnumber 
from t_booktype   where parentid='0'

数据查询二级分类信息(利用表的自连接)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select  child.typeid,child.typename,
child.parentid,child.countnumber 		
from t_booktype child ,t_booktype  parent 
where child.parentid=parent.typeid

二:MySQL 表中存储树形结构数据

由上面设计技巧引出,如果数据层级有多级呢?简言之就像一棵树一样,我们如何存储树形的数据到数据库。

存储父节点

存储于数据库中,最简单直接的方法,就是存储每个元素的父节点ID,即parent_Id->父节点Id。这种方式方便了插入,但是在某些情况下的查询会束手无策。我们可以增加两个字段(deep,is_leaf)帮助我们更快的查询。

deep=1表示父节点,deep>1 表示子节点。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
id
parent_id
deep     //当前树的深度
is_leaf  //是否叶子节点

查询所有父节点deSQL如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select * from tree where deep=1

查询某个父节点下的所有子节点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select * from tree where parent_id="" 

查询某个父节点下的所有后代节点,采用这种库表设计方式,这个需要依靠程序才能实现。

存储路径

将存储根结点到每个节点的路径,这种数据结构,可以一眼就看出子节点的深度。要插入自己,然后查出父节点的Path,并且把自己生成的ID更新到path中去。

如果要查询某个节点下的子节点,只需要根据path的路径去匹配,比如要查询D节点下的所有子节点。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select * from tree where path like '1/4/%'

总结

我建议存储树形结构可以将两者结合起来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
id
parent_id
deep     //当前树的深度
path     //根路径
is_leaf  //是否叶子节点

三:MySQL 表的简化(特定情况,例如:用户触发过的场景记录表)

假设业务中有N多道具,比如用户首次使用某个道具触发特效。根据表里有没有用户相关的道具触发记录来完成判断。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
id
user_id //用户Id
item_id //道具ID
flag    //是否触发过特效 0-1
add_time
update_time

毫无疑问,上述表结构是能够满足并实现我们需求的,但是如果有20种道具,那么每个用户最终将有20条数据,数据冗余,如何简化?

解决方案:

定义道具枚举值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public enum ItemOnceFlagEnum {
    
    NONE(0),
    
    ITEM_ONE(1),//道具1
    
    ITEM_TWO(1 << 1), //道具2
    
    ITEM_Three(1 << 2), //道具3
    
    ;
    
    private int code;
    
    ItemOnceFlagEnum(int code) {
        this.code = code;
    }
    public int getCode() {
        return code;
    }
    
    public static ItemOnceFlagEnum valueOf(int code) {
        ItemOnceFlagEnum[] values = ItemOnceFlagEnum.values();
        for (ItemOnceFlagEnum flag : values) {
            if (flag.getCode() == code) {
                return flag;
            }
        }
        return NONE;
    }
}

建表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
id
user_id //用户Id
flag    //是否触发过特效 2的0次幂、2的1次幂。。。
add_time
update_time

user_id设置为唯一索引

判断是否使用过某道具与添加道具使用记录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    //判断是否使用过某项道具
    public static boolean isHasThisFlag(long flag, ItemOnceFlagEnum itemOnceFlagEnum) {
        return (flag & itemOnceFlagEnum.getCode()) > 0;
    }

    //添加道具使用记录
    public Result<Boolean> addOnceFlag(long userId, itemOnceFlagEnum flag) {
         ItemOnceFlagDO itemOnceFlagDO = itmeOnceFlagService.getOnceFlagMap(Collections.singletonList(userId));
         long calculateFlag = (Objects.isNull(blockOnceFlagDO) ? 0L : itemOnceFlagDO.getFlag()) | flag.getCode();
         itemOnceFlag.setFlag(calculateFlag);
         boolean res = itemOnceFlagService.addOrUpdateOnceFlag(itemOnceFlag);
    }

添加记录SQL

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"INSERT INTO xxxx ( ) VALUES ( :1.userId,  :1.flag ) " +
            " ON DUPLICATE KEY UPDATE flag = :1.flag "

某一项道具为具体2次幂值(仅能够维护2种状态,有或无),flag代表所有触发道具2次幂和。

通过 (flag & itemOnceFlagEnum.getCode())>0 判断是否有某项道具

通过 flag | temOnceFlagEnum.getCode(); 添加道具记录


四:购物车模块的库表设计

在电商软件,必不可少的模块就是购物车。

我分享两种设计方法:

①:维护一张购物车表,以用户ID为外键

一个用户一个购物车,用户注册成功的同时,为用户在购物车表内维护一个专属于用户的购物车。(根据我以前学到的知识,这一步可以为用户表创建Insert触发法器,当用户注册成功[触发器将用户ID作为外键插入购物车表],用户即拥有了唯一的购物车)

T_Car

字段

类型

说明

Car_ID

Varchar2(36)

购物车编号 主键

User_ID

Varchar2(36)

外键 用户唯一标识

Car_Status

Varchar2(4)

购物车状态

T_Shop_Item

字段

类型

说明

Shop_item_ID

Varchar2(36)

购物项编号 主键

Car_ID

Varchar2(36)

购物车编号 外键

Product_ID

Varchar2(36)

商品编号 外键

Count

Number(4)

数量

Price

number(8,2)

价格

ProductName

Varchar(30)

商品名

这么实现购物车的弊端:①:非该网站的注册用户无法将商品加入购物车。这与现实的情况不符合。一般我们访问某宝,某东,我们可以以游客的方式将商品加入购物车,直到下订单、付款时才要求我们必须登录。②:每个用户维护一下购物车似乎不太明智,顾客将商品加入购物车到下订单,完成交易,这一需求对数据库更改频繁。

②:所有用户共用一个”购物车”

我们可以直接以用户ID为标识,区分购物车商品所属的用户。

T_Shop_Item

字段

类型

说明

Shop_item_ID

Varchar2(36)

购物项编号 主键

User_ID

Varchar2(36)

用户编号 外键

ProductID

Varchar2(36)

商品编号 外键

Count

Number(4)

数量

Price

number(8,2)

价格

ProductName

Varchar(30)

商品名

即使减少了一张购物车表,但是这表还需要用户登录才能记录用户添加商品情况。

③:利用Session暂时存储购物车内的东西

[用户不登录就能添加商品到购物车;用户登录状态将Session中的信息存入非关系型数据库、关系型数据库。将购物车内的东西持久化存储]

明确一点:Session -> 一次会话有效(在用户不关闭浏览器的前提下,默认存在30分钟;用户关闭浏览器再次打开后,未登录用户的购物车将清空。)

解决如何用Session存储购物车内信息。

第一个难点:那么如何准确区分不同的商品? (自然是商品ID)

第二个难点:那么如何准确标记一个进入购物车的商品? (只有商品ID是不行的)

商品ID,通过商品ID,我们可以查询到商品详情。(价格、名称等等)

同一商品的购买数量。这一信息是不存在于商品详情的。【重点,不能忽略】

这两个信息必须存储。于是我想到Map(两个原因)。

①:存储两个值

Map<String,Integer> map=new HashMap<String,Integer>();

key存储 商品ID, value存储 商品数量(购买数量)

②:保证商品ID(键)的唯一性

Map的特点:键唯一,值可以重复。我们以商品ID为键,这样就可以保证商品的唯一性。

我们再将map存入Session中就可以了。

当用户添加商品时,只需先从Session中取出map,迭代遍历判断key是否已经存在,若存在取value值加1;若不存在则将商品ID作为key,value数量默认为1,Put进map。

当用户(未登录)查看购物车时,只需从Session中取商品ID和数量,就可以显示购车内商品的详细信息,计算购物车内的商品总价格。

这种存储方式简化了添加商品进入购物车和删除购物车里商品的操作。但是却不得不再次封装一个Map对象将购物车详情页面的信息存储进去,以供购物车展示页面显示数据。

(这是我第一次考虑的存储方案,写到查看购物车详情页面才发现不合理之处。)

改进版本:

Map <String,Goods> map=new HashMap<String,Goods> ();

Key ->商品id

Value->购物车页面需要展示的商品详情(商品名、商品ID、商品数量、商品价格等)

核心:value值维护不再是一个商品数量,而是我们封装的模拟购物车实体对象

JSP页面的效果图

源代码:添加商品的Action

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//添加商品Action
	public String addToCar() throws Exception{
		//尝试从Session取出购物车
		ValueStack vs=ActionContext.getContext().getValueStack();
		Map<String,Goods> car=(Map<String,Goods>)vs.findValue("#session.car");
		
		BookService service=new BookServiceImpl();
		
		if(car==null){	
			//判断购物车是否存在
			//不存在则创建,将用户添加的商品加入Map 存入Session
			Map<String,Goods> map=new HashMap<String,Goods>();
			//查询数据将商品详情查询出出来,把我们感兴趣的属性封装到Goods实体中
			Book book=service.getSingleBook(bookid);
			Goods goods=new Goods();
			goods.setBookid(book.getBookid());
			goods.setCount(1);
			goods.setPrice(book.getPrice());
			goods.setCurrentprice(book.getCurrentprice());
			goods.setProductname(book.getProductname());
			
			map.put(bookid, goods);
			vs.setValue("#session.car", map);
		}else{		
			//判断用户添加的商品是否已经存在于购物车里
			//若存在根据key取出Goods->修改商品选购的数量
			//不存在则是首次添加,数量默认为1 ,将商品Put入map
			if(car.containsKey(bookid)){
				Goods product=car.get(bookid);
				product.setCount(product.getCount()+1);
			}else{			
				Book book=service.getSingleBook(bookid);
				Goods goods=new Goods();
				goods.setBookid(book.getBookid());
				goods.setCount(1);
				goods.setPrice(book.getPrice());
				goods.setCurrentprice(book.getCurrentprice());
				goods.setProductname(book.getProductname());				
				car.put(bookid, goods);
			}
		}	
		return Action.SUCCESS;
	}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/151591.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
回头试试看
回头试试看
回复回复点赞举报
推荐阅读
pyecharts︱交互式pyecharts的相关使用教程
pyecharts 是一个用于生成 Echarts 图表的类库。Echarts 是百度开源的一个数据可视化 JS 库。用 Echarts 生成的图可视化效果非常棒,为了与 Python 进行对接,方便在 Python 中直接使用数据生成图。以下是最新版echart的靓图。当然,pyecharts貌似没有这么齐全。
悟乙己
2022/05/09
3.2K0
pyecharts︱交互式pyecharts的相关使用教程
教你用pyecharts制作交互式桑基图,赶快学起来吧!
由于工作的需要,经常需要进行可视化展示,除了一些常用的BI工具,我也会使用python对数据进行可视化。
派大星的数据屋
2022/04/02
3.4K1
教你用pyecharts制作交互式桑基图,赶快学起来吧!
pyecharts(一):Python可视化利器
專 欄 ❈陈键冬,Python中文社区专栏作者 GitHub: https://github.com/chenjiandongx ❈ pyecharts 是一个用于生成 Echarts 图表的类库。
Python中文社区
2018/01/31
2.4K0
pyecharts(一):Python可视化利器
pyecharts 安装及使用指南
Charts是一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器,底层依赖轻量级的Canvas类库ZRender,提供直观、生动、可交互、可高度个性化定制的数据可视化图表。ECharts提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap,多维数据可视化的平行坐标,还有用于BI的漏斗图、仪表盘,并且支持图与图之间的混搭。
py3study
2020/11/12
2.6K0
pyecharts 安装及使用指南
Pyecharts绘图API总结
pyecharts 是一个用于生成 Echarts 图表的类库, Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,pyecharts 诞生了。
前端皮皮
2021/12/02
1.6K0
Pyecharts绘图API总结
[710]python使用pyecharts绘制地图
pyecharts 是一个用于生成 Echarts 图表的类库。Echarts 是百度开源的一个数据可视化 JS 库。用 Echarts 生成的图可视化效果非常棒,pyecharts 是为了与 Python 进行对接,方便在 Python 中直接使用数据生成图。
周小董
2020/01/13
3.8K0
[710]python使用pyecharts绘制地图
软件测试|Python数据可视化神器——pyecharts教程(一)
我们都知道百度开源了一个Echarts数据可视化库,支持绘制各种主流的图表。Python在数据分析方面是十分强大的,于是,pyecharts就应运而生了。
霍格沃兹测试开发Muller老师
2023/02/19
8390
Python 数据可视化神器分享:pyecharts
我们都知道python上的一款可视化工具matplotlib,而前些阵子做一个Spark项目的时候用到了百度开源的一个可视化JS工具-Echarts,可视化类型非常多,但是得通过导入js库在Java Web项目上运行。
公众号---人生代码
2019/09/17
8580
Python 数据可视化神器分享:pyecharts
Pyechart入门
pyecharts是一个用于生成echarts图表的类库。echarts是百度开源的一个数据可视化库,用echarts生成的图可视化效果非常棒。使用pyechart库可以在python中生成echarts数据图。 官网:http://pyecharts.org Github:https://github.com/pyecharts/pyecharts/ 在官网中可以获得比本文更详细的pyecharts库的使用方法。 下面代码的开发环境为jupyter notebook,使用在jupyter notebook中的截图表示运行结果。
潇洒坤
2018/09/10
2.6K0
Pyechart入门
python-pyecharts 数据分析原来可以这么炫酷
Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,pyecharts 诞生了。
大家一起学编程
2021/12/13
9090
python-pyecharts 数据分析原来可以这么炫酷
pyEcharts安装及详细使用指南
ECharts是一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器,底层依赖轻量级的Canvas类库ZRender,提供直观、生动、可交互、可高度个性化定制的数据可视化图表。ECharts提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap,多维数据可视化的平行坐标,还有用于BI的漏斗图、仪表盘,并且支持图与图之间的混搭。
Lansonli
2021/10/09
1.1K0
数据科学篇| pyecharts库的使用(五)
pyecharts 是一个用于生成 Echarts 图表的类库。Echarts 是百度开源的一个数据可视化 JS 库。本文将为你阐述pyecharts的使用细则。
润森
2019/08/29
1.5K0
数据科学篇| pyecharts库的使用(五)
更高级的数据可视化,使用pyecharts制作精美图表
提到用python进行数据可视化,那么大多数人选择都是matplotlib,但是生成的图表不能进行交互操作,比如时间轴拖动、交互式图例等,那么本文将对pyecharts进行详细讲解。
刘早起
2020/04/22
2K0
更高级的数据可视化,使用pyecharts制作精美图表
pyecharts-1-入门
前段时间写了很多关于plotly_express库的内容,从基本的一行代码出各种图,到每个类型图的绘制,再到图形的绘制技巧,内容还是非常的丰富,plotly_express可以说是自己目前见过最棒的库,主要是体现在3点:
皮大大
2021/03/01
1.2K0
pyecharts-1-入门
Python 数据可视化神器—Pyecharts
Echarts 是百度开源的一款数据可视化 JS 工具,数据可视化类型十分丰富,但是得通过导入 js 库在 Java Web 项目上运行。
Wu_Candy
2022/07/04
6360
Python 数据可视化神器—Pyecharts
盘点Pyecharts V1和V0.5之间的切换方法
Pyecharts这个可视化库火爆,关于它,官方如是说:Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,pyecharts 诞生了。
Python进阶者
2022/03/10
3760
盘点Pyecharts V1和V0.5之间的切换方法
还在用matplotlib画图?你out啦
进行数据处理的时候,可视化是非常重要的数据分析方式,但是有时候在处理大批量的数据时,由于数据量过多,数据往往会非常密集,而不能发现有效信息,而我们经常使用的matplotlib不能满足这样的需求,这就需要交互式的可视化方案,提供比较方便和快捷的数据可视化操作。前几天在处理数据的时候,需要实现数据可以滑动或者选择查看,就发现了几个python实现交互式可视化的库,跟大家分享一下。 首先简单介绍一下python的可视化的分类。在Python语言环境里,有不少可视化解决方案,主要的可以大致分为几类:
MeteoAI
2019/07/24
2.2K0
Python可视化神器——pyecharts的超详细使用指南!
pyecharts是一款将python与echarts结合的强大的数据可视化工具,本文将为你阐述pyecharts的使用细则
昱良
2019/03/07
2K0
数据可视化之pyecharts
Echats是百度开源的一个数据可视化js库,主要用于数据可视化,pyecharts 是一个用于生成Echarts图标的类库,实际上就是Echarts和Python的对接。
py3study
2020/01/19
3K0
Pyecharts入门
Apache ECharts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,pyecharts 诞生了;PyEcharts是Echarts的Python接口, Pyecharts = Python + Echarts
@小森
2024/06/28
2920
Pyecharts入门
推荐阅读
相关推荐
pyecharts︱交互式pyecharts的相关使用教程
更多 >
LV.3
河北工业职业技术大学讲师
目录
  • 实体与实体间的对应关系
  • 一:数据库表的菜单【分类】设计:如省市关联、图书的一、二级分类
  • 二:MySQL 表中存储树形结构数据
  • 三:MySQL 表的简化(特定情况,例如:用户触发过的场景记录表)
  • 四:购物车模块的库表设计
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档