sql >> Database teknologi >  >> RDS >> Oracle

Skinner model med fremmednøgle til sig selv

Så problemet er, at der skal være en bruger øverst i hierarkiet, en bruger for hvem der ikke er nogen manager (redaktør i dit eksempel). Derfor er den klassiske løsning på denne form for struktur at tillade nulværdier. Du anerkender dette i dit afsluttende afsnit:

Kickeren er, hvis den første bruger ikke har en CREATOR eller en EDITOR, så er der ingen "midlertidig":du skal droppe den obligatoriske begrænsning. Hvis du gør dette, vil problemet med den rekursive fremmednøgle-begrænsning forsvinde.

Alternativet er at introducere det, som Aristoteles kaldte en Prim-mover, en Bruger, hvis Skaber er sig selv. Givet denne tabel:

create table t72
( userid number not null
  , creator number not null
  , editor number not null
  , constraint t72_pk primary key (userid)
  , constraint t72_cr_fk foreign key (creator) 
                references t72 (userid)
  , constraint t72_ed_fk foreign key (editor) 
                references t72 (userid)
)
/

det er ret nemt at oprette sådan en bruger:

SQL> insert into t72 values (1,1,1)
  2  /

1 row created.

SQL> commit;

Commit complete.

SQL>

Så hvorfor er dette ikke den kanoniske løsning. Nå, det fører til en lidt skør datamodel, som kan skabe kaos med hierarkiske forespørgsler, når vi tilføjer et par flere brugere.

SQL> select lpad(' ', level-1)|| u.userid as userid
  2          , u.name
  3          , u.editor
  4  from t72 u
  5  connect by
  6     prior userid = editor
  7  start with userid=1
  8  /
ERROR:
ORA-01436: CONNECT BY loop in user data



no rows selected

SQL> 

Grundlæggende kan databasen ikke lide, at USERID er sin egen editor. Der er dog en løsning, som er NOCYCLE søgeord (introduceret med 10g). Dette fortæller databasen at ignorere cirkulære referencer i hierarkiet:

SQL> select lpad(' ', level-1)|| u.userid as userid
  2          , u.name
  3          , u.editor
  4  from t72 u
  5  connect by nocycle
  6     prior userid = editor
  7  start with userid=1
  8  /

USERID     NAME           EDITOR
---------- ---------- ----------
1          ONE                 1
 2         TWO                 1
  3        THREE               2
  4        FOUR                2
  5        FIVE                2
  6        SIX                 2
   7       SEVEN               6

7 rows selected.

SQL>

Her er det ligegyldigt, fordi dataene stadig er korrekt hierarkiske. Men hvad sker der, hvis vi gør dette:

SQL> update t72 set editor = 7
  2  where userid = 1
  3  /

1 row updated.

SQL> 

Vi mister et forhold ( 1 -> 7). Vi kan bruge CONNECT_BY_ISNOCYCLE pseudo-kolonnen til at se, hvilken række der cykler.

SQL> select lpad(' ', level-1)|| u.userid as userid
  2          , u.name
  3          , u.editor
  4          , connect_by_iscycle
  5  from t72 u
  6  connect by nocycle
  7     prior userid = editor
  8  start with userid=1
  9  /

USERID     NAME           EDITOR CONNECT_BY_ISCYCLE
---------- ---------- ---------- ------------------
1          ONE                 7                  0
 2         TWO                 1                  0
  3        THREE               2                  0
  4        FOUR                2                  0
  5        FIVE                2                  0
  6        SIX                 2                  0
   7       SEVEN               6                  1

7 rows selected.

SQL>  

Oracle har masser af ekstra funktionalitet, der gør det nemmere at arbejde med hierarkiske data i ren SQL. Det hele står i dokumentationen. Få mere at vide .



  1. SQL Server Error 206:Operand type sammenstød

  2. Håndtering af BatchUpdateException ved hjælp af withBatch

  3. hvilken forespørgsel skal vi bruge til at opdele 1colmnn i flere kolonner

  4. Sådan opretter du tabel med identitetskolonne