Event sourcing: Tracking each entity field changes in specific interval - sql

I'm trying to figure out what could be the best solution for this use case:
there is a need to track each field changes in agreement entity. So when someone makes update for any field they must set when this is going to be applied (can set date in future or past). And later it should be possible to filter by some field's value in the past for specific date interval. So basically it's needed to have history of each field and apply correct value according to current date.
At first glance, it's possible to use event sourcing when entity is built from events on write side and for read side it could be used snapshots so on each new change for entity would be rebuild in SQL database table for quering operations.
Is there any simpler solution for this case?

Yes, ES could be an appropriate solution for your problem. You track all fields changes as separate events. And it would help if you create various read models according to your requirements.
If you need to store the history of each field change, you probably have a read model for this purpose and another for your last or per version snapshot of your read side entity.
Noice: You create your read models according to your current or future requirements. Maybe you need a new read model after 6 months, So you create another read model. BTW you can achieve this by using event sourcing.

Related

Is there a way to create an virtual table that would be compared to one after editing?

I have a table [contractor c] in which only one field [tin] may be edited. If the user tries to change data in other field it shall not be updated. Was wondering if making a view of the c before editing and then comparing the view with edited table is a good idea. But that would require two scripts- before and after update.
I could also make a validation on every single field except tin, but there is 'a lot' of fields.
Looking for the best and most optimal way to approach this task.
This is too long for a comment. There are many ways to do what you describe. "Views" are not one of them. In SQL, a view is a stored query. It does not store values. That is definitely not going to help, because the view changes with the underlying tables.
If only one column can be updated, then one method is to implement a trigger that checks the before- and after- versions of the record and only allows updates when no other fields change.
You can start learning about triggers in the documentation.
An alternative mechanism is to make the table unupdatable except for update permissions on a single column. You can learn about permissions in the documentation.
If for some reason you wanted to do all the work in the application, then transactions might come into use. You would not commit the transaction until the update meets your requirement. Transactions are explained in the documentation.

Storing relational data in MongoDB (NoSQL)

I've been trying to get my head around NoSQL, and I do see the benefits to embedding data in documents.
What I can't understand, and hope someone can clear up, is how to store data if it must be relational.
For example.
I have many users. They are all buying a product. So everytime that they buy a product, we add it under the users document in mongo, so its embedded and its all great.
The problem I have is when something in reference to that product changes.
Lets say user A buys a car called "Porsche". Then, we add a reference to that under the users profile. However, in a strange turn of events Porsche gets purchased by Ferrari.
What do you do now, update each and every record and change to name from Porsche to Ferrari?
Typically in SQL, we would create 3 tables. One for users, one for Cars (description, model etc) & one for mapping users to purchases.
Do you do the same thing for Mongo? It seems like if you go down this route, you are trying to make Mongo do things SQL way, which is not what its intended for.
I can understand how certain data is great for embedding (addresses, contact details, comments, etc) but what happens when you need to reference data that can and needs to change at a regular basis?
I hope this question is clear
DBRefs/Manual References were made specifically to solve this issue. Instead of manually adding the data to each document and then needing to update when something changes, you can store a reference to another collection. Here is the mongoDB documentation for details.
References in Mongo
Then all you would need to do is update the reference collection and the change would be reflected in all downstream locations.
When i used the mongoose library for node js it actually creates 3 tables similar to how you might do it in SQL, you can use object id's as foreign keys and enrich them either on the client side or on the backend, still no joining but you could do an 'in' query for the ID's then enrich the objects that way, mongoose can do this automatically by 'populating'

Is it possible to set shared variables outside of the plugin pipeline CRM 2011

