sql >> Databáze >  >> RDS >> Oracle

Model kolejnic s cizím klíčem k sobě samému

Problém je tedy v tom, že na vrcholu hierarchie musí být uživatel, pro kterého neexistuje žádný správce (ve vašem příkladu editor). Proto klasickým řešením tohoto druhu struktury je povolit hodnoty null. Berete to na vědomí v závěrečném odstavci:

Hlavní je, že pokud první uživatel nemá Tvůrce nebo EDITORA, pak neexistuje žádné „dočasné“:musíte se vzdát povinného omezení. Pokud to uděláte, problém s rekurzivním omezením cizího klíče zmizí.

Alternativou je představit to, co Aristoteles nazval Prvotním hybatelem, Uživatelem, jehož Stvořitelem je on sám. Vzhledem k této tabulce:

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)
)
/

vytvořit takového uživatele je docela jednoduché:

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

1 row created.

SQL> commit;

Commit complete.

SQL>

Proč to tedy není kanonické řešení. Vede to k trochu šílenému datovému modelu, který může způsobit chaos s hierarchickými dotazy, jakmile přidáme několik dalších uživatelů.

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> 

Databáze se v zásadě nelíbí, že USERID je jejím vlastním editorem. Existuje však řešení, kterým je NOCYCLE klíčové slovo (uvedeno s 10g). To říká databázi, aby ignorovala cyklické odkazy v hierarchii:

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>

Zde to nevadí, protože data jsou stále správně hierarchická. Ale co se stane, když uděláme toto:

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

1 row updated.

SQL> 

Ztrácíme vztah (1 -> 7). Můžeme použít pseudosloupec CONNECT_BY_ISNOCYCLE, abychom viděli, který řádek se cykluje.

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 má spoustu dalších funkcí, které usnadňují práci s hierarchickými daty v čistém SQL. Vše je v dokumentaci. Zjistěte více .



  1. Oprava „CHYBA 1136 (21S01):Počet sloupců neodpovídá počtu hodnot na řádku 1“ při vkládání dat do MariaDB

  2. Laravel / Výmluvný:vnořený WhereHas

  3. Jak určit týden čtvrtletí v dotazu Oracle

  4. Jak propojit Jboss-as-7.1.1 s Postgresql