1

I was doing some research on how to store a user's friends in a database and I created my table based on a model I got from this answer here

The person also suggested to set up indexes on the (UserIDLink1, UserIDLink2) and vice versa (UserIDLink2, UserIDLink1). This is a bidirectional relationship also noted by the answer

(A is a friend of B if B is a friend of A)

I'm fairly new to databases but I made these indexes in Postgresql with a btree type and I'm selecting all of the users friends with this:

SELECT u.*
   FROM users u
   INNER JOIN friends f ON u.username = f.username_link1 or u.username = f.username_link2
WHERE f.username_link1 = 'user27' or f.username_link2 = 'user27';

When I use EXPLAIN I see it's still doing a sequence scan on links but maybe this is because I only have one entry in that table right now.

Either way this doesn't seem efficient nor does it look to scale so well. If I have n = 10,000 users the edge case here would be (n^2) entries if every user was friends with every user. Not very likely but if I had 1,000,000 users that would still be a lot of entries in one table for every bidirectional relationship.

The way I'm selecting all these users doesn't look too great either. I have an OR operation which is constant complexity but it doubles the amount of columns it's trying to match.

Maybe I'm wrong but this looks like a future disaster.

Here are my schemas

CREATE TABLE users(
    id              TEXT            PRIMARY KEY NOT NULL,
    username        VARCHAR(15)     NOT NULL UNIQUE,
    first_name      VARCHAR(255)    NOT NULL,
    avatar_url      TEXT            NOT NULL,
);
CREATE TABLE friends(
    username_link1  VARCHAR(15)  NOT NULL REFERENCES users(username) ON DELETE CASCADE,
    username_link2  VARCHAR(15)  NOT NULL REFERENCES users(username) ON DELETE CASCADE,
    PRIMARY KEY (username_link1,username_link2)
);
CREATE INDEX index_link1 ON friends 
(
    // also created the vice versa of this
    user_id_link2 DESC,
    user_id_link1 DESC
);

Can this table be spread out on multiple disks?
Is there a better way to optimize this table?
Would it be better to just create a table for each user that way I can use a simple SELECT * FROM 6762_friends?

Ryan Sam
  • 2,858
  • 4
  • 19
  • 30
  • Does this answer your question? [Are There Bidirectional Relational Databases?](https://stackoverflow.com/questions/40096518/are-there-bidirectional-relational-databases) – philipxy May 05 '20 at 23:58
  • Time to follow a published academic textbook on information modelling, the relational model & DB design & querying. (Manuals for languages & tools to record & use designs are not such textbooks.) (Nor are wiki articles or web posts.) Dozens of published academic information modelling & DB design textbooks are online free in pdf. (But asking for resources outside SO is off-topic.) – philipxy May 06 '20 at 00:01
  • Basic design steps are faqs. So are basics of DBMS optimization/performance--immediately leading to query engine basics & for SQL indexes, plans, statistics & SARGability. [Tips for asking a good SQL question](https://meta.stackoverflow.com/a/271056/3404097) Ask re optimization after you have learned & applied those basics. Before considering posting please read the manual & google any error message or many clear, concise & precise phrasings of your question/problem/goal, with & without your particular strings/names & site:stackoverflow.com & tags; read many answers. – philipxy May 06 '20 at 00:01
  • @philipxy No that doesn't particularly answer my question. I have yet to look over any formal book on RDBMS but I'm sure it would be quite a lot to take in (not saying I wont in the near future). I don't specialize in databases, I work on mostly frontend and backend api stuff. Right now I'm having a problem knowing the correct way to scale this type of table for a MVP. Someone with good knowledge in the field of databases probably knows the answer to my question and could possibly help other people who have yet to dive deep in the world of databases. – Ryan Sam May 06 '20 at 00:43

0 Answers0