我正在研究数据库,我正在研究关系数据库的一些局限性.
我得到大桌子的连接是非常昂贵的,但我不完全确定为什么.DBMS需要做什么才能执行连接操作,瓶颈在哪里?
非规范化如何帮助克服这种费用?其他优化技术(例如索引)如何帮助?
欢迎个人经历!如果您要发布资源链接,请避免使用Wikipedia.我知道在哪里找到它.
与此相关,我想知道云服务数据库(如BigTable和SimpleDB)使用的非规范化方法.看到这个问题.
database performance join denormalization relational-database
我刚读了一篇关于微服务和PaaS架构的文章.在那篇文章中,大约三分之一的时间,作者说(在像Denzy的Denormalize下):
重构数据库模式,并对所有内容进行反规范化,以实现数据的完全分离和分区.也就是说,不要使用提供多个微服务的基础表.不应共享跨多个微服务的基础表,也不应共享数据.相反,如果多个服务需要访问相同的数据,则应通过服务API(例如已发布的REST或消息服务接口)共享它.
虽然这在理论上听起来很棒,但在实践中它还有一些需要克服的严重障碍.其中最大的一点是,数据库经常紧密耦合,每个表与至少一个其他表有一些外键关系.因此它可能是不可能的分区的数据库进Ñ通过控制子数据库Ñ微服务.
所以我要问:给定一个完全由相关表组成的数据库,如何将其归一化为较小的片段(表组),以便片段可以由单独的微服务控制?
例如,给定以下(相当小但是示例性)数据库:
[users] table
=============
user_id
user_first_name
user_last_name
user_email
[products] table
================
product_id
product_name
product_description
product_unit_price
[orders] table
==============
order_id
order_datetime
user_id
[products_x_orders] table (for line items in the order)
=======================================================
products_x_orders_id
product_id
order_id
quantity_ordered
Run Code Online (Sandbox Code Playgroud)
不要花太多时间批评我的设计,我在飞行中做了这个.关键是,对我来说,将这个数据库分成3个微服务是合乎逻辑的:
UserService - 用于系统中的CRUDding用户; 应该最终管理[users]桌子; 和ProductService - 用于系统中的CRUDding产品; 应该最终管理[products]桌子; 和OrderService - 用于系统中的CRUDding订单; 应该最终管理[orders]和[products_x_orders]表但是,所有这些表都具有彼此的外键关系.如果我们将它们归一化并将它们视为整体,它们就会失去所有的语义:
[users] table
=============
user_id
user_first_name …Run Code Online (Sandbox Code Playgroud) 我听到很多关于非规范化的内容,这是为了提高某些应用程序的性能.但我从未试图做任何相关的事情.
所以,我只是好奇,归一化数据库中的哪些位置会使性能变差,换句话说,什么是非规范化原则?
如果我需要提高性能,我该如何使用这种技术?
database performance database-design normalization denormalization
我知道在Stack Overflow上已经广泛讨论了normalis(z)ation.我读过很多以前的讨论.我有一些额外的问题.
我正在研究一个至少有100个表的遗留系统.数据库具有一些非规范化结构,包含各种不同数据的表以及其他问题.我被赋予了改善它的任务.我不能再重新开始,但需要修改现有架构.
在过去,我一直试图设计规范化的数据库.现在的问题.一位高级开发人员建议在某些情况下我们无法规范化:
1)使用时态数据.例如,创建了一个链接到产品的发票.如果客户在一年后要求提供此发票的副本,我们必须能够生成原件的精确副本.如果产品价格,名称或描述已更新怎么办?资深人士建议将价格和其他产品信息复制到发票表中.我想也许我们应该有另一个表,例如productPrice,它有一个日期字段,所以我们可以跟踪价格随时间的变化.我想对产品描述和名称需要相同的东西吗?看似复杂.你怎么看?
2)数据库是一个会计系统.我对会计不是很熟悉.目前,一些摘要数据被导出并存储在数据库中.例如,当年的总销售额.我的高级助理表示,会计师喜欢通过将此值与实际根据发票等计算的数据进行比较来检查事情是否正确,以使他们相信应用程序正常工作.他说,目前我们可以判断是否有人错误地从去年删除了发票,因为总数不会相同.他还指出,在飞行中计算这些总数可能会非常缓慢.当然,我说数据不应该重复,应该在需要时进行计算.我建议我们可以使用SQL Reporting Services或其他一些解决方案来隔夜生成这些报告并缓存它们.无论如何,他不相信.对此有何评论?
非常感谢:)
干杯
马克
感谢您的出色回应.遗憾的是我只能将其中一个作为答案,因为这里有很多好的建议.
归一化导致许多基本和理想的特征,包括审美愉悦.此外,它在理论上也是"正确的".在这种情况下,非规范化被用作折衷方案,用于实现性能的校正.除了性能之外,还有其他任何理由可以对数据库进行非规范化吗?
我想做一个数据非规范化以获得更好的性能,并在Post模型中收到我的博客帖子收到的一些投票:
class Post(models.Model):
""" Blog entry """
author = models.ForeignKey(User)
title = models.CharField(max_length=255)
text = models.TextField()
rating = models.IntegerField(default=0) # here is the sum of votes!
class Vote(models.Model):
""" Vote for blog entry """
post = models.ForeignKey(Post)
voter = models.ForeignKey(User)
value = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)
当然,我需要保持Post.rating实际价值.Nornally我会使用数据库触发器,但现在我决定发出一个post_save信号(减少数据库处理时间):
# vote was saved
@receiver(post_save, sender=Vote)
def update_post_votes(sender, instance, created, **kwargs):
""" Update post rating """
if created:
instance.post.rating += instance.value
instance.post.save()
else:
# if vote was updated, we need to remove …Run Code Online (Sandbox Code Playgroud) 我有一个规范化订单数据的大型数据库,查询报告变得非常慢.我在报告中使用的许多查询都会连接五到六个表,并且必须检查数十或数十万行.
有很多查询,大多数都已尽可能优化,以减少服务器负载和提高速度.我认为是时候开始以非规范化格式保存数据副本了.
关于方法的任何想法?我应该从几个最糟糕的问题开始,然后从那里开始?
如何将矢量标准化为范围[-1;1]
我想使用函数norm,因为它会更快.
还让我知道如何在归一化后对该向量进行非规范化?
我们正在为即将到来的项目评估NoSQL.我倾向于以RDBMS的方式思考问题,并且难以概念化缺乏规范化.
我知道在NoSQL中重复数据不算错误.我无法理解的是修复数据更改以防止出现异常.
问题解释示例:
您正在组织一系列扑克锦标赛.您有球员,位置和锦标赛事件.据我了解,锦标赛活动可能包含一个位置和一组球员.它不需要拥有所有玩家数据,但如果你想获得每个人参加下一场锦标赛的名字和家庭住址,那么这些信息应该在锦标赛中.
有人已经结婚并搬家,改变他们的姓氏和地址.应用程序是否需要更新播放器集合和锦标赛集合?或者我的收藏模型错了吗?开发人员如何"跟踪"信息重复的位置?
使用MongoDB时,引用数据的非规范化似乎是一种非常常见的做法.然而,我没有看到使用Doctrine MongoDB ODM处理它的任何内置方法.
假设我有一个社交网络,用户可以互相关注,这里有两个示例用户:
{
_id : id1,
name: "Malcolm Reynolds",
followed: []
}
{
_id : id2,
name: "Zoe Alleyne",
followed: [
{ _id: id1, name: "Malcolm Reynolds" }
]
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我希望'name'属性被非规范化.正如我所说,Doctrine ODM似乎没有内置的方法来做到这一点.由于关于这个问题的最新一期是一年,我会尝试自己做.
虽然我在互联网上发现了很多文章,解释了非规范化在什么情况下是有用的,并提到如何保持非规范化数据的一致性,但我没有找到解释如何实现真正的数据更新过程.
在我的情况下,最终一致的数据就足够了,用户名更新和非规范化数据更新之间可能会有几个小时.我可以看到3种不同的方法:
1 - 一致性检查程序:让 后台运行的任务定期更新非规范化数据.
2 - 更新触发器: 名称字段上的每次更新都会在单次刷新中更新所有关联的非规范化数据.
3 - 混合解决方案 对于每个用户,当更新名称时,会将一个条目添加到具有更新信息的队列中(用户更新和队列中的插入将在单个刷新中进行),并且运行任务后台做了实际的更新.
第一个解决方案似乎是最容易实现的,但正如我所看到的那样,它可能非常耗费资源.第二种解决方案会使更新请求变得非常长,即使读/写比率很高,我也可能会遇到这个问题.我认为第三种解决方案是要走的路,我这样认为是对的吗?
另外,我想以干燥的方式进行,例如,我希望不必在preUpdate回调中为每个数据非规范化的Document重写相同的代码.我正在考虑制作自定义注释,这是一个好主意吗?
denormalization ×10
database ×5
performance ×2
django ×1
doctrine-odm ×1
join ×1
matlab ×1
mongodb ×1
mysql ×1
nosql ×1
postgresql ×1
python ×1
sql ×1