4 ms·
I have a pseudo-event sourcing setup because I imagine could help in better sync mobile devices (yes it work). But instead of using eventually consistent and g
by mamcx 7y ago
I have a pseudo-event sourcing setup because I imagine could help in better sync mobile devices (yes it work).
But instead of using eventually consistent and get rid of the RDBMS? I invert the operation:
1- Post data to the table (as normal) record the event in Postgres with JSONB: All integrity and validations work great and without complex logic.
2- 90% of all the queries need only the most recent data. Not stupid "reload the history" for each simply operations
3- Still get full history & auditing.
This is not much different to "audit tables" actually.
Most events are Table + CRUD operation. If a table is well modeled and normalized you don't need to detail much of the event.
What I miss in the first iteration was diff the changes. This lead to much extra info. Diffing the changes auto-magically turn the event more semantic!
----
Still is an imperfect setup and rely much on dynamic data to my taste. I wish modern RDBMS support algebraic types and better ways for this scenario but with this I avoid a lot of extra work and complications...
- alexandercrohde 7y agoSounds cool. The thing I'd say is, in this type of setup you can use somtehing called a "view." It's like a query that makes a virtual table. So you can then have this "virtual table" of the most recent of each audit record, and query against that. It helps keep stuff clean, very underused in my experience.
- AaronFriel 7y agoIn most relational database management systems (RDBMS) views are not persisted/materialized or indexed separately. Some RDBMS have materialized views that update concurrently and meet atomicity, consistency, isolation, and durability (ACID) requirements, but others do not and a separate command is needed to update views, in those cases you lose many of the benefits, but the view is fine for say, analytical queries in which a little lag is fine. I am personally a fan of temporal tables, a technique in which rows are versioned, and you can query for the state of the database "at" a point in time. Here support is even less uniform than with materialized views, but if you have control over your database access layer or object relational mapping, you can brew your own. This gives you history if you need it (rare, but incredibly helpful) and fine grained control over indexing. I recommend the latter approach for anyone looking to implement event sourcing and auditing. Including in each table a column for the source or cause of a change for example gives you an audit log for almost free.
- alexandercrohde 7y ago>> In most relational database management systems (RDBMS) views are not persisted/materialized or indexed separately. Right, which is why they're great. You can materialize a view, but then you have to manually refresh. And they are actually incredibly performant. How they work is they are basically treated as a query clause. For example you query "Select * from my_view where key = 1" and it intelligently executes "Select * from base_table where key = 1 and record = latest" (That is to say, it doesn't stupidly requery the whole base table each time, nor is there any risk of inconsistency) The query optimizer is incredibly smart and honestly pretty sure this can scale beyond the needs of any startup.
- AaronFriel 7y agoI know how views work in several RDBMS, and I don't think that description lines up with what I understand. > That is to say, it doesn't stupidly requery the whole base table each time, nor is there any risk of inconsistency I mentioned materialized views, but then you mention the base_table. I think this statement is inaccurate whether it's a materialized view or not: 1. With materialized views as implemented by PostgreSQL and MS SQL Server, it doesn't query the base_table, it queries an artificially generated table. In the case of PostgreSQL, that table will be out of date (inconsistent) the moment there is a change to base_table. A manual refresh is necessary and expensive every time the view becomes inconsistent. 2. With non-materialized views, you are incorrect with at least PostgreSQL and MS SQL Server, the view does not "cache" its filters or joins or clauses. The view just functions as a query modification, and it does in fact query the "base table each time". I think what you need to satisfy your requirements is actually a filtered or partial index, of the form: CREATE INDEX latest_idx ON base_table (some_base_table_keys, ...) WHERE record = latest; That index will be consistent and will keep the query optimizer from, as you say, stupidly requerying the whole base table, as long as the criteria holds and the keys your searching for are a prefix of those keys.
- mycall 7y agoViews are popular for projecting denormalized information. I pity the fool who inserts into views.
- kian 7y agoStay tuned on that last front.