我有一个购物清单应用程序,用户可以在其中将任意数量的项目拖放到清单中。项目以二维顺序组织,其中每个项目都有一个整数位置,即索引。与该域一样,没有两个项目可以具有相同的位置。
当前在下表中表示:
id list_id name position
------------------------------------
1 1 apple 0
2 1 banana 1
3 1 orange 2
4 2 milk 3
list_id
是另一个表(lists
)的外键。
此表具有以下唯一约束:
ALTER TABLE public.items
ADD CONSTRAINT unique_position
UNIQUE (list_id, position)
DEFERRABLE INITIALLY IMMEDIATE;
这有助于维护数据完整性,并防止应用程序中的错误(或顽皮的用户)导致在完全相同的位置插入两个项目的情况。 (之所以成为DEFERRABLE
的原因是该约束需要推迟到包含多个UPDATE position
语句的事务结束为止。)
现在,我想添加一个功能,用户也可以在主列表内创建子列表,并将项目插入到这些子列表中,以类似的方式进行。
我的计划是向原始sublist_id
表中添加一个items
列:
id list_id name position sublist_id
-----------------------------------------------------
1 1 apple 0 NULL
2 1 banana 1 NULL
3 1 orange 2 NULL
4 2 milk 0 NULL
5 2 chicken 1 NULL
6 2 eggs 2 NULL
7 2 coke NULL 1
8 2 water NULL 1
并引用另一个名为sublists
的表:
id list_id name position_in_list
------------------------------------------
1 2 drinks 3
然后使用名为sublist_items
的第三个表连接两个表:
id sublist_id item_id position
----------------------------------------
1 1 7 0
1 1 8 1
此问题是items
表将某些项目位置列为NULL,因为这些项目现在位于子列表中,并且足以跟踪子列表在主列表中的位置,以及项目在子列表中的位置。
问题1:如何更改原始约束,以便将其应用于两个表?换句话说,我仍然希望列表中的每个项目(无论是item
还是sublist
)都占据唯一的位置,除了来自两个{{1 }}和position
表,其中items
是通用表。
问题2:是否有更好的方法来组织数据?我知道从技术上讲,我不需要第一个表中的sublist_items
列,但我认为我会添加它,以便它允许我编写其他约束,例如“仅当list_id
不为空时,才允许sublist_id
为空”。
答案 0 :(得分:0)
这是一个有趣的问题:)
可以有很多方法来做到这一点。按照我的看法,您可以按照以下步骤操作:
子列表(Sublist_id,名称)(Sublist_id为PK)
项目(item_id,sublist_id,名称)(将Sublist_id设置为非空外键) 从“子列表”表中获取)(item_id为PK)
Items_position (item_id,sublist_id,list_id,位置)(您可以添加 检查约束以检查item_id和sublist_id的组合 应该在Items表中可用)(list_id和位置组合的唯一约束)
子列表:
Sublist_Id Name
0 Dummy
1 Drinks
项目:
Item_Id Sublist_id Name
1 0 Apple
2 0 Eggs
3 1 Water
4 1 Orange
Items_Position:
Item_id Sublist_id List_id Position
1 0 1 1
3 1 1 0
2 0 2 1
4 1 3 1
让我知道以防万一。