Вопрос

Michael Hartl's book shows how to build something similiar to Twitter ending up with a database schema that looks like this:

table: users
  id
  name
  email

table: microposts
  id
  content
  user_id

table: relationships
  id
  follower_id
  followed_id

Suppose I wanted to add private sharing as a feature. The immediate naive attempt would be to change the microposts table to the below where shared_ids has some type that I am unsure of. For someone completely new at SQL and designing schemas what is the standard idiomatic way to solve this problem.

table: microposts
  id
  content
  user_id
  shared_ids
Это было полезно?

Решение

The answer depends on how define "private sharing".

If "private sharing" means "allow all of my followers to see the post, but no one else" then, as suggested by user3019284, adding a single "private" flag to the microposts table would suffice.

table: microposts
  id
  content
  user_id
  private (values: 0=Not private; 1=Private)

But, because you have added the "shared_ids" field to the microposts table, I assume that you want more granular control. So, if "private sharing" means "only share with those followers that I have selected to see this micropost" then, along with a "private" flag on the microposts table, you should create a new table to hold the user id(s) of those who are allowed to view the micropost. Something like:

table: microposts
  id
  content
  user_id
  private (values: 0=Not private; 1=Private)

table: micropost_viewers
  micropost_id
  user_id

Where (micropost_id, user_id) comprise the unique key on the micropost_viewers (there is no need for an "id" column). In addition, put a non-unique index on micropost_viewers.user_id so you can quickly find private microposts that a specific user is allowed to view.

Or, perhaps you want BOTH meanings for "private sharing". In this case, I would suggest:

table: microposts
  id
  content
  user_id
  private (values: 0=Not private; 1=All Followers; 2=Specified Followers)

table: micropost_viewers
  micropost_id
  user_id

When microposts.private = 0, all users can see the micropost.

When microposts.private = 1, all followers can see the micropost.

When microposts.private = 2, only those users whose user id exists in the micropost_viewers table for the microposts.id can view the micropost.

P.S. In extremely rare circumstances would you want to put a list of user ids in a single column (such as shared_ids). The reason is, in a large database, it is extremely inefficient to query against. The only way to find rows related to a specific user is to scan all rows. Whereas, using a separate table with an index on user_id allows you to identify rows for a specific user quite quickly.

Другие советы

Why not just add a new bit column to the microposts table to indicate the post is private? Anyone linked from relationships would be from a private invite.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top