Bagaimana cara mendesain tabel basis data hubungan untuk menyimpan hubungan pertemanan?

9

Saya ingin mendesain meja untuk menyimpan hubungan pertemanan di proyek web saya

Setidaknya harus memenuhi 4 kondisi berikut:

yang mengirim permintaan add-friend misalnya (jika A TO B maka kolom ini akan menjadi A)

yang menerima permintaan add-friend misalnya (jika A TO B maka kolom ini akan menjadi B)

status saat ini misalnya (0 menunjukkan ditolak sedangkan 1 menunjukkan diterima atau 2 menunjukkan tidak diproses

hubungan teman kita bersifat bilateral

Jika ada di antara Anda yang berpengalaman dengan ini, ada saran yang disambut

desain saya saat ini (saya pikir buruk sekarang) adalah seperti ini ini adalah kolom

frienshipId  
fromUserId  
toUserId  
status  
requestTime
Hai 福气 鱼
sumber
Dapatkah saya menyarankan menggunakan tampilan kode (sorot teks Anda dan tekan ctrl-k atau letakkan empat spasi sebelum setiap baris) dan sorot DDL Anda sehingga kami dapat melihat bagaimana model data Anda dirancang (atau bagaimana Anda ingin mendesainnya)
jcolebrand
Periksa juga diskusi di sini: stackoverflow.com/questions/10807900/…
Flo
Gunakan basis data grafik. Ini dirancang hanya untuk keadaan ini.
Michael Green
quora.com/…
Vlady Veselinov

Jawaban:

9

Saya akan membuat tabel seperti yang Anda miliki. Saya menggunakan tipe data dan sintaksis SQL Server, Anda mungkin perlu mengubah tergantung pada platform Anda.

CREATE TABLE FriendStatus
(FriendStatusId BIGINT PRIMARY KEY IDENTITY(1,1),
FromUserId BIGINT,
ToUserId BIGINT,
StatusId TINYINT,
SentTime DATETIME2,
ResponseTime DATETIME2);

Pengindeksan tabel akan menjadi penting karena tabel tumbuh hingga puluhan dan ratusan juta.

mrdenny
sumber
Bagaimana dengan indeks utama / kunci utama pada StatusId?
bernd_k
Memperbaiki masalah nama duplikat. Indeks Clustered harus di FriendStatusId. Kunci utama bisa berupa FriendStatusId atau kombinasi dari FromUserId dan ToUserId.
mrdenny
Meskipun jika Anda mengizinkan beberapa permintaan pertemanan, Anda akan menginginkan PK pada FromUserID, ToUserId, SentTime atau Indeks Clustered.
mrdenny
strategi penamaan Anda lebih baik ...
Hai 福气 鱼
8

Di PostgreSQL:

CREATE TABLE users (
    users_id serial PRIMARY KEY,
    name text UNIQUE NOT NULL
);

CREATE TABLE friends (
    friends_id serial PRIMARY KEY,
    timestamp TIMESTAMPTZ default now(),
    user_a integer NOT NULL REFERENCES users,
    user_b integer NOT NULL REFERENCES users,
    status integer NOT NULL default 2
)

Untuk daftar pertemanan, tampilan:

CREATE VIEW friendships AS
    SELECT DISTINCT user_a, user_b FROM friends WHERE status = 1
    UNION
    SELECT DISTINCT user_b, user_a FROM friends WHERE status = 1;

Anda dapat menggunakannya seperti ini:

INSERT INTO users ( name ) VALUES ( 'foo' );
INSERT INTO users ( name ) VALUES ( 'bar' );
INSERT INTO users ( name ) VALUES ( 'baz' );

SELECT * FROM users;
 users_id | name 
----------+------
        1 | foo
        2 | bar
        3 | baz

INSERT INTO FRIENDS ( user_a, user_b, status ) VALUES ( 1, 2, 1 );
INSERT INTO FRIENDS ( user_a, user_b, status ) VALUES ( 2, 1, 1 );
INSERT INTO FRIENDS ( user_a, user_b, status ) VALUES ( 1, 3, 1 );

SELECT * FROM friendships ORDER BY user_a, user_b;
 user_a | user_b 
--------+--------
      1 |      2
      1 |      3
      2 |      1
      3 |      1

SELECT a.name, b.name
    FROM friendships
    JOIN users a ON a.users_id = user_a
    JOIN users b ON b.users_id = user_b
    ORDER BY a.name, b.name;
 name | name 
------+------
 bar  | foo
 baz  | foo
 foo  | bar
 foo  | baz
jkj
sumber
3

Apa yang membuat Anda berpikir desain Anda saat ini buruk? Berikut adalah tabel buat untuk Oracle:

CREATE TABLE IVR.FRIEND (
     FRIENDID   NUMBER(7) NOT NULL 
   , FROMUSERID NUMBER(7) NOT NULL 
   , TOUSERID   NUMBER(7) NOT NULL 
   , STATUSID   NUMBER(2) NOT NULL
   , REQUESTED  DATE      NOT NULL 
   , CONSTRAINT FRIEND_PK PRIMARY KEY (FRIENDID) ENABLE 
);
CREATE SEQUENCE FRIENDIDSEQ;

Jika database adalah Oracle Anda mungkin ingin mempertimbangkan kolom virtual yang diindeks yang akan membatasi data untuk entri yang diperlukan untuk permintaan tertentu. Misalnya, Anda bisa memiliki kolom virtual yang disebut AcceptedFromUserId yang menggunakan fungsi DECODE (StatusId, 1, FromUserId, NULL). Indeks hanya akan berisi AcceptedUserIds dan karenanya akan lebih kecil dari indeks untuk semua UserIds. Jika Anda secara teratur membersihkan permintaan yang ditolak, kolom virtual yang diindeks pada PendingToUserId mungkin lebih berguna.

Alternatif jika Anda mempartisi adalah mempartisi tabel pada StatusId.

Jika Anda tidak memerlukan beberapa permintaan teman di antara pengguna yang sama secara bersamaan, Anda dapat mengabaikan FriendId menggunakan FromUserId, ToUserId, dan StatusId sebagai kunci utama Anda. Dalam hal ini Anda juga harus mempertimbangkan membuat tabel sebagai Tabel yang Terorganisir Indeks.

Leigh Riffel
sumber
-2

Skema:

CREATE TABLE users (
    users_id serial PRIMARY KEY,
    name text UNIQUE NOT NULL
);

CREATE TABLE friends (
    friends_id serial PRIMARY KEY,
    timestamp TIMESTAMPTZ default now(),
    user_a integer NOT NULL REFERENCES users,
    user_b integer NOT NULL REFERENCES users,
    status integer NOT NULL default 2
)

Dari PHP:

select * 
from friends 
where user_a=$myid or user_b=$myid
jiss
sumber
Dan apa yang harus dilakukan dengan kebersamaan? (Dan friendsdefinisi tabelnya dicurigai karena kesalahan sintaksis.)
dezso