MySQL数据库结构的追随者


MySQL Database Structure for Followers

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

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

id (1) | | user_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行来增加冗余。

id (1) || user_id (1) || follower_id (2)

id (2) || user_id (1) || follower_id (3)

id (3) || user_id (1) || follower_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';

第二个选项稍微修改了字段名,因为follower和following都是user_id的。正如John所提到的,在下表中为*_user_id字段添加外键。

另外,永远不要使用复数表名。"用户"answers"关注"就足够了。我个人更喜欢像"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';

最好的方法是两者都不是。在follow表和follower表之间应该有一个中间表。中间的表只有两列。Follow_id和followers_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,
)

因为你经常更改你的帖子,我认为如果关注者和用户是一样的,你的第二种方法会更好。因为你只存储关注者和用户的索引,一个好的选择查询来查看单个用户关注的内容比解析和搜索字符串要好得多,重复条目没有问题,因为它们只是索引,这没有问题