I want to create a record of an entity, but I need to pass a list of guids to the pre create plugin. I don't want to create fields or related entities to do this. Can I use the Shared Variables to do it?
In other words is it possible to set shared variables before initiating the action that will trigger the plugins that will consume them?
EDIT:
I can be creating this type of records from different points that integrate with crm, silverlight, external pages or even plugins of other entities. My current problem can be solved with a field on the entity, but this way if I had to send parameters to control the execution of the plugin for two or more independent actions I would need one field for each action or instead use only one field using a complex format/parse pattern to parameterize each different action. Using fields to accomplish this feature looks a bit excessive.
If the shared variables could be set before the call of the action that will trigger the plugin that would solve the problem and I wouldn't have to create fields in the crm database, because the data I want to pass to the plugin it will only be needed at that time, like a parameter in a function, no need to persist them in the database.
But if it is not possible I will have to stick with the fields :(
Not if they vary by entity/execution of the plugin.
Options:
Set them in the plugin configuration if they don't change but need to be updated
without a recompile.
Apply them as a delimited string in a single field on the entity if they vary per record.
What's the reason for not wanting to use 2?
Nope. The easiest solution that I can think of is to add a BAT (big-ass text) field to the entity and populate it with a comma-delimited list of GUIDs, then access that field in your Create plugin. You could even clear it out if you don't want that extra data in your system.
Edit after your edit:
General comment about your thinking process: you are probably overthinking it. :) Using a single field, you could pass in any kind of "command" using a json or xml formatted string. As I said above, in the pre-create plugin, after you have extracted this "argument" field, you can clear out that field in the Target entity image and that data will never be persisted to the database. Technically it achieves the exact result you want with the only side effect being one extra "argument" field that is always NULL in the database. Don't fight simplicity so hard! :)

Using change tracking while ignoring an individual column

Presently, I'm tracking changes to all of my tables using SQL Server 2008 Change Tracking. Everything works out of the box just fine. However, an additional complexity is that the application reading these changes needs to make a change to a date column on each table that is being tracked. Changes in my application are like triggers to tell me that I need to send out additional data. This could cause an endless cycle if not managed.
There's a sent date that gets filled in after each change is read.
Is it configurable at a database/table level to ignore an individual column on a table so that versions/changes are not tracked when that column is modified?
Using change tracking, there's two ways but both involve merely filtering the results; there is not a way to limit the change tracking by column.
1) Filter by context
The following link shows how to change the context for when an application changes data. If you change the context specific to what is making the changes, you can then filter it by that when you query. http://msdn.microsoft.com/en-us/library/cc280462(v=sql.105).aspx
2) Filter using the columns updated mask
In addition, I have to admit that I roll my own change tracking still. I have scripts that I execute to autogenerate code triggers. They can be customized to prevent non-changing updates (i.e. a row update that changes no fields you are interested in), plus they allow me to fully control things. I can track which fields I want, plus I can move all of my tracking/default fields (such as suser_sname()) into the tracking table so that the day to day business tables are kept slim. If you are interested in this option, reply as such and I'll post the code to autogenerate the triggers and tracking table for a given table name.

sDesigning a database with flexible user profile

I am working on a design where I can have flexible attributes for users and I am confused how to continue the design of the schema.
I made a table where I kept system needed information:
Table name: users
id
username
password
Now, I wish to create a profile table and have one to one relation where all the other attributes in profile table such as email, first name, last name, etc. My question is: is there a way to add a third table in which profiles will be flexible? In other words, if my clients need to create a new attribute he/she won't need any customization to the code.
You're looking for a normalized table. That is a table that has user_id, key, value columns which produce a 1:N relationship between User & this new table. Look into http://en.wikipedia.org/wiki/Database_normalization for a little more information. Performance isn't amazing with normalized tables and it can take some interesting planning for optimization of your code but it's a very standard practice.
Keep the fixed parts of the profile in a standard table to make it easy to query, add constraints, etc.
For the configurable parts it sounds like you are looking for an entity-attribute-value model. The extra configurability comes at a high cost though: everything will have to be stored as strings and you will have to do any data validation in the application, not in the database.
How will these attributes be used? Are they simply a bag of data or would the user expect that the system would do something with these values? Are there ever going to be any reports against them?
If the system must do something with these attributes then you should make them columns since code will have to be written anyway that does something special with the values. However, if the customers just want them to store data then an EAV might be the ticket.
If you are going to implement an EAV, I would suggest adding a DataType column to your attributes table. This enables you to do some rudimentary validation on the entered data and dynamically change the control used for entry.
If you are going to use an EAV, then the one rule you must follow is to never write any code where you specify a particular attribute. If these custom attributes are nothing more than a wad of data, then an EAV for this one portion of your system will work. You could even consider creating an XML column to store these attributes. SQL Server actually has an XML data type but all databases have some form of large text data type that will also work. On reports, the data would only ever be spit out. You would never place specific values in specific places on reports nor would you ever do any kind of numerical operation against the data.
The price of an EAV is vigilence and discipline. You have to have discipline amongst yourself and the other developers and especially report writers to never filter on a specific attribute no matter how much pressure you get from management. The moment a client wants to filter or do operations on a specific attribute, it must become a first class attribute as a column. If you feel that this kind of discipline cannot be maintained, then I would simply create columns for each attribute which would mean an adjustment to code but it will create less of mess down the road.