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.