Purge strategy for parent-child persistent objects - intersystems-iris

We are seeing performance issues in purging objects/tables that have parent-child relationships defined. Due to the number of child objects, we're seeing a very long duration to purge a single parent and all child tables. Is there a better way to do this and get a more performant purge task?
I was thinking to purge the child tables individually first and then delete the parent is one way. Is there another approach?

Try to delete the child objects via IRIS SQL.
In this approach, you can see the query plan and maybe add the necessary indices.

"purge a single parent and all child tables".
As you want to delete the parent too,
it should be sufficient to delete just the parent object.
By definition, all children should be deleted implicitly.
BUT:
most of the processing time may be consumed by the maintenance of all related indices.

Related

When should I use CREATE and when MERGE in Cypher queries?

I've seen that sometimes CREATE is used to create nodes, and in other situations, MERGE is used. What's the difference, and when should one be used in place of another?
CREATE does just what it says. It creates, and if that means creating duplicates, well then it creates.
MERGE does the same thing as CREATE, but also checks to see if a node already exists with the properties you specify. If it does, then it doesn't create. This helps avoid duplicates.
Here's an example: I use CREATE twice to create a person with the same name.
CREATE should be used when you are absolutely certain that the information doesn't exist in the database (for example, when you are loading data). MERGE is used whenever there is a possibility that the node or relationship already exists and you don’t need to duplicate it. MERGE shouldn't always be used as it’s considerably slower than the create clause.

Embed documents in Java spring for Mongo

I want to conceive a relationship such as that if i destroy a parent object the child object is removed too on MongoDB (Spring)
How to achieve this ?
I know that in Python's Flask this could be done with EmbeddedDocumentField but how to do it in Java's Spring boot.
Thank you,
MongoDB doesn't support cascading deletes. You should probably create an array in the User object, and put the complete child documents into that array instead of keeping them in their own collection. That way they will be deleted together with the parent, because they are a part of it.
checkout this post
There are two ways I can think of
If parent deletion is in your control , you can use the transaction delete the child also .
If parent deletion is not in your control, you can listen to change stream and then when deletion happens, delete the child.

Running code when a model is deleted via cascade/bulk deletion

I have a table that basically represents uploads, therefore, when an instance of the model representing this table is deleted, I want the file being represented to be deleted from my uploads folder.
The way I've gone about this thus far is basically overriding the delete method, so that, before the model instance is deleted, the file will be as well.
Problem: not only does this not work for cascade deletions, it also doesnt work if I delete a Collection....
I've looked at Events, like Model::deleting, but they suffer from exactly the same problem (namely they're not triggered by cascade deletions or bulk deletions).
I have also considered a SQL trigger, but it doesnt seem like I can delete files from SQL (inform me if I can, I'd love it! I'm using MySQL, btw).
Do I have an option that is classier than just making a separate query and iterating over it deleting the files every time I need to do a bulk deletion/cascade, or is this really it?
Take a look at https://laravel-news.com/laravel-model-events-getting-started
You need to define an event inside your model.

Optimistic locking over multiple documents

I need to update some documents at once, like a RDBMS transaction. The best way to do this for a single document in a key-value store like couchbase seems to be using optimistic locking. This would work for me. However, I need to update multiple documents at once.
I need all documents to be updated, or none. Is this possible in couchbase or some similar highly scalable database?
(by the way, I'm using Go)
There are three approaches to resolve it:
You should take another look at your key/document designs and identify if its possible to combine your multiple docs into one. Then you will be able to do a single transactional update in Couchbase.
Simulate Transaction the effect can be simulated by writing a suitable document and view definition that produces the effect while still only requiring a single document update to be applied.
Simulate Multi-phase Transactions to use the transaction record to record each stage of the update process

Referencing object's identity before submitting changes in LINQ

is there a way of knowing ID of identity column of record inserted via InsertOnSubmit beforehand, e.g. before calling datasource's SubmitChanges?
Imagine I'm populating some kind of hierarchy in the database, but I wouldn't want to submit changes on each recursive call of each child node (e.g. if I had Directories table and Files table and am recreating my filesystem structure in the database).
I'd like to do it that way, so I create a Directory object, set its name and attributes,
then InsertOnSubmit it into DataContext.Directories collection, then reference Directory.ID in its child Files. Currently I need to call InsertOnSubmit to insert the 'directory' into the database and the database mapping fills its ID column. But this creates a lot of transactions and accesses to database and I imagine that if I did this inserting in a batch, the performance would be better.
What I'd like to do is to somehow use Directory.ID before commiting changes, create all my File and Directory objects in advance and then do a big submit that puts all stuff into database. I'm also open to solving this problem via a stored procedure, I assume the performance would be even better if all operations would be done directly in the database.
One way to get around this is to not use an identity column. Instead build an IdService that you can use in the code to get a new Id each time a Directory object is created.
You can implement the IdService by having a table that stores the last id used. When the service starts up have it grab that number. The service can then increment away while Directory objects are created and then update the table with the new last id used at the end of the run.
Alternatively, and a bit safer, when the service starts up have it grab the last id used and then update the last id used in the table by adding 1000 (for example). Then let it increment away. If it uses 1000 ids then have it grab the next 1000 and update the last id used table. Worst case is you waste some ids, but if you use a bigint you aren't ever going to care.
Since the Directory id is now controlled in code you can use it with child objects like Files prior to writing to the database.
Simply putting a lock around id acquisition makes this safe to use across multiple threads. I've been using this in a situation like yours. We're generating a ton of objects in memory across multiple threads and saving them in batches.
This blog post will give you a good start on saving batches in Linq to SQL.
Not sure off the top if there is a way to run a straight SQL query in LINQ, but this query will return the current identity value of the specified table.
USE [database];
GO
DBCC CHECKIDENT ("schema.table", NORESEED);
GO

Resources