主键选择所需的建议

时间:2012-10-08 18:34:49

标签: mysql sql database database-design relational-database

我正在建立一个数据库,用于即将成为我的社交网站版本。现在,我想存储朋友关系,有点像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 个答案:

答案 0 :(得分: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。

答案 1 :(得分:0)

使用相同的模式BIGINT(20)

避免像瘟疫这样的每个用户的表:)

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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