为社交网站建立用户之间的友谊模型的最佳方式是什么?
可能的状态是:
- 没有 Friendship
- A 到 B
- FriendRequest,B 需要确认(这是不对称的) A 和 B 是朋友(这是对称的)
现在选择正确的模型很复杂。
我的朋友是我的个人资料的一部分
,这一点非常明显,A.profile.friends 与其他用户是多对多的关系。
- 没有友谊:B不在A.friends中并且A不在B.friends中
- A请求与B建立友谊:B在A.friends中
- 朋友:B在A.friends中并且A在B.friends中
但是合并似乎相当不干净好友与好友请求关系。如果没有这种合并,数据是多余的,因为“A 在 B.friends 中,而不是 B 在 A.friends 中”将是一个未定义的状态。
Friend-Lookup: A.friends.filter(friends__contains=B) #在数据库级别上相当复杂的查找,对编码人员来说不直观
单独的表
FriendRequest 非常明显,一个带有 requester 和 request_user 的类,选择也非常明显。
朋友模型不是很好,因为它将有 person1 和 person2 作为字段,并且所有查找都需要选择具有 person1=A 和 person2=B 或 person1=B 和 person2=A 的朋友
Friend-Lookup: Friend.objects。 filter(person1=A) union Friend.objects.filter(person2=A) #unclean 需要合并两个集合
单独的many2many表
另一个选择是带有friends字段的Friend模型,这是一个Many2many 字段,它链接到恰好两个人。然后选择匹配朋友字段中的一个人,然后只返回模型,其中可以通过从朋友集中减去 A 来提取人 B。但这就太过分了,因为任何朋友对象都不会有超过 2 个人的关联。
好友查找:Friendship.objects.filter(persons__contains=A) #查询两个表
那么,您认为存储好友关系最干净、最直观的解决方案是什么?有没有什么通用的模式可以做到这一点?
What is the best way to model friendships between users for a social networking site?
The possible states are:
- no Friendship
- FriendRequest from A to B, B needs to confirm (this is asymmetric)
- A and B are friends (this is symmetric)
now its complicated to choose the models right.
My Friends are part of my profile
quite obvious, A.profile.friends is a many to many relation to other users.
- no friendship: B not in A.friends and A not in B.friends
- A requests friendship with B: B in A.friends
- Friends: B in A.friends and A in B.friends
but it seems to be rather unclean to merge the friend with the friendrequest relation. and without this merge, the data is redundant, because then "A in B.friends and not B in A.friends" would be an undefined state.
Friend-Lookup: A.friends.filter(friends__contains=B) #rather complicated lookup on db level, unintuitive for coders
Seperate tables
FriendRequest is quite obvious, a class with requester and requested_user, the selects are quite obvious, too.
The Friend Model would be not very nice, because it would have person1 and person2 as fields, and all lookups need to select Friends with person1=A and person2=B OR person1=B and person2=A
Friend-Lookup: Friend.objects.filter(person1=A) union Friend.objects.filter(person2=A) #unclean with the need to union two sets
Seperate many2many table
another option would be a Friend model with a friends field, which is a many2many field, which links to exactly two persons. Then the select is matching one of the persons in the friends field, and then just returns the model, where the person B can be extrated by substracting A from the friends set. But this would be overkill, because no friend-object would ever have more than 2 persons associated.
Friend-Lookup: Friendship.objects.filter(persons__contains=A) #queries two tables
So, what do you think is the cleanest and most intuitive solution to storing a friendship-relation? Are there any common patterns how to do it?
发布评论
评论(3)
如果您不想重新实现所有这些友谊关系内容,您可以使用以下模块: https: //github.com/revsys/django-friendship
它的行为是您在第三个选项中描述的:它创建单独的 ManyToMany 表。一种用于好友请求:
另一种用于好友状态:
它还提供关注、屏蔽和相关管理器。
If you do not want to re-implement all these Friendship relation stuff, you can use the following module: https://github.com/revsys/django-friendship
It's behavior is what you describe in your third option: it creates separate ManyToMany tables. One for the friendship request:
An other one for the friendship status:
It also provides follow, block and related managers.
我相信这是 Django 支持的扩展多对多关系的一个用例: https://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany
您不仅可以存储这些用户之间的连接,还可以存储其他 特性。这应该可以很好地将您的问题域投影到数据库模型上。即,一旦两人之一发起友谊,就创建您的连接,然后设置其他字段来存储谁在询问谁以及对方是否接受了友谊。
I believe this is a use case for the extended many-to-many relationship supported by Django: https://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany
Instead of just storing the connection between those users, you can store additional properties. This should project your problem domain onto the DB model pretty well. Ie create your connection as soon as one of the two initiates the friendship, then set additional fields to store who's asking whom and whether the other person has accepted the friendship.
对于 sql 数据库,我会为此使用多对多关系。但是,如果您认为您将拥有很多用户,您可能需要考虑像flock-db这样的图形数据库,它是专门为此类数据设计的
http://en.wikipedia.org/wiki/Graph_database
(将常规数据保留在 SQL 数据库上,并将关系保留在图形数据库上)
For an sql db, I would use many to many relationship for this. But if you think that you will have a lot of users You might want to consider graph databases like flock-db which is specifically designed for this kind of data
http://en.wikipedia.org/wiki/Graph_database
(Keep your regular data on sql db and keep relationships on graph database)