Подтвердить что ты не робот

Как сделать таблицу взаимосвязей SQL-кода многими другими для разных типов

Я новичок в SQL, и я прыгаю в голове, пытаясь как можно больше узнать, как я кодирую, что сложно, поскольку я разрабатываю базу данных, с которой мне придется жить в то время как я хочу убедиться, что я делаю это правильно. Я узнал основы таблиц моста "Множество ко многим", но что, если два поля одного типа? Скажем, социальная сеть с тысячами пользователей, и как бы вы создали таблицу, чтобы отслеживать, кто с кем знаком? Что делать, если есть дополнительные данные о каждой связи, например... например, "date friended". Зная, что будут такие запросы, как "показать всех друзей пользователяX, связанных между датой и датой". У моей базы данных было бы несколько ситуаций, подобных этому, и я не могу найти эффективный способ сделать это. Поскольку для меня это очень важно, я полагаю, что другие выяснили, как лучше всего создавать таблицы, не так ли?

4b9b3361

Ответ 1

Создайте таблицу User, затем таблицу Relationships, в которой вы храните id двух друзей и любую информацию об их отношении.

Диаграмма SQL

SQL diagram

Код MySQL

CREATE TABLE `Users` (
  `id` TINYINT NOT NULL AUTO_INCREMENT DEFAULT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `Relationships` (
  `id` TINYINT NOT NULL AUTO_INCREMENT DEFAULT NULL,
  `userid` TINYINT NULL DEFAULT NULL,
  `friendid` TINYINT NULL DEFAULT NULL,
  `friended` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
);

ALTER TABLE `Relationships` ADD FOREIGN KEY (userid) REFERENCES `Users` (`id`);
ALTER TABLE `Relationships` ADD FOREIGN KEY (friendid) REFERENCES `Users` (`id`);

Выбор SQL

После заполнения таблиц данными вы можете создать запрос SQL SELECT, чтобы получить всех своих друзей. Вашими друзьями являются те, чей id находится на одной стороне, а ваш идентификатор находится на другой стороне. Вы проверяете обе стороны для id, поэтому вам не нужно сохранять отношения дважды. Также вы должны исключить свой id, потому что вы не можете быть вашим собственным другом (в нормальном, здоровом мире).

SELECT *
FROM Users u
   INNER JOIN Relationships r ON u.id = r.userid
   INNER JOIN Relationships r ON u.id = r.friendid
WHERE
   (r.userid = $myid OR r.friendid = $myid)
   AND r.friended >= $startdate
   AND r.friended <= $enddate
   AND u.id != $myid;

Где $myid, $startdate и $enddate могут быть переменными PHP, поэтому в двойных кавычках вы можете передать этот код непосредственно в свою базу данных.

Ответ 2

Достаточно одной таблицы ссылок, например:

People( PersonId bigint, Name nvarchar, etc )
Friends( FromPersonId bigint, ToPersonId bigint, DateAdded datetime )

Пример запросов:

Кто со мной дружит? (т.е. люди, которые добавили меня как друга, но не обязательно ответили)

SELECT
    People.Name
FROM
    Friends
    INNER JOIN People ON Friends.FromPersonId = People.PersonId
WHERE
    Friends.ToPersonId = @myPersonId

Кто добавил меня между двумя датами?

SELECT
    People.Name
FROM
    Friends
    INNER JOIN People ON Friends.FromPersonId = People.PersonId
WHERE
    Friends.ToPersonId = @myPersonId
    AND
    Friends.DateAdded >= @startDate
    AND
    Friends.DateAdded <= @endDate

Ответ 3

Модель

Модель, растягивающаяся на три таблицы, будет вариантом. У вас будет очевидная таблица user со всеми параметрами пользователя (Имя, Дата рождения,...).

CREATE TABLE `user` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45),
  `dob` DATE,
  PRIMARY KEY (`id`)
);

Во-вторых, таблица connection пользователя может содержать привилегии, предоставляемые соединению (может ли это соединение увидеть мой фотоальбом), и, что важно, относится к таблице friendship. Нам нужна таблица connection между ними, потому что один пользователь может быть подключен во многие дружеские отношения.

CREATE TABLE `connection` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `user_id` INT NOT NULL,
  `friendship_id` INT NOT NULL,
  `privilege_mask` TINYINT,
  PRIMARY KEY (`id`)
);

friendship, в свою очередь, может включать общие данные, например, когда эта дружба была установлена. Пользователи, которые подключены к тому же friendship , являются друзьями.

CREATE TABLE `friendship` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `met_first_time` DATE,
  PRIMARY KEY (`id`)
);

Этот путь был бы более реалистичной моделью, чем другие решения, опубликованные до сих пор, поскольку избегает направленности (невзаимная дружба - которая не должна существовать!), но было бы немного больше работы для реализации.

Друзья запросов

Пример, который должен запрашивать имена ваших друзей, может быть (хотя и не протестирован):

SELECT B.name FROM user A
  INNER JOIN connection conn_A ON conn_A.user_id = A.id
    INNER JOIN connection conn_B ON conn_A.friendship_id = conn_B.friendship_id
    INNER JOIN user B ON conn_B.user_id = B.id
    INNER JOIN friendship ON friendship.id = conn_A.friendship_id
  WHERE A.name = 'Dan' AND A.id <> B.id AND
    friendship.met_first_time BETWEEN '2013-4-1' AND '2013-6-30';

Вы можете заметить, что если вам не нужна дата, когда вы подружились, вам не нужно JOIN в таблице friendship, поскольку соединения уже разделяют ключи friendship_id. Суть любого такого запроса заключалась бы в JOIN между conn_A и conn_B на conn_A.friendship_id = conn_B.friendship_id.

Ответ 4

Вы должны использовать идентификатор двух пользователей как PRIMARY KEY в таблице отношений (отношение будет уникальным, даже если оно не двунаправлено). Что-то вроде этого

CREATE TABLE Users (id int (9) NOT NULL AUTO_INCREMENT,
ПЕРВИЧНЫЙ КЛЮЧ (id));

CREATE TABLE Relationships (id1 int (9) NOT NULL, id2 int (9) NOT NULL, friended TIMESTAMP NOT NULL, ПЕРВИЧНЫЙ КЛЮЧ (id1, id2));

Обратите внимание:

  • id1 и ссылка id2 Таблица пользователей (код выше был очень упрощен)
  • даже если отношение не является "двунаправленным", вы можете думать что если у вас есть id1 - id2, кажется, что id1 пользователь добавляет id2 пользователя как друг, но не обязательно наоборот - THEN id2 пользователь может добавить id1 пользователь как друг - в таблице отношений вы можете эти возможные комбинации:
    • id1-id2, (только 1 добавить 2 в качестве друга)
    • id2-id1, (only2 добавить 1 в качестве друга)
    • id1-id2 И id2-id1 (оба - это 2 строки в таблице отношений, и оба являются ВЗАИМНОМ друзья)