PostgreSQL column values must be in a sequence

泄露秘密 提交于 2019-12-22 17:58:09

问题


How would I define a column in PostgreSQL such that each value must be in a sequence, not the sequence you get when using type serial but one such that a value 2 cannot be inserted unless there exists a value 1 already in the column?


回答1:


Theoretically, you could use a constraint that worked like this. (But it won't work in practice.)

  1. Count the rows.
  2. Evaluate max(column) - min(column) + 1.
  3. Compare the results.

You'd probably have to insert one row before creating the CHECK constraint. If you didn't, max(column) would return NULL. With one row,

  1. Count the rows (1).
  2. Evaluate max(column) - min(column) + 1. (1 - 1 + 1 = 1)
  3. Compare the results. (1 = 1)

With 10 rows . .

  1. Count the rows (10).
  2. Evaluate max(column) - min(column) + 1. (10 - 1 + 1 = 10)
  3. Compare the results. (10 = 10)

It doesn't matter whether the sequence starts at 1; this way of checking will always show a gap if one exists. If you needed to guarantee that the gapless sequence started at 1, you could add that to the CHECK constraint.

As far as I know, there isn't any way to do this declaratively with any current dbms. To do it, you'd need support for CREATE ASSERTION. (But I could be wrong.) In PostgreSQL, I think your only shot at this involves procedural code in multiple AFTER triggers.

I only have one table that needs to be gapless. It's a calendar table. We run a query once a night that does these calculations, and it lets me know whether I have a gap.




回答2:


I wrote a detailed example of a gapless sequence implementation using PL/PgSQL here.

The general idea is that you want a table to store the sequence values, and you use SELECT ... FOR UPDATE followed by UPDATE - or the shorthand UPDATE ... RETURNING - to get values from it while locking the row until your transaction commits or rolls back.




回答3:


You write an on insert tigger or a check constraint. However, this will still allow to delete "1" afterwards and "2" stays in the table, you'll probably have to address this too.



来源:https://stackoverflow.com/questions/6988910/postgresql-column-values-must-be-in-a-sequence

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!