I have a question: we have a table that has (among other stuff) a couple of IP/port pairs that I would like to be globally unique to avoid crosstalk in streaming binaries that use this configuration.
Assume a table as follows
Create table config
(
Id serial NOT NULL,
One_IP text,
One_Port integer,
Two_IP text,
Two_Port integer
);
Then I could add constraints
UNIQUE(One_IP, One_Port)
and
UNIQUE(Two_IP, Two_Port)
This gets me much of the way there. The will be no crosstalk among different rows an each set.
But these are independent of each other – no "One" IP/port pair will repeat and no "Two" IP/Port pair will repeat but I could still have a One IP/Port the same as a two IP/Port (on same or different rows)
Is there a way to create a constraint that combines them? (not a simple 4 column unique)
If I have these rows:
Id | One_IP | One_Port | Two_Ip | Two_Port |
---|---|---|---|---|
1 | 239.1.1.12 | 21 | 239.1.1.13 | 21 |
2 | 239.1.1.12 | 22 | 239.1.1.13 | 22 |
Then I shouldn’t be able to insert any of the following rows …
Id | One_IP | One_Port | Two_Ip | Two_Port |
---|---|---|---|---|
x | 239.1.1.12 | 21 | 239.4.5.6 | 44 |
x | 239.1.1.12 | 22 | 239.4.5.6 | 45 |
x | 239.1.1.13 | 21 | 239.4.5.6 | 46 |
x | 239.1.1.13 | 22 | 239.4.5.6 | 47 |
x | 239.7.8.9 | 81 | 239.1.1.12 | 21 |
x | 239.7.8.9 | 82 | 239.1.1.12 | 22 |
x | 239.7.8.9 | 83 | 239.1.1.13 | 21 |
x | 239.7.8.9 | 84 | 239.1.1.13 | 22 |
2
Answers
Maybe you need to restructure your table
And that way you can put a unique constraint on IP & Port.
OtherPortID has to be NULL so you can insert the first port details when you don’t have the ID of the second port config, but practically you will always populate it.
Any variation on "column1 and column2 and …" indicates a schema design problem. Lists in SQL are represented by join tables.
Also note that Postgres has network address types.
With this design, a device can have as many addresses as it wants, and you can avoid duplicate addresses.
You can pull add the addresses for a single device together by grouping by the device id and using
string_agg
to aggregate all the addresses.Demonstration