1

我想实现一个关注/收藏系统。我可以想到两种实现数据库/表结构的方法,但不确定要实现哪一种。其中哪一项被认为是最佳实践,最重要的是为什么?

我把我所有的追随者放在一个字符串中。通过将所有追随者放在一个字符串中,它减少了冗余行的数量。

前任。

编号 (1) || 用户 ID (1) || follower_ids (2, 3, 45)

'CREATE TABLE `users` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `username` varchar(20) NOT NULL, 
        PRIMARY KEY (`id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1';

'CREATE TABLE `follow` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `user_id` int(10) unsigned NOT NULL,
        `follower_ids` text NOT NULL, 
        PRIMARY KEY (`id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1';

或者

我将每个 follow_id 单独放置,但通过为相同的 user_id 设置 3 行来增加冗余。

前任。

编号 (1) || 用户 ID (1) || 追随者 ID (2)

编号 (2) || 用户 ID (1) || 追随者 ID (3)

编号 (3) || 用户 ID (1) || 追随者 ID (45)

'CREATE TABLE `users` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `username` varchar(20) NOT NULL,
        PRIMARY KEY (`id`) 
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1';

'CREATE TABLE `follow` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `user_id` int(10) unsigned NOT NULL,
        `follower_id` int(10) unsigned NOT NULL,
        PRIMARY KEY (`id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1';
4

2 回答 2

7

您的第二个选项对字段名称稍作修改,因为关注者和关注者都是用户 ID。正如 John 所提到的,将外键添加到下表中的两个 *_user_id 字段。

此外,永远不要有复数表名。“用户”和“关注”就足够了。我个人更喜欢像'follow'这样的表有像'xref_'这样的前缀,所以我知道它只是一个允许多对多关系的交叉引用表(一个用户可以关注许多用户,一个用户可能有很多关注用户)。

'CREATE TABLE `user` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `username` varchar(20) NOT NULL, 
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1';

'CREATE TABLE `follow` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `followed_user_id` int(10) unsigned NOT NULL,
        `follower_user_id` int(10) unsigned NOT NULL,
        PRIMARY KEY (`id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1';
于 2013-02-28T23:38:50.913 回答
4

最好的方法是两者都不是。您应该在跟随表和追随者表之间有一个中间表。中间的表只有两列。follow_id 和 follower_id。使用这种方法,您可以忽略您提到的两种解决方案的缺点。您不必处理字符串,也没有重复条目,并且仅包含索引的性能非常快。

'CREATE TABLE `follow` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        PRIMARY KEY (`id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1';

'CREATE TABLE `user` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `username` varchar(255) unsigned NOT NULL,
        ....
        PRIMARY KEY (`id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1';
'CREATE TABLE `follow_user` (
        `user_id` int(10) unsigned NOT NULL,
        `follower_id` int(10) unsigned NOT NULL,
)

因为您更改了很多帖子,我认为如果关注者与用户相同,您的第二种方法会更好。因为您只存储关注和用户的索引以及一个很好的选择查询来查看单个用户关注的内容比解析和搜索字符串要好得多重复的条目没有问题,因为它们只是索引并且没有问题.

于 2013-02-28T23:12:42.823 回答