DEV Community

JongHwa
JongHwa

Posted on

[Simple SNS Project] Step 3. Building the Follow System & Timeline (N:M Relationship)

Introduction

In Step 2, I built a personal feed. Now, in Step 3, I transformed the application into a real social network by implementing the Follow System.
The biggest challenge was modeling the relationship between users and efficiently retrieving the Timeline (a mix of my posts and my friends' posts).


1. Database Modeling: The N:M Relationship

A user can follow many people, and can be followed by many. This is a classic Many-to-Many (N:M) relationship.
To handle this in a Relational Database (MySQL), I introduced a mapping table called Follows.

@Entity
@Table(
    name = "follows",
    uniqueConstraints = {
        @UniqueConstraint(columnNames = {"follower_id", "followee_id"}) // Prevent duplicate follows
    }
)
public class Follow {
    @ManyToOne
    private User follower; // Who follows

    @ManyToOne
    private User followee; // Who is followed
}

Enter fullscreen mode Exit fullscreen mode

I also added a UniqueConstraint to ensure data integrity at the database level, preventing a user from following the same person twice.


2. The Timeline Query: Pull Model

How do we show the timeline?
I adopted the Pull Model (Fan-out on Read) strategy for this stage. When a user requests their timeline, the system dynamically queries the database.

The Logic:

  1. Find all users that I follow.
  2. Extract their IDs.
  3. Query the Feed table using an IN clause.
// FeedRepository.java
Page<Feed> findAllByUserInOrderByCreatedAtDesc(List<User> users, Pageable pageable);

Enter fullscreen mode Exit fullscreen mode

Why this approach?

  • Pros: Simple to implement and data consistency is guaranteed.
  • Cons: As the number of followings grows, the IN query can become slow.
  • Future Improvement: For a large-scale system, I would consider the Push Model (Fan-out on Write), where feeds are pre-distributed to followers' timelines upon creation. But for this project, the Pull Model is sufficient and efficient enough.

3. Frontend Integration

I updated the React frontend to allow users to input a User ID and follow them. The timeline now seamlessly mixes my posts with my friends' posts, sorted by time.


4. Conclusion

Handling relationships is the core of backend development. Through this step, I learned how to map entities using JPA and how to construct complex queries using Spring Data JPA's method naming conventions.

Top comments (0)