我想创建一个 user_widgets 表,该表由 user_id 和 user_widget_id 主键,其中 user_widget_id 像序列一样工作,除了它从每个用户 1 个开始。
对此有通用或实用的解决方案吗?我正在使用 PostgreSQL,但也可以使用不可知论的解决方案。
示例表:user_widgets
| user_id | user_widget_id | user_widget_name |
+-----------+------------------+----------------------+
| 1 | 1 | Andy's first widget |
+-----------+------------------+----------------------+
| 1 | 2 | Andy's second widget |
+-----------+------------------+----------------------+
| 1 | 3 | Andy's third widget |
+-----------+------------------+----------------------+
| 2 | 1 | Jake's first widget |
+-----------+------------------+----------------------+
| 2 | 2 | Jake's second widget |
+-----------+------------------+----------------------+
| 2 | 3 | Jake's third widget |
+-----------+------------------+----------------------+
| 3 | 1 | Fred's first widget |
+-----------+------------------+----------------------+
编辑:
我只是想包括这种设计的一些原因。
1. 减少信息泄露,而不仅仅是“通过默默无闻的安全”
在用户不应该知道彼此的系统中,他们也不应该知道彼此的widget_id。如果这是一张库存表、奇怪的商业机密、发票或其他更敏感的东西,他们就可以开始为这些小部件拥有自己未受影响的 ID 集。除了明显的例行安全检查之外,这还添加了一个隐式安全层,其中必须通过小部件 ID和用户 ID 过滤表。
2. 数据导入
应该允许用户从其他系统导入他们的数据,而不必丢弃他们所有的旧 ID(如果他们有整数 ID)。
3. 清洁度
与我的第一点并没有太大的不同,但我认为创建的内容比其他用户少的用户可能会对他们的小部件 ID 的显着跳跃感到困惑或烦恼。这当然比功能更肤浅,但仍然很有价值。
一个可能的解决方案
其中一个答案表明应用程序层会处理这个问题。我可以在该用户的表上存储一个递增的 next_id 列。或者甚至可能只计算每个用户的行数,并且不允许删除记录(使用删除/停用标志代替)。这可以通过触发器函数,甚至是存储过程而不是在应用程序层中完成吗?