我想制作一个应用程序,其中会有不同的用户,每个用户都有一组朋友,这些朋友将被分类。会有一些默认类别,但用户可以添加自己的类别。我想知道哪种方法是最好的。
我的想法是有3个表——用户、朋友和类别。
用户表中有朋友和类别的字段(一对多)(但我不知道用户表是否需要任何关于朋友和类别信息)。
friends表有一个类别字段(一对多)和一个用户字段(多对一)。
类别表具有用户(多对多?)和朋友(多对很多?)的字段。
我也不确定他们之间的关系。我将PHP与MySQL、Symfony2和Doctrine2结合使用。请帮忙!
编辑
也许我还没有确切地描述我需要什么。当你打开应用程序时,你会看到一个登录表单。如果你没有账户,你应该注册——注册会创建一个新用户。这个用户没有与其他用户连接(我还是编程新手,我想要一些更简单的东西,所以它有点像电话簿)。每个用户都有一个朋友列表,firend是表中的一行,其中包含姓名、地址、电话、电子邮件、照片、生日等字段,但它们是由当前用户添加的。朋友不是用户。事实上,每个用户都是一个有密码和用户名的帐户,当你登录时,只有一个朋友列表。因此,每个用户都为自己创建类别,而他与其他用户及其类别无关。类别将只有id和名称。
因此,这个想法是,你创建一个帐户,然后创建一些类别,并将朋友添加到其中,只是为了在你的朋友出生或居住的地方,或者哪个是他们的电话号码时,有一个组织者,但你创建了他们,并添加了关于他们的信息,他们是用户自己的。它不像一个社交网络。只是一个笔记本,每个用户都可以写下关于他的朋友的信息。
首先,您需要了解交集表的作用:如果用户A将用户B标记为朋友(即从user
到自身存在多对多关系),并且您创建了一个新表来表示该关系(friends
表),则有关该"友谊"的任何其他信息都应链接到该表。因此,如果用户以某种方式对他的朋友进行分类,则该类别适用于friends
,而不是user
。category
和user
之间没有必要为了这个特定目的而建立关系。
更新:由于朋友不是用户,friends
表将不是交集表(因此只有一个指向user
的引用,表示"所有者"),但答案的其余部分仍然适用。
我假设每个类别都是category
表中的一行。可能会添加有关类别的其他信息,但应仅限于此。例如,如果您想知道是哪个用户创建了一个类别,您可以向user
添加一个外键,例如标记为"owner"或"created_by"。如果一个用户创建的类别不被其他用户看到,这可能会很有用。
最后,您可以将friends
与category
关联起来。如果用户A最多可以将用户B放在一个类别中,那么从friends
到category
的外键就足够了(即一对多关系)。否则,您可能需要另一个多对多关系,因此应该创建一个额外的交集表(例如friend_category
)。
您可以通过使用反规范化来避免这个额外的表,即在friends
中有多行,其中两个用户相同(顺序相同),但类别不同(另请参见本示例)。这是否有利超出了这个答案的范围,但IMHO使用额外的表目前更好(它可能看起来更复杂,但从长远来看会更容易维护)。(更新:如果friends
不是交集表,那么像这样的非规范化实际上不是一个选项,所以请使用friend_category
表)
最后,你的布局会是这样的:
user friends friend_category category
---- ------- --------------- --------
(user fields) <-- user (owner) <-- friend (category fields)
(friend fields) category --> user (owner) --+
^ |
| |
+--------------------------------------------------------------------+
我可以建议为此设置下表(此方案也适用于电话簿或社交网络任务):
存储所有用户信息的表"用户":
- 用户ID
- 名称
- 电话
- 地址
- 。。。(任何其他字段)
存储关系类别信息的表"类别":
- 类别ID
- 名称
存储用户之间关系信息的表"关系":
- FirstUserId->链接到用户表
- SecondUserId->链接到用户表
- CategoryId->链接到Categories表
因此,任何用户都可以添加新的类别,然后在向另一个人添加新关系时引用它们。
如果你需要选择所有用户的朋友,你必须:
select fr.* from Relationships r join Users fr on r.SecondUserId = fr.UserId where r.FirstUserId = <Current user id>