由于您使用的是 Postgres,因此您希望 normalize your tables。归一化的意思,一句话,就是你的列由键、整个键表示,只有键表示。规范化可以是一个三步过程,但我只是要展示最终结果。
通常,在数据库中,表名是单数的。用户、集合、项目。此外,使用表名命名您的 ID 字段也不会造成混淆。它使 join SQL 更易于阅读。
让我们从 User 表开始。
User
----
User ID
User Name
User Email
...
到目前为止,一切都很好。所有列都与用户有关。
接下来,我们来看看Collection
Collection
----------
Collection ID
Collection Name
Owner ID
到目前为止,一切都很好。所有者 ID 是集合所有者的用户 ID。
接下来,我们来看看Item。
Item
----
Item ID
Item Name
Item Description
...
到目前为止,一切都很好。所有的列都与一个项目有关。
现在,让我们看看你在问题 1 中描述的 Collection 和 Item 之间的关系。一个 Collection 可以有一个或多个项目。一个项目可以在一个或多个集合中。
当您具有多对多关系时,您将创建一个联结表。所以让我们创建一个 CollectionItem 联结表。
CollectionItem
--------------
CollectionItem ID
Collection ID
Item ID
CollectionItem timestamp
CollectionItem contributor ID
其中 CollectionItem ID 是主集群键。您在 (Collection ID, Item ID) 上也有一个唯一索引,因此您可以将集合拉到一起。您还可以在 (Item ID, Collection ID) 上有一个唯一索引,这样您就可以看到哪些项目在多个集合中。
您还拥有一个关于(Collection ID、CollectionItem 贡献者 ID)的唯一索引。这使您可以查看哪个贡献者(用户)将项目贡献给集合。此用户 ID 可以是集合行中的所有者 ID,也可以是其他贡献者。
看看问题 2,我们需要一个投票表。 Vote 表是另一个连接集合、项目和投票者(用户)的连接表。
Vote
----
Vote ID
Collection ID
Item ID
Voter ID
Vote timestamp
其中 Vote ID 是主集群键,并且您在 (Collection ID, Item ID, Voter ID) 上有一个唯一索引。您可能还有另外两个唯一索引,具体取决于您是否要按投票者或项目对投票进行分组。
编辑添加:
您还需要某种权限表。
Permission
----------
Permission ID
Owner ID
Contributor ID
其中 Permission ID 是主集群键,并且您在 (Owner ID, Contributor ID) 上有一个唯一索引。你也可以有一个你没有定义的权限类型,所以我不能把它添加到权限表中。权限类型也是唯一索引的一部分。
我希望这个解释对你有所帮助。