Question

For relational databases, there is the notion of ON DELETE CASCADE. When working with JSON, how do these two concepts relate? Is ON DELETE CASCADE supported for JSON?

Can you give an example of a JSON-DB which supports ON DELETE CASCADE or allows some work around for that?

Was it helpful?

Solution

You're confused here,

  • JSON is a data-interchange format, in PostgreSQL we provide json and jsonb as formats with advantages like validation and indexing that help you work with this format.
  • ON DELETE CASCADE is a clause that tells a referring table what to do when the table that it refers to lose the row it's referencing.

You can mix the two concepts, but you should never do this

CREATE TABLE tfoo ( qux jsonb PRIMARY KEY );
CREATE TABLE tbar ( qux jsonb REFERENCES tfoo );
CREATE TABLE tbaz ( qux jsonb REFERENCES tfoo ON DELETE CASCADE );

Now we can insert some test data in tfoo,

INSERT INTO tfoo (qux) VALUES ( '{"id":42}' );
INSERT INTO tfoo (qux) VALUES ( '{"id":7}' );

And you'll get a reject if you try to insert into tbar or tbaz anything but the above,

-- Rejection
INSERT INTO tbar (qux) VALUES ( '{"id":2}' );
ERROR:  insert or update on table "tbar" violates foreign key constraint "tbar_qux_fkey"
DETAIL:  Key (qux)=({"id": 2}) is not present in table "tfoo".

This is a really bad idea though for many reasons. We can see here that these work though,

INSERT INTO tbar (qux) VALUES ( '{"id":42}' );   -- ON DELETE REJECT
INSERT INTO tbaz (qux) VALUES ( '{"id":7}' );    -- ON DELETE CASCADE

And moreover, we can see the effects -- {"id":7} is in tbaz which has the ON DELETE CASCADE

DELETE FROM tfoo WHERE qux = '{"id":7}';

And, this fails as {"id":42} is in tbar and it doesn't know what to do if you remove that entry from tfoo so it rejects the operation.

DELETE FROM tfoo WHERE qux = '{"id":42}';
ERROR:  update or delete on table "tfoo" violates foreign key constraint "tbar_qux_fkey" on table "tbar"                                              
DETAIL:  Key (qux)=({"id": 42}) is still referenced from table "tbar".

Clarification

So you can see you can have ON DELETE CASCADE on any type that can be put on a UNIQUE index (PRIMARY KEY is a special UNIQUE NOT NULL index). This means, you can mix these two concepts, as we did above. But you should never do that, and I've never seen it done in practice. Generally, you put FOREIGN KEYS on int or text,

CREATE TABLE tfoo (
  id_foo int     PRIMARY KEY
    GENERATED BY DEFAULT AS IDENTITY,

  qux    jsonb
);
CREATE TABLE tbar ( id_foo REFERENCES tfoo, qux jsonb );
CREATE TABLE tbaz ( id_foo REFERENCES tfoo ON DELETE CASCADE, qux jsonb );

OTHER TIPS

Adding to Evan's explanation how it should not be done, here is why it should not be done, referring to CouchDB:

https://stackoverflow.com/questions/1951030/does-couchdb-supports-referential-integrity

https://stackoverflow.com/questions/1197449/how-do-i-dry-up-my-couchdb-views

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top