我想制作模拟即时信使组策略的用户组系统。
每个用户可以根据需要创建任意数量的组,但他们不能拥有名称重复的组,并且他们可以将任意数量的朋友添加到任何组中。
例如,John的朋友Jen可以同时在约翰的“学校”小组和John的“同事”小组中。并且,它完全独立于Jen如何将John置于她的小组中。
我正在考虑两种可能的方法在数据库user_group表中实现它。
1
user_group (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
group_name VARCHAR(30),
UNIQUE KEY (user_id, group_name)
)
在这种情况下,所有用户拥有的所有组都将具有唯一ID。因此,id本身可以识别哪个用户和组的名称。
2
user_group (
user_id INT,
group_id INT AUTO_INCREMENT,
group_name VARCHAR(30),
PRIMARY KEY (user_id, group_id),
UNIQUE KEY (user_id, group_name)
)
在这种情况下,group_id总是从每个用户的0开始,因此,可能存在许多具有相同group_id的组。但是,pk对(user_id,group_id)在表中是唯一的。
哪种方式更好实现?为什么? 每种情况有哪些优点和缺点?
编辑: 在第二种情况下将AUTO_INCREMENT添加到group_id,以确保为每个user_id从0自动分配。
编辑: '更好'意味着...... - SELECT / INSERT / UPDATE朋友对组的更好性能,因为这将是关于用户组的最常用的操作。 - 数据库的健壮性,就用户规模而言,它更安全。 - 任何一方的受欢迎程度或普遍偏好。 - 灵活性 - 可扩展性 - 可用性 - 更易于使用。
答案 0 :(得分:3)
就个人而言,我会选择第一种方法,但这实际上取决于您的应用程序的工作方式。如果可以更改组的所有权或合并用户配置文件,那么在第一种方法中比在第二种方法中更容易实现。在第二种方法中,如果其中任何一种情况发生,您不仅需要更新user_group
表,还要更新与user_group
具有外键关系的任何相关表。这也是多对多关系(组中将有多个用户,并且用户将是多个组的成员),因此它将需要单独的连接表。在第一种方法中,这是相当简单的:
group_member (
group_id int,
user_id int
)
对于你的第二种方法,它需要第3列,这不仅会更加混乱,因为你现在包括user_id
两次,但也需要33%的额外存储空间(这可能是也可能不是一个问题取决于您对数据库的期望大小):
group_member (
owner_id int,
group_id int,
user_id int
)
此外,如果您计划从MySQL迁移到另一个数据库平台,则可能不支持auto_increment
的此行为。我知道在MS SQL Server中,auto_increment
字段(MSSQL中的identity
)将始终递增,而不是根据表中的索引使其唯一,因此要获得相同的功能,您必须实现它自己。
答案 1 :(得分:0)
请定义“更好”。
从我的直觉中,我会选择第二个。
可搜索的部分被分解得更多,但如果插入/更新性能受到关注,那就不是我所选择的。
答案 2 :(得分:0)
我认为2号没有任何可能的好处,它更复杂,更脆弱(它在SQL Server中根本不起作用)并且什么也得不到。记住groupId没有意义,除了唯一地标识记录,用户可能只会看到组名而不是id。因此,如果它们都从0开始或者由于组被回滚或删除而存在间隙并不重要。