Skip to content
Advertisement

PostgreSQL cyclic foreign keys to multiple tables

I have 3 tables.

chat_room

group_chat_room

private_chat_room

As you can see chat_room has foreign key constraints that refer to group_chat_room and private_chat_room. Also both group_chat_room and private_chat_room have FK constraints that refer to chat_room.

When I want to INSERT a row into group_chat_room I would use this

However because of those constraints this would produce an error

[23503] ERROR: insert or update on table "chat_room" violates foreign key constraint "fk__chat_room__private_chat_room" Detail: Key (id)=(cef8c655-d46a-4f63-bdc8-77113b1b74b4) is not present in table "private_chat_room".

How do I only insert to group_chat_room without having to insert it to private_chat_room?

Advertisement

Answer

The main problem here is creating multiple required bidirectional foreign keys. You can probably work around it, eventually. But it makes the data model more complicated and the code much more so. And it is completely unnecessary. Everything you have can be accomplished with just 1 table. If group_chat_room and private_chat_room are independently required then create a view for each. Further, as simple views, they are fully update-able.
You accomplish this by moving the column ‘pus_code’ to chat_room and adding 2 boolean values to indicate if this is a private or group room or both. Yes, strange as it sounds you can get a private_group_chat_room. (Note: there is nothing in your design preventing it and the error you are getting is because it is required). If you do want that then create a check constraint requiring at least 1 of the boolean columns be false.

See fiddle for full example and a few tests. Note: fiddle has an issue with generate_uuid_v4() (did not exist) so for demo I changed to identity. It will fine in an operational environment.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement