Implement "follow person, post" feature in asp.net mvc - asp.net

In any social network, you can follow a person, a post or anything, everything you followed will be displayed in your wall, now I wanna implement the same feature in asp.net mvc, but I have problem on design table to query all following things of a user. This is tables I designed:
[User(id,name,email,password)]
[Following(id,personId,followingId,source)]
[Post(id,title,description,authorId)]
So when a user followed other user,a new record will be pushed on Following table with followingId is userId, and source is "User" table, the same as with following a post with followingId is postId and source is "Post" table.
The problem is when fetch data from what your following, the query join many tables to return result if user followed more things than a Post, and Other User (such as a Tag, a Topic...). this will be not good performance and query time to return data to user.
Do you have any idea about this ? I'm very appreciate to hear your solution, thanks a lot!

Your database design is flawed, instead of one "link" table with a string to identify where the "Followed thing" resides makes it hard to query effectively.
Instead you need one link table per thing linked. SO in your simplified example you might have
[User(id,name,email,password)]
[Post(id,title,description,authorId)]
[UserFollowingUser(id, userId, followedUserId]
[UserFollowPost(id,userId,postId)]
Therefore to get all users following a post, or all posts followed by a user, or get all users following a particular user, or get all users followed by a particular user is easy as pie.

Related

Custom URLS for database information

How do things like google classroom do this:
classroom.google.com/c/(random characters here)
When you go to that link, because of the random characters, it knows what information to show
how would I do something like that in asp.net
Well, in .net you often might have grid or pick list of say hotels. When the user clicks on a hotel from that list, then you can jump/navigate to the hotel and display information. In these cases you actually want to AVOID having to use parameters in the URL. So, you can use session() to pass the value to the new web form/page.
However, often you might want to say email a link to someone else, or say send a email with a link called:
Click here for your Hotel Booking details.
So for above? What is often done is you create a table in the database. I often call it tblHotelJump or whatever. In that table you have this:
ID: (standard PK value all tables have).
CusotmerID: the PK of the customer - you might not need this, but if you using logons
and security - then you might only want the the link to work for the given
user.
HotelID: - PK value of hotel. This is where you can now pull the Hotel information
from the hotel table. (or maybe the booking table ID
JumpGUID: {3434sl%$#*} - a random generated number or GUID is often used.
userLogonID: internal user logon ID - obtained from logon authentication system.
So, now, we can pass a URL like this:
www.MyBookings.com/HotelInformation.aspx?JID={3434sl%$#*}
So the above is now a link you can send to a user.
They click on above, and your code behind on the page load does this:
If Not IsPostBack Then
' get parms
Dim strGuid As String
strGuid = Request.QueryString("JID")
So the above gets/grabs that parameter.
Now you code pulls that one row from the tblHotelsJump like this:
Dim cmdSQL As New SqlCommand("SELECT * from tblHotelJump
where JumpGUID = #GUID ORDER BY WhenTime DESC", GetCon())
cmdSQL.Parameters.Add("#GUID", SqlDbType.NVarChar).Value = strGuid
Dim rstGUID As DataTable = MyrstP(cmdSQL)
If rstGUID.Rows.Count > 0 Then
' Ok, valid jump row, get Hotel information and display it.
So now we can display hotel information since we have the HotelID and can display that data record.
Now in some cases, you might see something like:
www.MyBookings.com/ShowHotel.aspx?ID=343
And again the code will now simply use ID 343 and pull that hotel information from the database table with ID = 343. This idea ONLY works if you don't need security. So, say weather for a city. But you can't and don't want to use the actual database ID like above, since then users can type in ANY number and not just 343 in above example
In fact in the VERY early days of the internet, apparently a credit card company used a ID with customer number. if you typed in someone else customer number, then you could see their information!!! So using parameters is not appropriate for all cases. For public data, sure, it works well and makes sense. No harm done if you change the city parameter in the URL for weather.
So, that's why a GUID or some next to impossible number to guess is often used. Now for weather in a city? Well, then that don't matter and the WHOLE idea is to allow users to get/see the weather in any location. But for sensitive data? Then you need GUID.
And on top of the above, in that "jump table", I also included the User ID, and thus I would not display that web page unless:
The user is logged on (so a page protected by valid logons).
The Hotel information I pulled from that jump table ALSO matches the user logon id.
So, in a lot of cases? I think the parameters in the URL is VERY ugly and messy. However, for VERY large scale web sites they often use the parameters in the URL since then their server side code does NOT have to chew up memory and resources to hold/retain/keep the session() data. But with session() then you can jump around and use URL's without ugly parameters. So in .net we often avoid parameters, but in some cases the parameters in the URL is desired since then you can send/share that link. So for a say "click here" to view your order? Then sure, a GUID in the link may well be used. But even then, once that first page is hit with the GUID (along with above security), then any additional pages to view things about the order will not in fact require the parameters.
So paramters are easy, often used, and they reduce loads on the server side software, and as above shows, most development languages for the web have a "ready made" easy way to grab/get/use parameters in the URL. However, as noted, unless you building the next google, or say you need to send a customer a "link" to allow jumping to a particular order? Well then in .net we tend to avoid the parameters because we don't need them most of the time and .net has a whole bunch of really cool OTHER ways to store/keep values and pass them from one web form to the next web form without having to use parameters.
But if you using a limited web scripting language, then using parms in the URL is often your only practical choice.

What is the best way to create a web traffic log in DynamoDB?

I have a newspaper and would like to register the hits for every news article. I was thinking of tbl_hits with fields ArticleId and sort field timestamp (plus Other attribute fileds for headers, browser type).
However usually i get multiple hits for the same article at theexact same time so I guess I wont be able to register them since I will get duplicate key error.
What primary key + sorting fields would you recommend? Thanks so much.

Cloud Firestore and data modeling: From RDBMS to No-SQL

I am building an iOS app that is using Cloud Firestore (not Firebase realtime database) as a backend/database.
Google is trying to push new projects towards Cloud Firestore, and to be honest, developers with new projects should opt-in for Firestore (better querying, easier to scale, etc..).
My issue is the same that any relational database developer has when switching to a no-SQL database: data modeling
I have a very simple scenario, that I will first explain how I would configure it using MySQL:
I want to show a list of posts in a table view, and when the user clicks on one post to expand and show more details for that post (let say the user who wrote it). Sounds easy.
In a relational database world, I would create 2 tables: one named "posts" and one named "users". Inside the "posts" table I would have a foreign key indicating the user. Problem solved.
Poor Barry, never had the time to write a post :(
Using this approach, I can easily achieve what I described, and also, if a user updates his/her details, you will only have to change it in one place and you are done.
Lets now switch to Firestore. I like to think of RDBMS's table names as Firestore's collections and the content/structure of the table as the documents.
In my mind i have 2 possible solutions:
Solution 1:
Follow the same logic as the RDBMS: inside the posts collection, each document should have a key named "userId" and the value should be the documentId of that user. Then by fetching the posts you will know the user. Querying the database a second time will fetch all user related details.
Solution 2:
Data duplication: Each post should have a map (nested object) with a key named "user" and containing any user values you want. By doing this the user data will be attached to every post it writes.
Coming from the normalization realm of RDBMS this sounds scary, but a lot of no-SQL documents encourage duplication(?).
Is this a valid approach?
What happens when a user needs to update his/her email address? How easily you make sure that the email is updated in all places?
The only benefit I see in the second solution is that you can fetch both post and user data in one call.
Is there any other solution for this simple yet very common scenario?
ps: go easy on me, first time no-sql dev.
Thanks in advance.
Use solution 1. Guidance on nesting vs not nesting will depend on the N-to-M relationship of those entities (for example, is it 1 to many, many to many?).
If you believe you will never access an entity without accessing its 'parent', nesting may be appropriate. In firestore (or document-based noSQL databases), you should make the decision whether to nest that entity directly in the document vs in a subcollection based on the expect size of that nested entity. For example, messages in a chat should be a subcollection, as they may in total exceed the maximum document size.
Mongo, a leading noSQL db, provides some guides here
Firestore also provided docs
Hope this helps
#christostsang I would suggest a combination of option 1 and option 2. I like to duplicate data for the view layer and reference the user_id as you suggested.
For example, you will usually show a post and the created_by or author_name with the post. Rather than having to pay additional money and cycles for the user query, you could store both the user_id and the user_name in the document.
A model you could use would be an object/map in firestore here is an example model for you to consider
posts = {
id: xxx,
title: xxx,
body: xxx,
likes: 4,
user: {refId: xxx123, name: "John Doe"}
}
users = {
id: xxx,
name: xxx,
email: xxx,
}
Now when you retrieve the posts document(s) you also have the user/author name included. This would make it easy on a postList page where you might show posts from many different users/authors without needed to query each user to retrieve their name. Now when a user clicks on a post, and you want to show additional user/author information like their email you can perform the query for that one user on the postView page. FYI - you will need to consider changes that user(s) make to their name and if you will update all posts to reflect the name change.

rails nested model query

I'm trying to work out how to use active record to return some data based on a nested model.
My relationship is setup as below:
User - Has many books
Book - Has many users
UserBook - belongs to user and belongs to book
I can access users through books like so:
book.users.first
book.users.second
etc.
I'd like to select all the books, that does not have a particular user.
I have generated a query like this, please note, the 'near', method is provided by the Geocoder gem.
Book.near(location, distance).joins(:users).where("users.id != #{#current_user.id}")
I believe the syntax is correct, no errors occur, however, the query still returns books with the current user.
The issue appears to be that if book.users contains a user id that is not current user id AND also contains the current user id, book is still returned.
I can get the desired result using code like this, but I presume there is a way to get ActiveRecord to do it for me.
search = Book.near(location, distance).reject do |book|
if book.users.include?(#current_user)
book
end
end

Beginning ASP.NET. using login name as sql parameter

Does anyone have some code or a link as to how to create the user login name as a parameter during a sql query in ASP.NET?
Basically I want to use the default membership structure with a new field ClubID, then I want to add a new table called aspnet_Clubs which contains things such as Club Name, stadium name, Balance etc etc... and then use a relationship between ClubID and a field in the aspnet_Clubs table to tie things together.
Then when each user logs in they should see the clubs information specific to their loginID.
I know the syntax to use for the query, its getting the loginname parameter and being able to use/assign it as part of the search that is causing me the problem.
In general it is not recommended to break the default schema of the aspnetdb where the Membership data is stored. It can bring you to unexpected consequences in the future.
I had a similar question a couple of days ago, please check it here, may be you will be able to adopt something from the discussion to your situation.

Resources