DEV Community

Cover image for A simple Like is more complicated than you think
IroncladDev
IroncladDev

Posted on

A simple Like is more complicated than you think

You click the like button on a post in social media, on dev.to, or somewhere else. Have you ever gotten to think about how that little button and its system was made? How it worked?

It's not just "oh I pressed the like button". There is actually a lot of code behind it.

If I modeled a post table in SQL, it would look something like this:

CREATE TABLE Post (
  id INTEGER NOT NULL,
  text VARCHAR(500), 
  author VARCHAR(50), 
  PRIMARY KEY (id)
)
Enter fullscreen mode Exit fullscreen mode

If you look in detail, the id key will tell which post it is. The id is the primary key.

The text is a string of 500 chars or less.

The author is a string of 50 chars or less. This is the username of the author in this example.

Now you are probably wondering "hey, you forgot the LIKE stat". I didn't. I will create a new table for that and show you how to link it.

CREATE TABLE Like (
  id INTEGER NOT NULL,
  post_for INTEGER, 
  author VARCHAR(50), 
  PRIMARY KEY (id)
)
Enter fullscreen mode Exit fullscreen mode

The ID is obvious.

The post_for stat determines which post the like has been submitted to. The post's id in this example.

The author is who pressed the like button or submitted the like.

Now, I'll show you how I would link them.
First, I'll let users make posts with text in them.
I will display the text and author of a post when it is submitted. Also, I add a like button in the post route
/post/<post_id>

When the like button is pressed, submit a new like with the author being the user, the post_for stat being the post's id stat.

To calculate how many likes the post has, count all the likes that have the same ID as the post.

And finally make sure that a user can only like a post one time.

Some people prefer other methods and I know that not everyone wants to do this. I just want to explain how complex a simple Like is.

If anything was confusing, please tell me.
Thanks for reading.

Happy Coding.

Discussion (6)

Collapse
ben profile image
Ben Halpern

Oh and the complication doesn't stop there! For example, on DEV we load the state of whether you liked something asynchronously so we can otherwise cache the rest of the page as static HTML shared by all.

Every platform needs to do something to efficiently get you not only the content, but your unique relationship with the content... Choices about the product need a lot of consideration on how the data is fetched and what can be shared and cached, and the choices need to evolve over time to account for different amounts of shared use.

Collapse
cray2015 profile image
cray2015

ben is your architecture available to understand like how things are functioning. i want to understand and read some efficient architectures.

Collapse
ben profile image
Ben Halpern

All the code is public so you're more than welcome to have at it 😄

GitHub logo forem / forem

For empowering community 🌱


Forem 🌱

For Empowering Community

ruby version rails version Travis Status for forem/forem Code Climate maintainability Code Climate technical debt CodeTriage badge Dependabot Badge GitPod badge Netlify badge GitHub code size in bytes GitHub commit activity GitHub issues ready for dev Honeybadger badge Knapsack Pro Parallel CI builds for dev.to

Welcome to the Forem codebase, the platform that powers dev.to. We are so excited to have you. With your help, we can build out Forem’s usability, scalability, and stability to better serve our communities.

What is Forem?

Forem is open source software for building communities. Communities for your peers, customers, fanbases, families, friends, and any other time and space where people need to come together to be part of a collective See our announcement post for a high-level overview of what Forem is.

dev.to (or just DEV) is hosted by Forem. It is a community of software developers who write articles, take part in discussions, and build their professional profiles. We value supportive and constructive dialogue in the pursuit of great code and career growth for all members. The ecosystem spans from beginner to advanced developers, and all are welcome to find their place…

Collapse
sroehrl profile image
neoan

Since you only dove into the table setup, I will have to make the following assumptions which are very relevant for this to work:

  • a username cannot be changed
  • any uniqueness needs to be managed in code

In order to create a secure and performant solution, I suggest the following changes:
Use the user ids instead of strings and make your "post_for" a foreign key relation. Then add a unique key over the combination of author and post_for in the Like table.
I also see no reason in naming the columns author instead of userId or user_id:
If you followed a convention for foreign keys, then your model logic can be abstracted better. So instead of post_for, make it post_id, instead of author, user_id.
This way you can develop a simple orm for relations and as a developer never have to wonder about what your columns are called when your app becomes complicated.

Collapse
gnsp profile image
Ganesh Prasad • Edited on

A real consumer facing implementation would be much more complex than that. Here are a few simple changes to the schema to make the implementation little more efficient:

  1. The like count should be an integer field(column) in each post record (row in the table).

  2. Like table should be indexed on author (assuming author/username is unique). A safer approach is to use an userID as foreign key.

  3. The like relationship between post and user should be cached for better read performance. For each user we can use a set datastructure to cache the post IDs of liked posts.

Collapse
ertra profile image
Tomas Zeman

Well, as other mentioned, this is a very poor database schema design. I don’t recommend to follow advice in your article. Please fix your schema as other people are recommending.

Also under heavy load, calculating the number of likes using the “select count()….” is not recommended at all.