Як створити таблицю бази даних стосунків для зберігання відносин дружби?


9

Я хочу створити таблицю для зберігання відносин дружби у своєму веб-проекті

Він повинен задовольняти принаймні наступним 4 умовам:

які надсилають запит на додавання друзів, наприклад (якщо A TO B, тоді цей стовпець буде A)

які отримують запит на додавання друзів, наприклад (якщо A TO B, тоді цей стовпець буде B)

Поточний статус, наприклад (0 позначає відхилено, тоді як 1 позначає прийняте або 2 позначає необроблений

наші дружні стосунки двосторонні

Якщо хтось із вас відчуває це, будь-яка пропозиція вітається

мій сучасний дизайн (я думаю, погано зараз) такий, як це ці колонки

frienshipId  
fromUserId  
toUserId  
status  
requestTime

Чи можу я запропонувати використовувати перегляд коду (виділіть текст та натисніть ctrl-k або поставте чотири пробіли перед кожним рядком) та виділіть ваш DDL, щоб ми могли бачити, як розроблена ваша модель даних (або як ви хочете її розробити)
jcolebrand

Також перевірте , обговорення тут: stackoverflow.com/questions/10807900 / ...
Фло

Використовуйте базу даних графіків. Вони розроблені саме за таких обставин.
Майкл Грін

Відповіді:


9

Я б створив стільки, як той, який у вас є. Я використовую типи даних і синтаксис даних SQL Server, можливо, вам доведеться налаштувати залежно від вашої платформи.

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

Індексація таблиці буде критичною, оскільки таблиця зростає до десятків і сотень мільйонів.


А як щодо кластеризованого індексу / первинного ключа в StatusId?
bernd_k

Виправлена ​​проблема з іменем дубліката. Індекс кластеру повинен бути на FriendStatusId. Первинним ключем може бути FriendStatusId або комбінація FromUserId і ToUserId.
mrdenny

Хоча якщо ви дозволите кілька запитів друзів, вам потрібна ПК у FromUserID, ToUserId, SentTime або в кластерному індексі.
mrdenny

ваша стратегія іменування краще ...
Привіт 福气 鱼

8

На 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
)

Для перерахування дружби, перегляньте:

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;

Ви можете використовувати його так:

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

3

Що змушує вас вважати ваш сучасний дизайн поганим? Ось таблиця створення для 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;

Якщо база даних Oracle, ви можете розглянути індексований віртуальний стовпець, який обмежить дані записами, необхідними для конкретних запитів. Наприклад, ви можете мати віртуальний стовпець під назвою AcceptedFromUserId, який використовує функцію DECODE (StatusId, 1, FromUserId, NULL). Індекс міститиме лише AcceptedUserIds і тому буде меншим, ніж індекс для всіх UserIds. Якщо ви регулярно очищаєте відхилені запити, індексований віртуальний стовпець у PendingToUserId може бути кориснішим.

Альтернативою, якщо б у вас був розділ, було б розділити таблицю на StatusId.

Якщо вам не потрібно одночасно кілька запитів друзів між одними і тими самими користувачами, ви можете відмовитися від FriendId, використовуючи FromUserId, ToUserId і StatusId в якості основного ключа. У цьому випадку слід також розглянути можливість створення таблиці впорядкованою по таблиці.


-2

Схема:

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
)

Від PHP:

select * 
from friends 
where user_a=$myid or user_b=$myid

А що робити із взаємністю? (І friendsвизначення таблиці є підозрюваним у синтаксичній помилці.)
дез
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.