Thinking about how to model a simple graph for a Side project.
The project's users will be able to add social networks so that they can find other users with social information.
Given neo4j's architecture, which I'm new to, is the correct way to do this:
A different type for each social network (e.g, twitter, LinkedIn) and a relationship of user --> has_twitter_account / user --> has_linkedin_account with relevant keys
one type (SocialMediaAccount) with user --> has_socialmedia_acct relationship with relevant keys In a more generic way and an attribute for name of social network
adding social networks as attributes under each User entity?
Something else I haven't thought of?
I'm leaning towards number 1 but given that I'm a newcomer I want to make sure this isn't an anti-pattern or setting me up for pain later.
Not sure if I understand you requirements correctly, but in general, it's good to model real world entities as nodes and relationships between things, quite naturally, as relationships.
In your case, I'd go one of the two following ways, depending on how much you want to do with their social media accounts.
1) A node for each social media, e.g. (LinkedIn), (Twitter), (Facebook). Then a single relationship type, call it HAS_ACCOUNT, which links (user) nodes to accounts. For example:
(user1)-[:HAS_ACCOUNT]->(LinkedIn)
2) If you find you're storing too many properties in the HAS_ACCOUNT relationship, or even that you feel like it should be linked to something else (e.g. links between social media accounts), create a node for each account the user has.
(user1)-[:HAS_ACCOUNT]->(user1LinkedInAccount)-[:IS_ACCOUNT]->(LinkedIn)
That way, your model is more flexible and you can link users account together with a different kind of relationship. Say user1 follows user2 on Twitter:
(user1TwitterAccount)-[:IS_LINKED_TO]->(user2TwitterAccount)
Hope it makes sense.
Related
I am using neo4j to build a social network web app where users that are friends can communicate with each other through video calls. Each participating user will also be able to submit a review at the end of each call. I structured the graph such that two (:User) nodes can have a [:FRIEND] relationship between each other. For a particular video call, I am planning on creating a (:VideoCall) node (which contains properties such as roomId) and a [:PARTICIPANT] relationship from the (:VideoCall) node to each participating (:User) node. The [:PARTICIPANT] relationship will have a rating property containing the user's review for that video call. Would this model be performant if there are a large number of user and video call nodes? Is there a better way to design the database for this type of feature?
Yes it should be performing well. Just make sure you have properties that you want to look up by indexed and constraints in place
What kind of use cases would you want to cover besides regular ones?
It is a good model if the video calls involve multiple users AND you want to use roomId as a condition for queries because in this way you can easily find all users that have participated in a specific video call.
However, I noticed that you mentioned it is a social networking web app. So chances are the video calls are just between TWO users. If that's the case, then there'a an alternative to your current model: Make video calls as an edge between users: (:user)-[:videocall]->(:user) Properties such as roomId can be assigned to the edge. This model saves memory because you have fewer nodes.
I have a question concerning microservices and databases. I am developing an application: a user sees a list of countries and can click through it so he can see a list of attractions of that country. I created a country-service, auth-service (contains users for oAuth2) and an attraction-service. Each service has its own database. I mapped the association between an attraction and its country by the iso code (for example: BE = belgium): /api/attraction/be.
The approach above seems to work but I am a bit stuck with the following: a user must be able to add an attraction to his/her list of favorites, but I do not see how that's possible since I have so many different databases.
Do I create a favorite-service, do I pass id's (I don't think I should do this), what kind of business key can I create, how do I associate the data in a correct way...?
Thanks in advance!
From the information you have provided, using a standalone favourite service sounds like the right option.
A secondary simpler and quicker option might be to also to handle this on your user service which looks after the persistence of your users data as favourites are exclusive to a user entity.
As for ID's, I haven't seen many reasons as to why this might be a bad idea? Your individual services are going need to store some identifying value for related data and the main issue here I feel is just keeping this ID field consistent across your different services. What you choose just needs to be reliable and predictable to keep things easy and simple as your system grows.
If you are using RESTful HTTP, you already have a persistent, bookmarkable identification of resources, URLs (URIs, IRIs if you want to be pedantic). Those are the IDs that you can use to refer to some entity in another microservice.
There is no need to introduce another layer of IDs, be it country codes, or database ids. Those things are internal to your microservice anyway and should be transparent for all clients, including other microservices.
To be clear, I'm saying, you can store the URI to the country in the attractions service. That URI should not change anyway (although you might want to prepare to change it if you receive permanent redirects), and you have to recall that URI anyway, to be able to include it in the attraction representation.
You don't really need any "business key" for favorites either, other than the URI of the attraction. You can bookmark that URI, just as you would in a browser.
I would imagine if there is an auth-service, there are URIs also for identifying individual users. So in a "favorites" service, you could simply link the User URI with Attraction URIs.
I am working on my first web project. I have referenced many tutorials and pdfs but all those had simple examples for the login and sign-up feature for a webpage, which only used a single database. I am having a massive confusion on whether or not, the login and sign-up should have separate databases.
My main question is : The project intakes user's personal information(name, email, address, telephone number, etc.) along with information specific to their vehicles (model, company, make, manufacture date, etc.). And after logging into the website, both these data's are important but only some of them are in use like, the user's name, his/her address, the model of vehicle, and the company. So should I maintain separate databases for both of them and reference each element with a foreign key while working on databases ?? Or should i just bother less and use a single database and complete my login and sign-up function ??, because with the no. of columns that I have apparently is very large.
This might be a bit too academic, but a word you'll want to learn well is normalization. Here is a link to a pretty stiff definition: https://en.wikipedia.org/wiki/Database_normalization
This being your first web project, my advice would the following:
Don't be afraid to make mistakes. I would strongly encourage trying approaches you think are good and then don't be afraid to change your mind. The lessons learned will stick with you.
Keep everything simple up front. Only add complexity when you need it.
Definitely don't be afraid to grow horizontally with tables (add more and more tables). When I first started working with databases I was afraid to have too many tables because it felt wrong. Try to resist the temptation to cram everything in one table.
Definitely separate login, users and vehicle information. Not a bad idea to also separate out user address information since people can have more than one address.
You must use the same database for holding all the information for your project. Two different database is not really good idea , you can create many tables in an database. and each table is designed to hold different information.In case of your example you may choose the following tables in the same database
UserLogin [store login information]
User [ store personal info]
Vehicle
and so on
There must be one to one relationship between UserLogin and User table and one to many in user - Vehicle table
One user may have many Vehicle
Hopefully it will help
In our SaaS system we're dividing users into separate "pools" according to the customer that originally "owns" the user. We're using "email addresses plus ID of owning organisation" to identify users, rather than just email addresses - so duplicate email addresses can exist between customers (don't ask). Users arrive at the site on various subdomains, and we use these subdomains to identify the "user pool" we're authenticating the user against.
My question: is there any established name for this pattern or something similar?
Cheers!
In database terminology, when uniquely identifying a row using more than one column, this is called a composite primary key (aka compound key).
The scenario you describe is used commonly when a single database is used for multiple customers - one form of multitenancy.
"home-realm-discovery" is a common term for identifying what tenant a user belongs to in a multi-tenant SaaS application. It's most often talked about in the context of Federated Identity but applies in your case too. Using a sub-domain like you're doing is a common practice.
I am not aware of any specific name for this scenario, but in general, this would fall under the phrase "multi-tenant" / "multi-tenancy". Many SaaS implementations do customer (or rather tenant) based branding already on the login screen, which would mean that they'd have to identify the user based on the URL / subdomain, or at least in some way other than the email address used.
Routing to different servers based on the subdomain is also a common way to achieve tiered service levels for SaaS implementations.
I'm not sure I've answered the question, but I hope the general info helps!
I'm working on a user facing django application for an enterprise solution. Currently, users are able to categorize data on the site into private collections, visible only to themselves. A feature request is for managers to be able to view the private collections of their subordinates.
My issue is, what is the best solution for implementing this hierarchy? I've thought of a few solutions:
A foreign key from user to user named manager. Create a #user_passes_test test that recurses through the manager relation looking from the owner of the collection until a) the requesting user is found to be a manager, or b) manager is Null, indicating the requesting user is not authorized to do access this page.
Benefits: simple hierarchy is accurately represented with minimum data
Drawbacks: A large hierarchy results in many queries
Create a many to many relation between users and users called managers. Create all the relationships in this table.
Benefits: Only one query necessary, and users can have multiple managers.
Drawbacks: difficult to change the hierarchy when someone leaves.
I'm open to any other suggestions people have, as well.
A tree of uniform data (where the data referred to by nodes and leaves is of the same class) can often easily be maintained by an SQL-based tree structure. While you can always write one by hand, Django MPTT and Treebeard have both dealt with the issue. I've used Treebeard, but MPTT seems to be more popular.