Redis is document-based, and it's difficult for nosql to deal with relationships.
For example, people can blog, blogs can be categorized. According to the traditional SQL, the user table and the classification table are the main table, the blog table is from the table, there are foreign keys and categories of the user's foreign key
If you are using a document-based way of thinking.
Store his blog for User A (id=1), which is a list or set in Redis
A blog under Category A (Cate id=1) storage classification, which is a list or set in Redis
When user A adds a new blog to category A, it needs to add data to the two list (or set) at the same time, and in theory it should be a transaction, and modify two at a time.
The benefit is that the read operation is fully optimized, and what is read directly from a key is immediately available
The downside is that the write operation is too complex to notice anything that might be missing, and updating the blog requires updating the elements in very many lists.
Servicestack's Redis client provides several methods specifically for this scenario.
First look at the entity class
Public classUser{ public intId {Get; Set; } Public StringName {Get; Set; }}Public classBlog{ public intId {Get; Set; } Public StringTitle {Get; Set; }}Public classCate{ public intId {Get; Set; } Public StringName {Get; Set; }}
Very simple 3 classes, used to represent users, categories, blogs 3 kinds of concepts
Save 3 instances with a strongly typed client
varClientsmanager =NewPooledredisclientmanager();using(iredisclientRedis = clientsmanager.getclient ()) {Redis. Flushall (); varu =NewUser{Id = 1, Name ="A"}; varC =NewCate{Id = 1, Name ="A"}; varblog =NewBlog{Id = 1, Title ="Blog"}; Redis. as<User> (). Store (U); Redis. as<Cate> (). Store (c); Redis. as<Blog> (). Store (blog);}
Can be viewed through the client software, 3 entities are saved successfully, but does not reflect the relationship
Redis. as<User> (). Storerelatedentities (u.id, blog), Redis. as<Cate> (). Storerelatedentities (c.id, blog);
The statement that holds the relationship is then called, as is the primary table, the first is the primary table primary key, and the second is from the object
2 new Key,ref:cate/blog:1 and ref:user/blog:1 in Redis
Their value is a set
The specific content in set is not the object itself, but the object's key in the urn
blogs = Redis. as<User> (). getrelatedentities<Blog> (u.id);
The contents of the table can be obtained from the related statements.
The entity that directly takes to the blog
But there was a bug when I deleted it.
His method specifies that the second parameter is childID, so we pass in the ID, but the deletion does not fall
Redis. as<User> (). deleterelatedentity<Blog> (u.id, blog);
Do not use the ID, but the use of the object, still can not erase
View source discovery, when he runs from set to delete things, look for key is right, but to be deleted by the element generated by the wrong
When added, he takes urnkey<t> (x) to generate the entity saved key, while deleting it without
When deleted, is directly serialized, then 1, after serialization is 1, and our set, there is no 1 this value, so there is no deletion of anything.
The client's urnkey is a internal way, and it's disgusting again.
Redis. as<User> (). deleterelatedentity<Blogredisnativeclientidutils . Createurn (blog));
We can only use such a complex way, it is equal to the internal code to take the outside to deal with, of course, you can clone his source to change or write the extension method.
Depending on the key of the relationship, we can probably analyze
Ref: Primary table/From table: Primary table primary key value
But such a way has certain limitations, that is, to the same master-slave type, they can only express a relationship.
such as people and blogs, if I need to express people write blog, people recommend the blog these two relationships (both people and blogs), it is impossible to achieve
For example, User 1, he wrote blog 1, recommended the blog 2. But they were all added to the ref:user/blog:1, unable to distinguish between what he wrote or what he recommended.
So we need to give a name to the relationship between the two types, to distinguish between the relationship.
There is a Getchildreferencesetkey method in redistypedclient<t> that is to generate this key, the private method, is again disgusting
Of course, it can be distinguished by setting a different value on the NamespacePrefix, but it feels weird, because it seems to me to be a different application, set to prevent key duplication
Interested friends can write a few extension methods, anyway, the source is basically able to see
Again to be disgusted again is that GitHub did not open issues submit
The limitations and bugs of the relationship operation in Servicestack.redis