业务建模数据建模_数据建模就是一切

业务建模数据建模

每个人都知道关系数据建模,它已经为行业服务了很长时间,但是随着数据压力的增加,基于Edgar_F._Codd规则的关系数据建模无法很好地扩展。

这些规则基于1970年代的硬件限制,而RDMS数据库接管了所有这些内容,并建立了基于70年代的硬件限制的合适数据库。

我们到了2020年,时间已经改变,硬件便宜又好得多。 查看一段时间内的存储价格。

许多数据系统已经利用便宜的存储来构建高可用性和可靠的系统。 一些RDMS仍在玩追赶游戏。 我想说NoSQL通过利用这一点而处于领先地位。

当存储不是问题或瓶颈时,数据建模有很大不同,今天的限制是CPU,因为它们没有变得越来越快,您可以拥有更多但没有更快。 让我们看一下即使是您最喜欢的RDBMS也可以今天使用的一些数据建模技术,以实现快速的性能。

在进行建模之前,必须先考虑一下现实世界是关系和数据之间的关系,因此,任何无法处理1-2-1,1-2-Many或Many-2-Many等建模技术都是没有用的。 每个数据模型都需要权衡,并且有针对性地进行设计,并且可以针对特定访问模式针对写入或读取进行优化。

无限制的表扫描,连接和聚合很少使RDBMS变慢。 如果我们构建不需要这些慢速操作的数据模型,那么我们可以构建快速的系统!

RDBMS的大多数是键值存储,其顶部是B-Tree索引,如果对DB的所有查询都可以转换为键查找或小索引扫描,那么我们最好从数据库中移出。

这样一来,我们就可以深入研究一些想法,以避免加入Dataset。

使用非标量属性类型

特别是对于复杂的关系,例如客户到偏好,客户到地址,联邦快递到目的地,客户到付款选项等,我们倾向于创建具有多行的表,然后在读取时与外键联接。

如果这种类型的请求每天要向您的系统发送数百万次的时间,那么加入百万次的时间并不是一个很好的选择。 那我们该怎么办呢?

欢迎使用非标量类型的数据存储系统,使用地图,列表,向量或Blob。

我知道这听起来很疯狂,但仅通过使用上述类型,您就避免了加入并节省了上百万的CPU时间。 您还应该知道要权衡此模式,现在不再可能使用计划SQL来查看非标量列的值,但这仅是工具空白,可以解决。

此类数据模型的代码段

case class Customer(customerId: String, email: String, paymentOption: List[PaymentOption])

case class InternetBanking(bankName: String, userId: String, bankWebSite: URI) extends PaymentOption

case class CreditCard(cardType: String, issuer: String, cardNo: Long) extends PaymentOption

case class DebitCard(cardType: String, issuer: String, cardNo: Long) extends PaymentOption

case class Payla(id: String) extends PaymentOption

我的许多加入都避免了使用这种模式,并且用户体验有了很大的改善。 数据库将免费加载此列,如果数据库不支持此列,则可以在应用程序层中进行汇编。

需要注意的另一件事是,列值不应无界,设置一些限制,并在超过限制时将其分块以使您喜欢的数据库满意。

重复的不可变属性


这种模式需要更多的勇气使用。 如果您清楚地知道系统中的某些事物是不可变的,例如产品名称,说明,品牌,卖家等,那么只要产品像订购商品一样被引用,就代表所购买的商品,那么您可以将产品的所有不可变属性复制到订购商品中。

case class Product(id: Long, name: String, desc: String, brand: String, price: Double)

case class OrderItem(orderId: Long, itemId: Long, noOfUnit: Int, totalPrice: Double,
                     productName: String, productDesc: String, productBrand: String, productPrice: Double)

显示订单详细信息是电子商务网站中非常常见的访问方式,而这种解决方案类型将有助于这种访问方式。

需要权衡的是,如果属性不是不可变的,则每当引用实体发生更改时,都有更新它的开销,但是如果该属性不经常更改,则可以从中受益。

–单表或多实体表

这肯定会最有抵抗力,因为它看起来像是对RDBMS的侮辱,但我们过去曾做过这些事情,请记住那些父子查询,其中父子都存储在单个表中,并且我们将parent和id结合在一起。 多年以来,员工和经理都是以此为榜样。

让我们再举一个父母与子女关系的例子。

班级和学生也是经典的例子,班级会有很多学生,反之亦然。

每当我们想显示特定班级的所有学生的详细信息时,我们都会先查询以获取班级ID,然后再查询该班级的所有学生,或者我们可以根据班级ID加入。

我们如何避免联接或顺序加载依赖性?

当我们编写联接查询时,我们试图在运行时创建非规范化视图,并在服务请求后将其丢弃,但是如果该视图是在写时创建的,那么我们设法预联接数据,而只是避免在联接运行。

case class Registration(pk1: String, pk2: String,
                            className: String = null, classDesc: String = null, frequency: Int = 0,
                            firstName: String = null, lastName: String = null)

    Registration("class:C1", "class:C1", className = "Maths", classDesc = "Basic Algebra")
    Registration("class:C1", "student:S1", firstName = "Student1", lastName = "Student1")
    Registration("class:C1", "student:S2", firstName = "Student2", lastName = "Student2")
    Registration("class:C1", "student:S2", firstName = "Student2", lastName = "Student2")

该模型使用通用名称(pk1,pk2)来识别单个表中的实体,这看起来没什么不同,但是功能非常强大,因为有了预连接数据,我们可以获得诸如以下问题的答案

–单个类的详细信息( pk1 =“ class:c1”,pk2 =“ class:c1”
–给定班级的单个学生( pk1 =“ class:c1”,pk2 =“ student:s1” )。

–所有班级和所有学生( pk1 =” class:c1”
–给定班级的所有学生( pk1 =” class:c1”,pk2!=” class:c1”

让我们再添加一个场景以使学生可以参加所有课程。 这只需要翻转pk1和pk2就可以了

注册(“ student:s1”,“ class:C1”,className =“ science”,classDesc =“ Science for Primary kids”)

注册(“ student:s1”,“ class:C2”,className =“ Maths”,classDesc =“ Basic Algebra”)

我想说这是最不同的一种,需要开箱即用的思维进行尝试,但是您可以解决许多用例。

这是很常见的一种情况,其中投影和聚合是预先完成的,可以在写时将其视为非规范化视图。 如果聚合是线性的,如sum,avg,max,min,则聚合可以增量进行。 这样可以避免对每个请求运行“分组依据”查询。 想想通过使用这种简单模式可以节省多少CPU。

–极限投影指数

这是上述模式的扩展,它通过计算每个级别的投影将其扩展到下一个级别,对于基于层次结构的查询非常有效。 这可以帮助您完全避免读取时的分组和聚合。

结论

共享的所有模式都不是什么新鲜事物,它们正在利用廉价的存储来避免读取时的非规范化。

如果所有连接和大多数聚合都可以在写入时完成,则读取速度如此之快,以至于您可能感觉不到正在访问任何数据库。

在本文中,我们没有涉及数据分区策略,但是它在构建用户喜欢使用的系统中也起着重要作用。

是时候让您更接近您的数据,并花一些时间在设计系统之前了解访问模式和硬件限制!

翻译自: https://www.javacodegeeks.com/2020/05/data-modeling-is-everything.html

业务建模数据建模

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值