教义:跟踪缓慢变化的维度的历史 [英] Doctrine: tracking history of slowly changing dimensions

查看:83
本文介绍了教义:跟踪缓慢变化的维度的历史的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Symfony3 / Doctrine开发一种网络商店。为了简化事情,假设我有一个表修复和一个零件。零件有一个名称和一个价格,一个维修可以使用很多零件,以及各种零件可以用于各种修理(多对多)。维修的价格是部件价格和其他一些因素的总和。



尺寸变化



现在应该可以更改一个零件的价格,这应该会改变未来的价格维修。然而,数据库中已经存在的任何修复不应更改,因为它们用于会计,发票等。



可软更新



删除部分很容易解决 SoftDeleteable 。这将保持零件维修之间的关系。类似的事情应该是更新实体。只有重要的某些事情(如价格)发生变化,才能在数据库中更新实体。然而,似乎没有现成的代码。



我尝试过以下操作:




  • 简单地删除旧实体并在每次更新时存储一个副本,这是代码密集,效率低下,并在数据库中留下大量垃圾。

  • 可版本化,但这对多对多实体无效

  • Loggable ,但是这些更改会写在单独的日志表中,而不是在我正在使用的表格

  • EntityAudit ,但这也没有不要做我想要的,不能用于多种笨蛋。



以不同方式解决问题?



我有 询问我的技术解决方案的帮助之前的persist-soft-delete-only-if-object-has-changed>,但由于我认为问题是一个常见的问题,我开始认为缺乏直接的,现成的解决方案意味着我以错误的方式来解决问题。也许我应该简单地保留静态表用于存储在其中的静态值(但是这不允许在保持价格的同时更改某个修复的名称)?或者?

免责声明:您的问题相当广泛,因此可能还有一个足够好的解决方案。下面这个只是我的意见。



我想你应该重新考虑你的域名。再想想一下价格实际上是什么。你已经注意到它根据观点而不同。在您的示例中,有两种情况:




  • 当前(基本)产品价格。

  • 当时的价格, Rapair 已经完成。 (实际上支付金额)



但是,同样的价格还有更多的观点。价格可能不仅随时间而变化,而且可能同时具有多个值 。假设您要实现折扣功能,如果零件修复成本> 100 $总共给予5%的折扣。在这种情况下,两个客户可能在相同的确切时间具有不同的价格。



考虑到以上考虑,您可以注意到,实际上它不是 Part 的价格,但有两个不同的价格属性。一个基础价格和第二个付费价格。



由于付费价格可能具有从不存在的基础的价值(例如,在折扣案例中),很明显,您正在处理两种不同的价值观,只有通过认定才能使用相同的名称 price 。但是它们属于两个不同的实体。



tl; dr



重新处理两种不同的价值观,并应分开保存。



解决方案提案



而不是 ManyToMany 关系,您可以创建一个明确的实体 RepairPart ,这将与<$ c $在 ManyToOne 关系中修复和部分实体,但它还将包含其他数据您可能需要在将来,但他们可能会更改源部分表。在这种情况下,这是价格。


I'm developing a type of web shop in Symfony3/Doctrine. In order to simplify things, let's say I have a table Repairs and one Parts. Parts have a name and a price, and a Repair can use many Parts, as well as various Parts can be used in various Repairs (Many-to-many). The price of a Repair is the sum of the prices of the Parts and some other factors.

Slowly changing dimensions

Now it should be possible to change the price of one Part, and this should change the price of future Repairs. However, any Repairs that already exist in the Database should not change, as they are used for accounting, invoicing and such.

"Soft-updateable"

Deleting a Part is easily solved with SoftDeleteable. This keeps the relationships between Parts and Repairs intact. Something similar should happen for updating Entities. Only if something vital (such as the price) changes, the Entity should be updated in the database. However, there seems to be no ready-made code.

I've tried the following:

  • Simply deleting the old Entity and storing a copy upon every update, which is code-intensive, inefficient and leaves lots of junk in the database.
  • Versionable, but this does not work on many-to-many entities
  • Loggable, but this writes the changes in a separate log table, not in the table I'm using
  • EntityAudit, but this also doesn't do what I want and can't be used on many-to-manies.

Approach the problem differently?

I've asked for help with my technical solutions before, but Since I believe that the problem is a common one, I'm starting to think that the lack of straightforward, ready-made solutions mean that I'm approaching the problem in the wrong way. Perhaps I should simply keep a static table for accounting with static values stored in them (but this would not allow changing the name of a certain Repair while keeping the price)? Or?

解决方案

Disclaimer: Your question it pretty broad, therefore there may be more then one good enough solution. This one below is just my opinion.

I think you should reconsider your domain. Think again about what the "price" actually is. As you've already noticed that it's varying depending on point of view. In your examples there were two cases:

  • current (base) price of product.
  • the price in the past at the time, the Rapair was made. (actually paid amount)

But there are even more points of view on the same price. The price may not only change over time, but it may have multiple values at the same time. Let's say, you want to implement discounts feature, where if Parts for a Repair cost >100$ in total, you give a 5% discount. In this case two clients may have different price at the same exact time.

Taking above into account, you could notice, that it's not actually matter of Part's price over time, but there are two different price properties. One base price, and the second paid price.

Since paid price may have values that never existed as a base (e.g. in discount case), it's clear, that you're dealing with two different values that only by accidence can have the same name price. But they belong to two different entities.

tl;dr

You're dealing with two different values and they should be kept separately.

Solution proposal

Instead of ManyToMany relation, you could make an explicit entity RepairPart, which would relate to both Repair and Part entities in ManyToOne relation, but it will also contain additional data that you may need in the future, but they may change in source Part table. In this case it's the price.

这篇关于教义:跟踪缓慢变化的维度的历史的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