0

我正在为即将成为我的社交网站版本的东西建立一个数据库。现在,我想存储朋友关系,有点像 facebook。我应该提到我正在为此使用 MySQL。

所以我正在考虑做这样的事情:

UserFriends
(
    UserFriendID SOME_DATA_TYPE NOT NULL AUTO_INCREMENT PRIMARY KEY,
    UserID BIGINT(20) UNSIGNED NOT NULL,
    FriendID BIGINT(20) UNSIGNED NOT NULL -- This is basically the same as UserID
)Engine=InnoDB;

现在,我正在寻找某种类型的数据类型用于该表的主键,因为我预计会有大量记录,我想要某种类型的索引来加速任何类型的查找我可能会做的记录。比如朋友推荐功能等。

我愿意接受建议。在我看来,另一个更难管理的选择是为每个用户动态创建一个单独的表并将他们的朋友存储在其中,但是这对于代码管理来说是一场噩梦。

4

4 回答 4

1

如果你做这样的事情

create table UserFriends
(
    UserFriendID SOME_DATA_TYPE NOT NULL AUTO_INCREMENT PRIMARY KEY,
    UserID BIGINT(20) UNSIGNED NOT NULL,
    FriendID BIGINT(20) UNSIGNED NOT NULL -- This is basically the same as UserID
) Engine=InnoDB;

那么您最终可能会得到如下所示的数据。

UserFriendID  UserID  FriendID
--
1             100     201
2             100     201
3             201     100

问题应该很明显。

如果您不需要知道谁与谁成为朋友,那么这样的事情会更有意义。(标准 SQL,不是 MySQL。)

create table UserFriends (
    UserID BIGINT(20) UNSIGNED NOT NULL,
    FriendID BIGINT(20) UNSIGNED NOT NULL,
    primary key (UserID, FriendID),
    check (UserID < FriendID),
    foreign key (UserID) references users (UserID),
    foreign key FriendID references users (UserID)
);

主键约束保证单个“友谊”没有多个相同的行。check() 约束保证您没有两行,仅在 id 编号的顺序上有所不同,用于单个“友谊”。

但是因为 MySQL 不强制 check() 约束,所以您必须编写一个触发器来确保 UserID 小于 FriendID。

于 2012-10-08T18:46:08.640 回答
0

使用相同的模式BIGINT(20)

避免像瘟疫一样每个用户使用一张桌子:)

于 2012-10-08T18:38:30.880 回答
0

只需使用INT。有很多方法可以优化性能,选择不常见的主键数据类型不是其中之一。

不要为每个用户创建一个表。如果你真的有很多用户,你可以在以后知道瓶颈在哪里时,用一些分片键来分割它们。

于 2012-10-08T18:39:14.810 回答
0

如果您期望有足够的记录来填充 INT 数据类型,那么 MySQL 不是正确的解决方案,尤其是对于推荐、多级朋友的朋友的朋友等。它可能更适合那里的图形数据库之一. Neo4j 是一个很好的例子,专为社交网络设计。http://neo4j.org看看,可能是一个不错的选择。您不必摆脱 mysql,它很可能是一种混合方法。

于 2012-10-08T18:56:53.513 回答