【问题标题】:MySQL friends tableMySQL好友表
【发布时间】:2011-03-01 20:27:57
【问题描述】:

我有一个 MySQL 数据库,用于存储每个用户的数据。

我想为每个用户添加一个朋友列表。我应该为数据库中的每个用户创建一个朋友表还是有更好的方法?

【问题讨论】:

  • 友谊是双向的还是单向的?如果皮特是玛丽的朋友,是否总是意味着玛丽也是皮特的朋友?
  • 另请注意,您想要的名称是“交叉表”或“查找表”。如果您熟悉数据库概念,它是多对多表,因为用户可能有很多朋友,也可能与其他人有很多朋友。另请注意,使用此样式,用户可以有一个不是朋友的朋友回来。还有其他方法,但这是最容易实现的。也许更多关于您的交友业务逻辑会有所帮助? @Juha Syrjälä 打败了我!
  • 好友是单向的,必须已经存在于数据库中。这只是您认识的人的提醒列表。
  • 还要注意我关于索引的回答中的 cmets - 没有什么复杂的要求,但您需要添加正确的以保持对较大卷的快速访问(您最终会得到耗时的完整表否则扫描) - 所以不要忽视它们。

标签: mysql database-design data-modeling


【解决方案1】:

为所有朋友创建一个表,并为每个朋友提供一个用户 ID,该用户 ID 等于他们各自的用户密钥

【讨论】:

    【解决方案2】:

    创建一个包含所有朋友的表 表中的每一行都将包含用户的 ID 和他们的朋友的 ID

    【讨论】:

    • 所以对于每个用户的每个朋友,我在一个 2 列表(用户,朋友)中添加一行。例如,如果我有 200 个用户,每个用户有 10 个朋友,那么“Friends”表应该有 2000 行(每个用户 10 个)。我理解正确吗?
    • @asmo 是正确的,但是在这种情况下,您可以使用高度索引优化的表,您不应该害怕超过一百万行的表 - 不会一个问题。
    【解决方案3】:

    假设您的 USER 表有一个名为 id 或类似名称的主键,请使用下表:

    DROP TABLE IF EXISTS `friends`;
    CREATE TABLE `friends` (
      `user_id` int(10) unsigned NOT NULL,
      `friend_id` int(10) unsigned NOT NULL,
      PRIMARY KEY (`user_id`,`friend_id`),
      KEY `FK_FRIENDS_2` (`friend_id`),
      CONSTRAINT `FK_FRIENDS_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
      CONSTRAINT `FK_FRIENDS_2` FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    

    此设置支持 Peter 是 Mary 的朋友,但 Mary 并不这样认为 Peter。但是数据的存在可以推断出彼得是玛丽的熟人……

    作为两列的主键也可以阻止重复。

    【讨论】:

    • 我错过了FK_FRIENDS_1 的分配吗?
    • 使用 user_id 和friend_id 更简洁
    • 如果 user1 是 user3 的朋友,你将插入记录 1,3 并且你想检查 3 的朋友,那么你可以编写查询吗?
    【解决方案4】:

    您正在寻找 M 对 N 或多对多连接表。

    表用户:

    USER_ID  integer primary key,
    NAME     varchar
    

    餐桌上的友谊

    USER_ID    integer not null,
    FRIEND_ID  integer not null,
    

    USER_ID 和 FRIEND_ID 都是引用用户表 (Users.user_id) 的外键。

    如果用户 123 是用户 921 的朋友。将行 (123, 921) 添加到 Friendships 表中。

    【讨论】:

    • 您只显示 2 个表格?一对多还不够吗?
    • 既然用户 921 是 123 的朋友,那么你将如何查询呢?
    【解决方案5】:

    假设您的所有朋友也在 user 表中,您将需要一个定义简单的一对多关系的朋友表 - 将 users 表链接回自身。所以

    User Table
    UserID int identity not null
    [other attribute fields]
    
    Friends Table
    UserIDLink1 int
    UserIDLink2 int 
    [other attribute field]
    

    其中 UserIDLink1 和 UserIDLink2 都是 Users 表上的外键。

    例如,如果我有三个用户

    1 Joe
    2 Bill
    3 Jane
    

    Joe 和 Jane 是朋友,那么 Friends 表将包含一行

    1 3
    

    以上内容隐含假设如果 A 是 B 的朋友,则 B 是 A 的朋友 - 如果不是这种情况,您可能希望将 UserIDLink1 和 UserIDLink2 重命名为 UserID 和 FriendID 或类似的 - 在这种情况下您的记录也将翻倍。

    对于双向配置(如果 B 是 A 的朋友,A 是 B 的朋友),您应该在 Friends 表上为 (UserIDLink1,UserIDLink2) 和 (UserIDLink2,UserIDLink1) 设置索引,以确保访问是如果我们搜索 joe 的朋友或 jane 的朋友,总是有效的(如果您没有设置第二个索引,那么第一个查询将是一个有效的索引查找,但第二个查询需要全表扫描)。

    如果您的链接不是双向的,则无需找出 A 的朋友是谁,但您可能仍然最需要它,因为您可能还需要找出 B 的朋友是谁。

    【讨论】:

    • 我想知道,你如何制定两个外键(userIDLink1 和 userIDLink2)指向同一个主键的连接查询?
    猜你喜欢
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多