How can I avoid a circular reference situation

Oneiros

Advice on SQL tables, circular reference and foreign keys.

I'm very new to SQL (about a month or so), so please forgive any subsequent unfortunate naivete. I working on a project on stories where a user can start a story and another user can add to that story. At the moment, my two main tables are stories and paragraphs. Stories are made up of paragraphs. Paragraphs are just a chunk of text. The stories schema looks like this:

stid varchar not null primary key,
title text not null,
description text,
created_at timestamptz DEFAULT now()

The paragraph schema looks like this:

prid bigint not null primary key,
story varchar not null REFERENCES stories(stid),
maintext text,
writer text not null REFERENCES users(username),
parentpr bigint, //the previous paragraph
childpr bigint, //the next paragraph
created_at timestamptz DEFAULT now()

I am thinking of adding a headpara and lastpara column to the stories schema (with an ALTER) so I can easily access the first paragraph and last paragraph but that creates circular reference situation, since stories will ref paragraph and vice versa. Is this okay? Will it become a more when I begin to deal with larger amount of data and queries?

I have thought of a solution where I have another table: story-paragraph assignment. schema:

ID primary key
story REFERENCES stories(stid),
headpara REFERENCES paragraph(prid),
lastpara REFERENCES paragraph(prid)

for some reason, I am not convinced of this solution. It feels redundant to me. This is not a many-to-many situation. But paragraphs needs to reference stories and I need to be able access the first paragraph and last paragraph of a story.

Another possible solution could be having two boolean columns in the paragraph schema called head and tail so first paragraph can be called with

WHERE story == stID AND head == True. 

Thoughts? This solution seems like it would be an issue when my paragraph table is very large. Many thanks in advance.

Gordon Linoff

You can do the solution either way. If you know that the head paragraph and last paragraph are really important, then having references to them in the story is fine.

In either case, there is a bit of a challenge maintaining relational integrity. Presumably, you want the head and last paragraphs to be in the same story. For this, you will want a composite key. And you need to add the key using a separate alter table statement. So:

alter table paragraph add constraint unq_paragraph_story_prid unique (story, prid);

alter table stories add constraint fk_stories_headpara
    foreign key (stid, headpara) references paragraph(story, prid);

alter table stories add constraint fk_stories_lastpara
    foreign key (stid, lastpara) references paragraph(story, prid);

Similarly, if you use the flags, you will need to ensure that there is exactly one flag of each type set. That can be a bit of a pain when updating. That constraint would look like:

create unique index unq_paragraph_headpara paragraph(story) where head = 1;

create unique index unq_paragraph_lastpara paragraph(story) where last = 1;

Notes about naming and other things:

  • ids should be numeric, if they can be. This simplifies foreign key references.
  • The name of the id should be completely spelled out (paragraphId or paragraph_id) or simply id. If you use prid, that could get confused with another table.
  • Not all databases support filtered unique indexes. In those cases, you need to use a trigger or another mechanism.

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

How can I resolve this situation with Java Generics?

分類Dev

How can I avoid "environment hell" in postman?

分類Dev

How can I avoid losing precision with ftFmtBcd?

分類Dev

Django conditional queries: How can I avoid this?

分類Dev

How can I avoid duplicate templates in Meteor?

分類Dev

How i can avoid the distinct() of watchdog?

分類Dev

How can I avoid problems with CPU power?

分類Dev

How can I reference a enum in another enum

分類Dev

GNUwin32 make is conflicted with Git, how to avoid this situation?

分類Dev

How can I group by one variable in terms of status of a different variable in a longitudinal situation in R?

分類Dev

Database Design: Circular reference and how to correct it

分類Dev

How can I avoid nested Navigation Bars in SwiftUI?

分類Dev

How can I avoid running some tests in parallel?

分類Dev

How can I avoid Phusion Passenger running as root?

分類Dev

How can I avoid using 'at' in radial-gradient?

分類Dev

How can i avoid Jquery translate `?` to `%3F`

分類Dev

How can I avoid overwriting dynamodb from two lambdas?

分類Dev

EXC_BAD_ACCESS - How can I avoid it?

分類Dev

How can i avoid or pass over a directory that is access denied?

分類Dev

How can I avoid repeating the css and not using !important?

分類Dev

How can I avoid a black background when fading in an overlay with ffmpeg?

分類Dev

Can I reference ResourceResolver?

分類Dev

Can I avoid mutating in this scenario?

分類Dev

How to use forward declaration with boost::msm to avoid circular dependency?

分類Dev

Can I use a circular iPhone app icon?

分類Dev

How to avoid mutable reference to Actor instance

分類Dev

In Ruby, how can I reference a lambda defined in a module?

分類Dev

How can I get a reference to the TFS WorkItem in a WorkItemChangedEvent?

分類Dev

How can I load a VBA library reference and use it in the same procedure?

Related 関連記事

  1. 1

    How can I resolve this situation with Java Generics?

  2. 2

    How can I avoid "environment hell" in postman?

  3. 3

    How can I avoid losing precision with ftFmtBcd?

  4. 4

    Django conditional queries: How can I avoid this?

  5. 5

    How can I avoid duplicate templates in Meteor?

  6. 6

    How i can avoid the distinct() of watchdog?

  7. 7

    How can I avoid problems with CPU power?

  8. 8

    How can I reference a enum in another enum

  9. 9

    GNUwin32 make is conflicted with Git, how to avoid this situation?

  10. 10

    How can I group by one variable in terms of status of a different variable in a longitudinal situation in R?

  11. 11

    Database Design: Circular reference and how to correct it

  12. 12

    How can I avoid nested Navigation Bars in SwiftUI?

  13. 13

    How can I avoid running some tests in parallel?

  14. 14

    How can I avoid Phusion Passenger running as root?

  15. 15

    How can I avoid using 'at' in radial-gradient?

  16. 16

    How can i avoid Jquery translate `?` to `%3F`

  17. 17

    How can I avoid overwriting dynamodb from two lambdas?

  18. 18

    EXC_BAD_ACCESS - How can I avoid it?

  19. 19

    How can i avoid or pass over a directory that is access denied?

  20. 20

    How can I avoid repeating the css and not using !important?

  21. 21

    How can I avoid a black background when fading in an overlay with ffmpeg?

  22. 22

    Can I reference ResourceResolver?

  23. 23

    Can I avoid mutating in this scenario?

  24. 24

    How to use forward declaration with boost::msm to avoid circular dependency?

  25. 25

    Can I use a circular iPhone app icon?

  26. 26

    How to avoid mutable reference to Actor instance

  27. 27

    In Ruby, how can I reference a lambda defined in a module?

  28. 28

    How can I get a reference to the TFS WorkItem in a WorkItemChangedEvent?

  29. 29

    How can I load a VBA library reference and use it in the same procedure?

ホットタグ

アーカイブ