SlideShare une entreprise Scribd logo
1  sur  128
Trees in the Database
       Advanced Data Structures




        Lorenzo Alberton
           lorenzo@ibuildings.com
  DPC09, Amsterdam, 13 June 2009
Lorenzo Alberton




                   2
Lorenzo Alberton

                   MDB2
                   Calendar
                   Pager
                   Translation2
                   Mail_Queue
                   DB_QueryTool




                                  2
Lorenzo Alberton

                   MDB2
                   Calendar
                   Pager
                   Translation2
                   Mail_Queue
                   DB_QueryTool




                                  2
Tree

Connected, undirected, acyclic graph


                       A

                 B           C             G

                       D               E


                                       F

                                               3
Tree

Connected, undirected, acyclic graph


                       A

                 B           C

                       D               E


                                       F

                                           3
Tree

Connected, undirected, acyclic graph


                       A

                 B           C

                       D               E


                                       F

                                           3
Tree

Connected, undirected, acyclic graph


                       A

                 B           C

                       D               E


                                       F

                                           3
Tree

Connected, undirected, acyclic graph


                       A

                 B           C

                       D               E


                                       F

                                           3
Adjacency List Model
AKA “parent-child” model




                           4
Adjacency List Model

CREATE TABLE emp_orgchart (
    emp VARCHAR(10) NOT NULL PRIMARY KEY,
    boss VARCHAR(10),
    salary DECIMAL(6,2) NOT NULL
);

                                     A
  emp    boss   salary
   A     NULL   1000.00
                            B               C
   B      A     900.00
   C      A     900.00
   D      C     800.00           D          E   F
   E      C     700.00
   F      C     600.00

                                                    5
Adjacency List Model

  Finding the root node

     SELECT *
       FROM emp_orgchart
      WHERE boss IS NULL;


  Finding the leaf nodes

     SELECT   e1.*
       FROM   emp_orgchart AS e1
  LEFT JOIN   emp_orgchart AS e2 ON e1.emp = e2.boss
      WHERE   e2.emp IS NULL;




                                                   6
Adjacency List Model Anomalies

UPDATE anomalies

  START TRANSACTION;
                         emp     boss   salary
  UPDATE emp_orgchart     A      NULL   1000.00
     SET emp = ‘C1’       B       A     900.00
   WHERE emp = ‘C’;       C1      A     900.00
                          D       C     800.00
  UPDATE emp_orgchart     E       C     700.00
     SET boss = ‘C1’      F       C     600.00
   WHERE boss = ‘C’;

  COMMIT;


                                                  7
Adjacency List Model Anomalies

UPDATE anomalies

  START TRANSACTION;
                         emp     boss   salary
  UPDATE emp_orgchart     A      NULL   1000.00
     SET emp = ‘C1’       B       A     900.00
   WHERE emp = ‘C’;       C1      A     900.00
                          D       C     800.00
  UPDATE emp_orgchart     E       C     700.00
     SET boss = ‘C1’      F       C     600.00
   WHERE boss = ‘C’;

  COMMIT;


                                                  7
Adjacency List Model Anomalies

UPDATE anomalies

  START TRANSACTION;
                        UPDATE emp_orgchart
                           SET emp = CASE emp
  UPDATE emp_orgchart
                                WHEN ‘C’ THEN ‘C1’
     SET emp = ‘C1’
                                ELSE emp END,
   WHERE emp = ‘C’;
                               boss = CASE boss
                                WHEN ‘C’ THEN ‘C1’
  UPDATE emp_orgchart
                                ELSE boss END
     SET boss = ‘C1’
                         WHERE ‘C’ IN (emp, boss);
   WHERE boss = ‘C’;

  COMMIT;


                                                 7
Adjacency List Model Anomalies

INSERT anomalies




                                 8
Adjacency List Model Anomalies

INSERT anomalies

  INSERT INTO emp_orgchart (emp, boss) VALUES
  (‘G’, ‘H’),
  (‘H’, ‘G’);

                   G         H




                                                8
Adjacency List Model Anomalies

INSERT anomalies

  INSERT INTO emp_orgchart (emp, boss) VALUES
  (‘G’, ‘H’),
  (‘H’, ‘G’);

                   G         H



  INSERT INTO emp_orgchart VALUES (‘M’, ‘M’);


                       M


                                                8
Adjacency List Model Anomalies

DELETE anomalies



   DELETE FROM emp_orgchart WHERE emp = ‘C’;




                       A


              B            C


                   D       E     F

                                               9
Adjacency List Model Anomalies

DELETE anomalies



   DELETE FROM emp_orgchart WHERE emp = ‘C’;




                       A


              B            C


                   D       E     F

                                               9
Fixing the Adjacency List Model
 CREATE TABLE emp (
    id INTEGER DEFAULT 0   PRIMARY KEY,
    name VARCHAR(10) NOT   NULL,
    salary DECIMAL (6,2)   NOT NULL
        CHECK (salary >=   0.00),
    ...
 );

 CREATE TABLE orgchart (
    emp_id INTEGER NOT NULL DEFAULT 0 -- vacant
        REFERENCES emp(id)
        ON DELETE SET DEFAULT ON UPDATE CASCADE,
    boss_id INTEGER -- NULL means root node
        REFERENCES emp(id),
    ...
 );

                                                   10
Fixing the Adjacency List Model

 -- cannot be your own boss
 CHECK ((boss_id <> emp_id) OR
        (boss_id = 0 AND emp_id = 0)),




                                         11
Fixing the Adjacency List Model

 -- cannot be your own boss
 CHECK ((boss_id <> emp_id) OR
        (boss_id = 0 AND emp_id = 0)),

 -- prevent longer cycles
 UNIQUE (emp_id, boss_id),




                                         11
Fixing the Adjacency List Model

 -- cannot be your own boss
 CHECK ((boss_id <> emp_id) OR
        (boss_id = 0 AND emp_id = 0)),

 -- prevent longer cycles
 UNIQUE (emp_id, boss_id),

 -- connected graph (edges = nodes - 1)
 CHECK ((SELECT COUNT(*) FROM orgchart) - 1
      = (SELECT COUNT(boss_id) FROM orgchart)),




                                                  11
Fixing the Adjacency List Model

 -- cannot be your own boss
 CHECK ((boss_id <> emp_id) OR
        (boss_id = 0 AND emp_id = 0)),

 -- prevent longer cycles
 UNIQUE (emp_id, boss_id),

 -- connected graph (edges = nodes - 1)
 CHECK ((SELECT COUNT(*) FROM orgchart) - 1
      = (SELECT COUNT(boss_id) FROM orgchart)),

 -- one root only
 CHECK ((SELECT COUNT(*) FROM orgchart WHERE
 boss_id IS NULL) = 1),


                                                  11
Adjacency List Model - Navigation



 Loops /               Self-Joins
 procedural code
                       SELECT o1.emp AS e1,
                              o2.emp AS e2,
 CREATE PROCEDURE
                              o3.emp AS e3
 TreeTraversal (IN
                         FROM emp_orgchart AS o1
 current_emp_id INT)
                         LEFT OUTER JOIN
 BEGIN
                              emp_orgchart AS o2
 ...
                           ON o1.emp = o2.boss
                         LEFT OUTER JOIN
                              emp_orgchart AS o3
                           ON o2.emp = o3.boss
                       WHERE o1.emp = ‘A’;
                                                   12
Adjacency List Model - Deletion




                                  13
Adjacency List Model - Deletion




           A


   B           C



       D       E   F




                                  13
Adjacency List Model - Deletion




           A


   B           C



       D
               x
               E   F




                                  13
Adjacency List Model - Deletion




           A                   A


   B           C       B           C



       D
               x
               E   F       D       E   F




                                           13
Adjacency List Model - Deletion




           A                       A

                                       A
   B           C           B               C



       D
               x
               E   F
                       B       D
                               D
                                           E
                                           E
                                               F
                                               F




                                                   13
Adjacency List Model - Deletion




           A                       A                       A

                                       A
   B           C           B               C       B           C



       D
               x
               E   F
                       B       D
                               D
                                           E
                                           E
                                               F
                                               F       D       E   F




                                                                       13
Adjacency List Model - Deletion




           A                       A                       A

                                       A
   B           C           B               C       B           D
                                                               C



       D
               x
               E   F
                       B       D
                               D
                                           E
                                           E
                                               F
                                               F       D       E   F




                                                                       13
Adjacency List Model - Deletion




           A                               A                       A

                                               A
   B           C                   B               C       B           D
                                                                       C



       D
               x
               E       F
                               B       D
                                       D
                                                   E
                                                   E
                                                       F
                                                       F       D       E   F




                   Requires traversal (deferred constraints)

                                                                               13
Path Enumeration Model
aka Materialized Path




                         14
Path Enumeration Model

CREATE TABLE emp_orgchart (
  emp_id CHAR(1) NOT NULL PRIMARY KEY
    -- if using a separator, don’t use it in the ID
    CHECK (REPLACE(emp_id, ‘/’, ‘’) = emp_id),
  emp_name VARCHAR(10) NOT NULL,
  path_string VARCHAR(512) NOT NULL
);


 emp_id   emp_name   path_string           A
   A      Anthony    A
   B      Beryl      AB
                                   B           C
   C      Charles    AC
   D      Denise     ACD
   E      Ellen      ACE               D       E   F
   F      Frank      ACF
                                                       15
Path Enumeration Model

 -- prevent cycles (nodes appearing twice: ‘ABCA’)
 CHECK (NOT EXISTS(
 SELECT *
    FROM emp_orgchart AS D1,
         emp_orgchart AS P1
  WHERE LENGTH(REPLACE(P1.path_string, D1.emp_id,
         ‘’)) <
        LENGTH(P1.path_string) - LENGTH(D1.emp_id))
 ))


 -- No path can be longer than the number of nodes
 CHECK((SELECT MAX(LENGTH(path_string))
          FROM emp_orgchart AS E1) <=
       (SELECT COUNT(emp_id) * LENGTH(emp_id)
          FROM emp_orgchart AS E2))

                                                 16
Path Enumeration Model




                         17
Path Enumeration Model

  Depth of the node




                         17
Path Enumeration Model

  Depth of the node
  • LENGTH(path_string) / LENGTH(emp_id)




                                           17
Path Enumeration Model

  Depth of the node
  • LENGTH(path_string) / LENGTH(emp_id)
  • LENGTH(path_string) -
    LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1




                                                17
Path Enumeration Model

  Depth of the node
  • LENGTH(path_string) / LENGTH(emp_id)
  • LENGTH(path_string) -
    LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1




                                                17
Path Enumeration Model

  Depth of the node
  • LENGTH(path_string) / LENGTH(emp_id)
  • LENGTH(path_string) -
    LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1


  Searching for subordinates




                                                17
Path Enumeration Model

  Depth of the node
  • LENGTH(path_string) / LENGTH(emp_id)
  • LENGTH(path_string) -
    LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1


  Searching for subordinates
  • SELECT * FROM emp_orgchart
    WHERE path_string LIKE ‘%’ || :parent_emp_id ||
    ‘%’;




                                                      17
Path Enumeration Model

  Depth of the node
  • LENGTH(path_string) / LENGTH(emp_id)
  • LENGTH(path_string) -
    LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1


  Searching for subordinates
  • SELECT * FROM emp_orgchart
    WHERE path_string LIKE ‘%’ || :parent_emp_id ||
    ‘%’;
  • SELECT * FROM emp_orgchart
    WHERE path_string LIKE
      (SELECT path_string FROM emp_orgchart
        WHERE emp_id = :parent_emp_id)        || ‘%’;

                                                      17
Path Enumeration Model

  Searching for superiors

 SELECT SUBSTRING(P1.path_string
        FROM seq * LENGTH(P1.emp_id)
        FOR LENGTH(P1.emp_id)) AS emp_id
   FROM emp_orgchart AS P1,
        sequence AS S1
  WHERE P1.emp_id = :search_emp_id
    AND S1.seq <= LENGTH(path_string)/
                  LENGTH(emp_id);




                                           18
Path Enumeration Model

  Deleting a subtree:

  DELETE FROM emp_orgchart
   WHERE path_string LIKE (
         SELECT path_string
           FROM emp_orgchart
          WHERE emp_id = :deleted_node) || ‘%’;

  Deleting a single node:
     START TRANSACTION;
    DELETE FROM emp_orgchart
     WHERE emp_id = :deleted_node;
    UPDATE emp_orgchart SET path_string =
           REPLACE(path_string, :deleted_node, ‘’);
    COMMIT;
                                                      19
Path Enumeration Model

  Insertion of a new node
  INSERT INTO emp_orgchart VALUES (
    :new_emp_id, -- ‘M’
    :new_name,   -- ‘Maggie’
    (SELECT path_string
       FROM emp_orgchart
      WHERE emp_id = :boss_of_new_emp) -- ‘D’
      || :new_emp_id -- ‘M’
  );

            emp_id   emp_name   path_string

              D      Denise     ACD

              M      Maggie     ACDM

                                                20
Path Enumeration Model

  Insertion of a new node
  INSERT INTO emp_orgchart VALUES (
    :new_emp_id, -- ‘M’
    :new_name,   -- ‘Maggie’
    (SELECT path_string
       FROM emp_orgchart
      WHERE emp_id = :boss_of_new_emp) -- ‘D’
      || :new_emp_id -- ‘M’
  );

            emp_id   emp_name   path_string

              D      Denise     ACD

              M      Maggie     ACDM

                                                20
Path Enumeration Model

  Insertion of a new node
  INSERT INTO emp_orgchart VALUES (
    :new_emp_id, -- ‘M’
    :new_name,   -- ‘Maggie’
    (SELECT path_string
       FROM emp_orgchart
      WHERE emp_id = :boss_of_new_emp) -- ‘D’
      || :new_emp_id -- ‘M’
  );

            emp_id   emp_name   path_string

              D      Denise     ACD

              M      Maggie     ACDM

                                                20
Path Enumeration Model

  Splitting the path string into nodes
  SELECT CASE
         WHEN SUBSTRING(‘/’ || P1.path_string || ‘/’
              FROM S1.seq FOR 1) = ‘/’
         THEN SUBSTRING(‘/’ || P1.path_string || ‘/’
              FROM (S1.seq + 1)
              FOR CharIndex(‘/’ ,
                  ‘/’ || P1.path_string || ‘/’,
                  S1.seq + 1) - S1.seq - 1
         ELSE NULL END AS emp_id
    FROM sequence AS S1,
         emp_orgchart AS P1
   WHERE S1.seq BETWEEN 1
         AND LENGTH(P1.path_string) + 1
     AND SUBSTRING(‘/’ || P1.path_string || ‘/’
         FROM S1.seq FOR 1) = ‘/’
                                                   21
Path Enumeration Model


    emp_name      edge_path           Edge
 Anthony       1.
 Beryl         1.1.
                                      Enumeration
 Charles       1.2.                   Model
 Denise        1.2.1.
 Ellen         1.2.2.
 Frank         1.2.3.
                                      Anthony


                              Beryl             Charles


                                      Denise     Ellen    Frank

                                                                  22
Nested Set Model
aka Modified Preorder Tree Traversal (MPTT)




                                              23
Nested Set Model

                       A
                           C
            B      D       E   F




                                   24
Nested Set Model

                           A
                                   C
             B         D           E       F




                           A
 1                                                               12
         B                             C
     2       3 4                                            11
                       D               E           F
                   5           6   7       8   9       10

                                                                  24
Nested Set Model

CREATE TABLE orgchart (
    emp VARCHAR(10) NOT NULL PRIMARY KEY,
    lft INTEGER NOT NULL,
    rgt INTEGER NOT NULL
);                                   A
                       1                                                       12
                               B                       C
                           2       3 4                                    11
                                             D         E         F
                                         5       6 7       8 9       10




                                                                               25
Nested Set Model

    CREATE TABLE orgchart (
        emp VARCHAR(10) NOT NULL PRIMARY KEY,
        lft INTEGER NOT NULL,
        rgt INTEGER NOT NULL
    );                                   A
                                                1                                                        12
                                                         B                       C
           1           A           12               2        3 4                                    11
                                                                       D         E         F
                                                                   5       6 7       8 9       10

2      B       3               4        C       11




                   D                    E                F
           5               6       7        8        9       10

                                                                                                         25
Nested Set Model
  Finding root node


                              1           A           12




                      2   B       3               4        C       11




                                      D                    E                F
                              5               6       7        8        9       10




                                                                                26
Nested Set Model
  Finding root node
  SELECT *
     FROM orgchart
    WHERE lft = 1;            1           A           12




                      2   B       3               4        C       11




                                      D                    E                F
                              5               6       7        8        9       10




                                                                                26
Nested Set Model
  Finding root node
  SELECT *
     FROM orgchart
    WHERE lft = 1;             1           A           12


  Finding leaf nodes
                       2   B       3               4        C       11




                                       D                    E                F
                               5               6       7        8        9       10




                                                                                 26
Nested Set Model
  Finding root node
  SELECT *
     FROM orgchart
    WHERE lft = 1;              1           A           12


  Finding leaf nodes
  SELECT *
                        2   B       3               4        C       11

    FROM orgchart
   WHERE lft = (rgt - 1);
                                        D                    E                F
                                5               6       7        8        9       10




                                                                                  26
Nested Set Model
  Finding root node
  SELECT *
     FROM orgchart
    WHERE lft = 1;              1           A           12


  Finding leaf nodes
  SELECT *
                        2   B       3               4        C       11

    FROM orgchart
   WHERE lft = (rgt - 1);
                                        D                    E                F
  Finding subtrees              5               6       7        8        9       10




                                                                                  26
Nested Set Model
  Finding root node
  SELECT *
     FROM orgchart
    WHERE lft = 1;                  1           A           12


  Finding leaf nodes
  SELECT *
                          2   B         3               4        C       11

    FROM orgchart
   WHERE lft = (rgt - 1);
                                            D                    E                F
  Finding subtrees                  5               6       7        8        9       10

  SELECT Mgrs.emp AS   boss
         Workers.emp   AS worker
    FROM orgchart AS   Mgrs,
         orgchart AS   Workers
   WHERE Workers.lft   > Mgrs.lft
     AND Workers.lft   < Mgrs.rgt
                                                                                      26
Nested Set Model
  Finding root node
  SELECT *
     FROM orgchart
    WHERE lft = 1;                1           A           12


  Finding leaf nodes
  SELECT *
                          2   B       3               4        C       11

    FROM orgchart
   WHERE lft = (rgt - 1);
                                          D                    E                F
  Finding subtrees                5               6       7        8        9       10

  SELECT Mgrs.emp AS   boss
         Workers.emp   AS worker
    FROM orgchart AS   Mgrs,
         orgchart AS   Workers
   WHERE Workers.lft   > Mgrs.lft
                       BETWEEN Mgrs.lft AND Mgrs.rgt
     AND Workers.lft   < Mgrs.rgt
                                                                                    26
Nested Set Model
  Finding the level of a node




                                27
Nested Set Model
  Finding the level of a node
    SELECT o2.emp,
           COUNT(o1.emp) AS lvl
      FROM orgchart AS o1,
           orgchart AS o2
     WHERE o2.lft BETWEEN o1.lft AND o1.rgt
  GROUP BY o2.emp;




                                              27
Nested Set Model
  Finding the level of a node
    SELECT o2.emp,
           COUNT(o1.emp) AS lvl
      FROM orgchart AS o1,
           orgchart AS o2
     WHERE o2.lft BETWEEN o1.lft AND o1.rgt
  GROUP BY o2.emp;

  Finding the height of the tree




                                              27
Nested Set Model
  Finding the level of a node
    SELECT o2.emp,
           COUNT(o1.emp) AS lvl
      FROM orgchart AS o1,
           orgchart AS o2
     WHERE o2.lft BETWEEN o1.lft AND o1.rgt
  GROUP BY o2.emp;

  Finding the height of the tree
  SELECT MAX(lvl) AS height FROM (
    SELECT o2.emp,
           COUNT(o1.emp) - 1
      FROM orgchart AS o1,
           orgchart AS o2
     WHERE o2.lft BETWEEN o1.lft AND o1.rgt
  GROUP BY o2.emp) AS L1(emp, lvl);

                                              27
Nested Set Model
 Finding relative position
  SELECT CASE
           WHEN :emp1 = :emp2
           THEN :emp1 || ‘ is ’ || :emp2

           WHEN o1.lft BETWEEN o2.lft AND o2.rgt
           THEN :emp1 || ‘ subordinate to ’ || :emp2

           WHEN o2.lft BETWEEN o1.lft AND o1.rgt
           THEN :emp2 || ‘ subordinate to ’ || :emp1

           ELSE :emp1 || ‘ no relation to ’ || :emp2
         END
    FROM orgchart AS o1,
         orgchart AS o2
   WHERE o1.emp = :emp1 AND o2.emp = :emp2;
                                                       28
Nested Set Model
  Deleting subtrees
  DELETE FROM orgchart
   WHERE lft BETWEEN (SELECT      lft
                           FROM   orgchart
                          WHERE   emp = :start_node)
                    AND (SELECT   rgt
                           FROM   orgchart
  Filling gaps            WHERE   emp = :start_node);
 CREATE VIEW   LftRgt (seq) AS
      SELECT   lft FROM orgchart
       UNION   ALL
      SELECT   rgt FROM orgchart;

 UPDATE orgchart SET
 lft = (SELECT COUNT(*) FROM LftRgt WHERE seq <= lft),
 rgt = (SELECT COUNT(*) FROM LftRgt WHERE seq <= rgt)

                                                        29
Nested Set Model
  Deleting a single node

  DELETE FROM orgchart
  WHERE emp = ‘C’;



                               A
                                   C
                B          D       E   F




                                           30
Nested Set Model
  Deleting a single node

  DELETE FROM orgchart
  WHERE emp = ‘C’;



                               A

                B          D       E   F




                                           30
Nested Set Model
  Deleting a single node
  CREATE PROCEDURE downsize(IN removed VARCHAR(10))
  LANGUAGE SQL DETERMINISTIC
  UPDATE orgchart SET emp = CASE
    WHEN orgchart.emp = removed
         AND orgchart.lft + 1 = orgchart.rgt --leaf
    THEN ‘{vacant}’
    WHEN orgchart.emp = removed
         AND orgchart.lft + 1 <> orgchart.rgt
              -- promote subordinate and vacate
    THEN (SELECT o1.emp
            FROM orgchart AS o1
           WHERE orgchart.lft + 1 = o1.lft)
    WHEN orgchart.emp = (SELECT o1.emp
            FROM orgchart AS o1
           WHERE orgchart.lft + 1 = o1.lft)
    THEN ‘{vacant}’ ELSE emp END;
                                                  31
Nested Set Model
  Deleting a single node
  CREATE PROCEDURE downsize(IN removed VARCHAR(10))
  LANGUAGE SQL DETERMINISTIC
  UPDATE orgchart SET emp = CASE
    WHEN orgchart.emp = removed
         AND orgchart.lft + 1 = orgchart.rgt --leaf
    THEN ‘{vacant}’
    WHEN orgchart.emp = removed
         AND orgchart.lft + 1 <> orgchart.rgt
              -- promote subordinate and vacate
    THEN (SELECT o1.emp
            FROM orgchart AS o1
           WHERE orgchart.lft + 1 = o1.lft)
    WHEN orgchart.emp = (SELECT o1.emp
            FROM orgchart AS o1
           WHERE orgchart.lft + 1 = o1.lft)
    THEN ‘{vacant}’ ELSE emp END;
                                                  31
Nested Set to Adjacency List
  SELECT B.id AS boss,
         P.emp, P.lft, P.rgt
    FROM orgchart as P
    LEFT OUTER JOIN emp AS B ON B.lft =
         (SELECT MAX(S.lft)
            FROM orgchart AS S
           WHERE P.lft > S.lft
             AND P.lft < S.rgt);

              boss       emp     lft       rgt
             NULL      Anthony         1         12
             Anthony   Beryl           2          3
             Anthony   Charles         4         11
             Charles   Denise          5          6
             Charles   Ellen           7          8
             Charles   Frank           9         10

                                                      32
Frequent Insertion Trees

Avoid overhead (locking + updating) with larger spreads
and bigger gaps

               emp      lft         rgt
           Anthony            100      1200
           Beryl              200       300
           Charles            400      1100
           Denise             500       600
           Ellen              700       800
           Frank              900      1000




                                                          33
Frequent Insertion Trees

Avoid overhead (locking + updating) with larger spreads
and bigger gaps

               emp      lft         rgt
           Anthony            100      1200
           Beryl              200       300
           Charles            400      1100
           Denise             500       600
           Ellen              700       800
           Frank              900      1000

       Datatype of (lft, rgt)?
       - INTEGER (full range)
       - FLOAT / REAL / DOUBLE
       - NUMERIC(p,s) / DECIMAL(p,s)
                                                          33
Frequent Insertion Trees

Avoid overhead (locking + updating) with larger spreads
and bigger gaps

               emp      lft         rgt
           Anthony            100      1200
           Beryl              200       300
           Charles            400      1100
           Denise             500       600
           Ellen              700       800
           Frank              900      1000

       Datatype of (lft, rgt)?
       - INTEGER (full range)
       - FLOAT / REAL / DOUBLE
       - NUMERIC(p,s) / DECIMAL(p,s)
                                                          33
Frequent Insertion Trees

Avoid overhead (locking + updating) with larger spreads
and bigger gaps

               emp      lft         rgt
           Anthony            100      1200
           Beryl              200       300
           Charles            400      1100
           Denise             500       600
           Ellen              700       800
           Frank              900      1000

       Datatype of (lft, rgt)?
       - INTEGER (full range)
       - FLOAT / REAL / DOUBLE
       - NUMERIC(p,s) / DECIMAL(p,s)
                                                          33
Frequent Insertion Trees

Avoid overhead (locking + updating) with larger spreads
and bigger gaps

               emp      lft         rgt
           Anthony            100      1200
           Beryl              200       300
           Charles            400      1100
           Denise             500       600
           Ellen              700       800
           Frank              900      1000

       Datatype of (lft, rgt)?
       - INTEGER (full range)
       - FLOAT / REAL / DOUBLE
       - NUMERIC(p,s) / DECIMAL(p,s)
                                                          33
Hybrid Models

  Adjacency List with Nested Sets (node, parent, lft, rgt)
  Nested Sets with depth
  Adjacency List with depth
  ...




                Denormalisation to save
                subselects or joins



                                                             34
Nested Intervals
Rational Number Encodings




                            35
Nested Intervals Model

  Rational numbers (a/b, with a and b integers)


   ((p.lft <= c.lft) AND (c.rgt <= p.rgt))



                 0/5         A          5/5




  1/5       B          2/5        3/5         C   4/5


                                                        36
Nested Intervals Model




   a                     b




                             37
Nested Intervals Model




   a                                  b

            a+(b-a)/3    a+2(b-a)/3




                                          37
Nested Intervals Model

  Finding GCD (greatest common divisor)

  CREATE FUNCTION gcd(IN x INTEGER, IN y INTEGER)
  RETURNS INTEGER
  LANGUAGE SQL DETERMINISTIC
  BEGIN

  WHILE x <> y DO
     IF x > y THEN SET x = x - y; END IF;
     IF y > x THEN SET y = y - x; END IF;
  END WHILE;
  RETURN x;

  END;



                                                    38
Nested Intervals Model

  Binary                 Node (x, y)
 Fractions




                                   39
Nested Intervals Model

  Binary                           Node (x, y)
 Fractions



                         First node (1, 1/2)




                                               39
Nested Intervals Model

  Binary                           Node (x, y)
 Fractions



                         First node (1, 1/2)



                                   depth-first
                            convergence point




                                               39
Nested Intervals Model

  Binary                           Node (x, y)
 Fractions
                          First child of first node (1, 3/4)




                         First node (1, 1/2)



                                   depth-first
                            convergence point




                                                       39
Nested Intervals Model

  Binary                           Node (x, y)
 Fractions
                          First child of first node (1, 3/4)




                         First node (1, 1/2)



                                   depth-first
                            convergence point

                                 breadth-first
                            convergence point
                                                       39
Nested Intervals Model

  Binary                           Node (x, y)
 Fractions
                          First child of first node (1, 3/4)




                         First node (1, 1/2)



                                   depth-first
                            convergence point

                                 breadth-first
                            convergence point
                                                       39
Nested Intervals Model

  Binary                           Node (x, y)
 Fractions
                          First child of first node (1, 3/4)




                         First node (1, 1/2)



                                   depth-first
                            convergence point

                                 breadth-first
                            convergence point
                                                       39
Nested Intervals Model




                         40
Nested Intervals Model
                    CREATE FUNCTION x_numer(
                     IN numer INT, IN denom INT
                    ) RETURNS INTEGER
                    BEGIN

                     DECLARE ret_num INTEGER;
                     DECLARE ret_den INTEGER;
                     SET ret_num = numer + 1;
                     SET ret_den = 2 * denom;
                     WHILE FLOOR(ret_num/2)
                           = ret_num/2
                     DO SET ret_num = ret_num/2;
                        SET red_den = ret_den/2;
                     END WHILE;
                     RETURN ret_num;   -- ret_den
                                 -- for x_denom()
                    END;
                                                  40
Nested Intervals Model
CREATE FUNCTION parent_numer(IN numer INTEGER,
IN denom INTEGER) RETURNS INTEGER
LANGUAGE SQL DETERMINISTIC
BEGIN
 DECLARE ret_num INTEGER;
 DECLARE ret_den INTEGER;
 IF numer = 3
    THEN RETURN CAST(NULL AS INTEGER)
 END IF;
 SET ret_num = (numer - 1)/2;
 SET ret_den = denom/2;
 WHILE FLOOR((ret_num - 1)/4) = (ret_num - 1)/4
 DO SET ret_num = (ret_num + 1)/2;
    SET red_den = ret_den/2;
 END WHILE;
 RETURN ret_num; -- ret_den for parent_denom()
END;
                                                  41
Nested Intervals Model

Similar functions for:
  sibling_numer(), sibling_denom()
  child_numer(), child_denom()
  enumerated_path(), distance()
  path_numer(), path_denom()




                                     42
Nested Intervals Model

Similar functions for:
  sibling_numer(), sibling_denom()
  child_numer(), child_denom()
  enumerated_path(), distance()
  path_numer(), path_denom()


INSERT INTO   orgchart (name, numer, denom) VALUES
(‘Anthony’,   path_numer(‘1’),   path_denom(‘1’)),
(‘Beryl’,     path_numer(‘1.1’), path_denom(‘1.1’)),
(‘Charles’,   path_numer(‘1.2’), path_denom(‘1.2’)),
(‘Denise’,    path_numer(‘1.2.1’), path_denom(‘1.2.1’));



                                                      42
Nested Intervals Encodings

  Interval Halving


    average:
    (lft + rgt) / 2




                             43
Nested Intervals Encodings

  Interval Halving


    average:
    (lft + rgt) / 2



  Farey Fractions
  a/b and c/d neighbours
  => bc -ad = 1


   mediant:
   (lft_num + rgt_num)
   (lft_den + rgt_den)


                             43
Nested Intervals Encodings

  Continued Fractions



                                          1.1.2.1


  Reverse (or additive) Continued Fractions




                                                    44
Proprietary Solutions
Oracle




                        45
Oracle: CONNECT BY PRIOR

  Traversing the tree
      SELECT   emp, boss
        FROM   emp_orgchart
       START   WITH boss IS NULL
  CONNECT BY   [NOCYCLE] PRIOR emp = boss;


                        emp     boss
                         A      NULL
                         B       A
                         G       B
                         C       A
                         D       C
                         E       C
                         F       C

                                             46
Oracle: CONNECT BY PRIOR

  Traversing the tree
      SELECT   emp, boss
        FROM   emp_orgchart
       START   WITH boss = ‘C’
                         IS NULL
  CONNECT BY   [NOCYCLE] PRIOR emp = boss;




                        emp     boss
                        D        C
                         E       C
                         F       C



                                             46
Oracle: CONNECT BY PRIOR
  Traversing the tree
         SELECT emp, boss, salary, LEVEL AS lvl,
                   LPAD(' ', 2*(LEVEL-1)) || emp AS tree,
                   CONNECT_BY_IS_LEAF AS is_leaf
            FROM emp_orgchart
   CONNECT BY PRIOR emp = boss
           START WITH boss IS NULL
  ORDER SIBLINGS BY salary DESC;
     emp    boss    salary    lvl       tree    is_leaf
      A     NULL    1000.00    1    A              0
      B      A       900.00    2        B          0
      G      B       800.00    3            G      1
      C      A       900.00    2        C          0
      D      C       800.00    3            D      1
      E      C       700.00    3            E      1
      F      C       600.00    3            F      1
                                                          47
Oracle: CONNECT BY PRIOR

  Determining the relationship between two nodes

   SELECT COUNT(*) AS ‘is_subordinate’
     FROM emp_orgchart
    WHERE emp = :subordinate
      AND LEVEL > 1
    START WITH emp = :superior
  CONNECT BY PRIOR emp = boss;




                                                   48
Oracle: CONNECT BY PRIOR

  Determining the relationship between two nodes

   SELECT COUNT(*) AS ‘is_subordinate’
     FROM emp_orgchart
    WHERE emp = :subordinate
      AND LEVEL > 1
    START WITH emp = :superior
  CONNECT BY PRIOR emp = boss;



                  A subordinate of C? 0
                  F subordinate of A? 1


                                                   48
Oracle: CONNECT_BY_ROOT

 Determining the ancestor of a node

      SELECT emp_id,
             CONNECT_BY_ROOT emp_id AS root
        FROM orgchart
  START WITH boss = ‘A’
  CONNECT BY PRIOR emp_id = boss;


                  emp_id          root
                    B               B
                    G               B
                    C              C
                    D              C
                    E              C
                    F              C

                                              49
Oracle: SYS_CONNECT_BY_PATH

 Materialized Path View
      SELECT emp_id,
             SYS_CONNECT_BY_PATH (emp_id,'.')
             AS path_string
        FROM orgchart
  START WITH boss IS NULL
  CONNECT BY PRIOR emp_id = boss
    ORDER BY 2;
                          emp_id     path_string
                   A               .A
                   B               .A.B
                   C               .A.C
                   D               .A.C.D
                   E               .A.C.E
                   F               .A.C.F

                                                   50
Common Table Expressions
SQL-99 Standard




                           51
Common Table Expressions
CREATE TABLE emp_orgchart (
  emp VARCHAR(10) PRIMARY KEY,
  boss VARCHAR(10) REFERENCES emp_orgchart(emp_id),
  salary TEXT
);

INSERT   INTO emp_orgchart (emp, boss, salary) VALUES
 (‘A’,   NULL, 1000.00),
 (‘B’,   ‘A’, 900.00),
 (‘C’,   ‘A’, 900.00),               A
 (‘D’,   ‘C’, 800.00),
 (‘E’,   ‘C’, 700.00),
 (‘F’,   ‘C’, 600.00),        B            C
 (‘G’,   ‘B’, 800.00);

                          G        D       E      F

                                                        52
Common Table Expressions

WITH RECURSIVE hierarchy AS (
  -- non recursive term
  SELECT *
    FROM emp_orgchart
   WHERE boss IS NULL
  UNION ALL
  -- recursive term
  SELECT E1.*
    FROM emp_orgchart AS E1
    JOIN hierarchy AS E2
      ON E1.boss = E2.emp
)
  SELECT *
    FROM hierarchy
ORDER BY emp;


                                53
Common Table Expressions

WITH RECURSIVE hierarchy AS (
  -- non recursive term
  SELECT *
    FROM emp_orgchart
   WHERE boss IS NULL
  UNION ALL
  -- recursive term
  SELECT E1.*
    FROM emp_orgchart AS E1
    JOIN hierarchy AS E2
      ON E1.boss = E2.emp
)
  SELECT *
    FROM hierarchy
ORDER BY emp;


                                53
Common Table Expressions

WITH RECURSIVE hierarchy AS (
  -- non recursive term
  SELECT *
    FROM emp_orgchart
   WHERE boss IS NULL
  UNION ALL
  -- recursive term
  SELECT E1.*
    FROM emp_orgchart AS E1
    JOIN hierarchy AS E2
      ON E1.boss = E2.emp
)
  SELECT *
    FROM hierarchy
ORDER BY emp;


                                53
Common Table Expressions

WITH RECURSIVE hierarchy AS (
  -- non recursive term
  SELECT *
    FROM emp_orgchart
   WHERE boss IS NULL           emp   boss   salary
  UNION ALL                      A    NULL   1000.00
  -- recursive term              B     A      900.00
  SELECT E1.*                    C     A      900.00
    FROM emp_orgchart AS E1      D     C      800.00
    JOIN hierarchy AS E2
                                 E     C      700.00
      ON E1.boss = E2.emp
                                 F     C      600.00
)
  SELECT *                       G     B      800.00
    FROM hierarchy
ORDER BY emp;


                                                       53
Common Table Expressions
WITH RECURSIVE hierarchy AS (
  SELECT *,
         1 AS lvl,
         CAST(emp AS TEXT) AS tree,
         emp || ‘.’ AS path
    FROM emp_orgchart
   WHERE boss IS NULL
  UNION ALL
  SELECT E1.*,
         E2.lvl + 1 AS lvl,
         LPAD(E1.emp, lvl * 2, ‘ ’) AS tree,
         E2.path || E1.emp || ‘.’ AS path
    FROM emp_orgchart
    JOIN hierarchy AS E2
      ON E1.boss = E2.emp
)
  SELECT *
    FROM hierarchy
ORDER BY path;
                                               54
Common Table Expressions
WITH RECURSIVE hierarchy AS (
  SELECT *,
         1 AS lvl,
         CAST(emp AS TEXT) AS tree,
         emp || ‘.’ AS path
    FROM emp_orgchart
   WHERE boss IS NULL
  UNION ALL
  SELECT E1.*,
         E2.lvl + 1 AS lvl,
         LPAD(E1.emp, lvl * 2, ‘ ’) AS tree,
         E2.path || E1.emp || ‘.’ AS path
    FROM emp_orgchart
    JOIN hierarchy AS E2
      ON E1.boss = E2.emp
)
  SELECT *
    FROM hierarchy
ORDER BY path;
                                               54
Common Table Expressions
WITH RECURSIVE hierarchy AS (
  SELECT *,
         1 AS lvl,
         CAST(emp AS TEXT) AS tree,
         emp || ‘.’ AS path
    FROM emp_orgchart
   WHERE boss IS NULL
  UNION ALL
  SELECT E1.*,
         E2.lvl + 1 AS lvl,
         LPAD(E1.emp, lvl * 2, ‘ ’) AS tree,
         E2.path || E1.emp || ‘.’ AS path
    FROM emp_orgchart
    JOIN hierarchy AS E2
      ON E1.boss = E2.emp
)
  SELECT *
    FROM hierarchy
ORDER BY path;
                                               54
Common Table Expressions
WITH RECURSIVE hierarchy AS (
  SELECT *,
         1 AS lvl,
         CAST(emp AS TEXT) AS tree,
         emp || ‘.’ AS path
    FROM emp_orgchart
   WHERE boss IS NULL
  UNION ALL
  SELECT E1.*,
         E2.lvl + 1 AS lvl,
         LPAD(E1.emp, lvl * 2, ‘ ’) AS tree,
         E2.path || E1.emp || ‘.’ AS path
    FROM emp_orgchart
    JOIN hierarchy AS E2
      ON E1.boss = E2.emp
)
  SELECT *
    FROM hierarchy
ORDER BY path;
                                               54
Common Table Expressions
WITH RECURSIVE hierarchy AS (
  SELECT *,
         1 AS lvl,
         CAST(emp AS TEXT) AS tree,
         emp || ‘.’ AS path
    FROM emp_orgchart
   WHERE boss IS NULL
  UNION ALL
  SELECT E1.*,
         E2.lvl + 1 AS lvl,
         LPAD(E1.emp, lvl * 2, ‘ ’) AS tree,
         E2.path || E1.emp || ‘.’ AS path
    FROM emp_orgchart
    JOIN hierarchy AS E2
      ON E1.boss = E2.emp
)
  SELECT *
    FROM hierarchy
ORDER BY path;
                                               54
Common Table Expressions
WITH RECURSIVE hierarchy AS (
  SELECT *,
         1 AS lvl,
  emp    CAST(emp salary
         boss     AS TEXT) AS tree, tree
                            lvl                 path
         emp || ‘.’ AS path
   A     NULL     1000.00    1   A         A.
    FROM emp_orgchart
   WHERE boss IS NULL
   B       A       900.00    2     B       A.B.
  UNION ALL
  SELECT E1.*,
   G       B       800.00    3        G    A.B.G.
         E2.lvl + 1 AS lvl,
   C     LPAD(E1.emp, lvl * 2, ‘ ’)CAS tree,
           A       900.00    2             A.C.
         E2.path || E1.emp || ‘.’ AS path
   D       C       800.00
    FROM emp_orgchart        3        D    A.C.D.
    JOIN hierarchy AS E2
   E       C       700.00    3        E    A.C.E.
      ON E1.boss = E2.emp
) F        C       600.00    3        F    A.C.F.
  SELECT *
    FROM hierarchy
ORDER BY path;
                                                       54
Common Table Expressions

WITH RECURSIVE hierarchy AS (
  SELECT *,
         1 AS lvl,
         CAST(emp AS TEXT) AS tree
    FROM emp_orgchart
   WHERE boss = ‘A’
  UNION ALL
  SELECT E1.*,
         E2.lvl + 1 AS lvl,
         LPAD(E1.emp, depth * 2, ‘ ’) AS tree
    FROM emp_orgchart
    JOIN hierarchy AS E2 ON E1.boss = E2.emp
   WHERE E2.lvl < 3 -- termination condition
)
  SELECT *
    FROM hierarchy
ORDER BY path;

                                                55
Common Table Expressions
WITH RECURSIVE hierarchy AS (
  SELECT *,
         1 AS lvl,
         CAST(emp AS TEXT) AS tree
    FROM emp_orgchart
   WHERE boss = ‘A’
  UNION ALL
  SELECT E1.*,
         E2.lvl + 1 AS lvl,
         LPAD(E1.emp, depth * 2, ‘ ’) AS tree
    FROM emp_orgchart
    JOIN hierarchy AS E2 ON E1.boss = E2.emp
)
SELECT *,
       COALESCE((SELECT 0 FROM emp_orgchart E3
                  WHERE hierarchy.emp = E3.boss
                  FETCH FIRST ROW ONLY), 1) AS is_leaf
    FROM hierarchy;

                                                         56
And the winner is...




                       57
And the winner is...




                       57
Questions ?




              58
Resources
Joe Celko, “Trees and Hierarchies in SQL for
Smarties”, Morgan Kaufmann:
http://www.amazon.com/dp/1558609202/



Vadim Tropashko, various articles and papers:

http://www.dbazine.com/top-auth/top-auth-trop/
http://www.sigmod.org/sigmod/record/issues/
0506/p47-article-tropashko.pdf
http://arxiv.org/pdf/cs/0402051



                                                 59
Thank you!
            Contact details:

    Lorenzo Alberton
     lorenzo@ibuildings.com
    http://www.alberton.info
http://joind.in/talk/view/585

Contenu connexe

Tendances

Introduction to SQL Antipatterns
Introduction to SQL AntipatternsIntroduction to SQL Antipatterns
Introduction to SQL AntipatternsKrishnakumar S
 
Apache doris (incubating) introduction
Apache doris (incubating) introductionApache doris (incubating) introduction
Apache doris (incubating) introductionleanderlee2
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix itRafael Dohms
 
Pyspark Tutorial | Introduction to Apache Spark with Python | PySpark Trainin...
Pyspark Tutorial | Introduction to Apache Spark with Python | PySpark Trainin...Pyspark Tutorial | Introduction to Apache Spark with Python | PySpark Trainin...
Pyspark Tutorial | Introduction to Apache Spark with Python | PySpark Trainin...Edureka!
 
Data Federation with Apache Spark
Data Federation with Apache SparkData Federation with Apache Spark
Data Federation with Apache SparkDataWorks Summit
 
Clean Architecture Applications in Python
Clean Architecture Applications in PythonClean Architecture Applications in Python
Clean Architecture Applications in PythonSubhash Bhushan
 
HBaseCon 2012 | Lessons learned from OpenTSDB - Benoit Sigoure, StumbleUpon
HBaseCon 2012 | Lessons learned from OpenTSDB - Benoit Sigoure, StumbleUponHBaseCon 2012 | Lessons learned from OpenTSDB - Benoit Sigoure, StumbleUpon
HBaseCon 2012 | Lessons learned from OpenTSDB - Benoit Sigoure, StumbleUponCloudera, Inc.
 
Laravel Design Patterns
Laravel Design PatternsLaravel Design Patterns
Laravel Design PatternsBobby Bouwmann
 
Couchdb List and Show Introduction
Couchdb List and Show IntroductionCouchdb List and Show Introduction
Couchdb List and Show IntroductionOliver Kurowski
 
Percona Live 2012PPT: MySQL Query optimization
Percona Live 2012PPT: MySQL Query optimizationPercona Live 2012PPT: MySQL Query optimization
Percona Live 2012PPT: MySQL Query optimizationmysqlops
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event LoopDesignveloper
 
Elegant and Scalable Code Querying with Code Property Graphs
Elegant and Scalable Code Querying with Code Property GraphsElegant and Scalable Code Querying with Code Property Graphs
Elegant and Scalable Code Querying with Code Property GraphsConnected Data World
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and EffectsMartin Odersky
 
Software Design Patterns in Laravel by Phill Sparks
Software Design Patterns in Laravel by Phill SparksSoftware Design Patterns in Laravel by Phill Sparks
Software Design Patterns in Laravel by Phill SparksPhill Sparks
 

Tendances (20)

Monadic Java
Monadic JavaMonadic Java
Monadic Java
 
Introduction to SQL Antipatterns
Introduction to SQL AntipatternsIntroduction to SQL Antipatterns
Introduction to SQL Antipatterns
 
How to Use JSON in MySQL Wrong
How to Use JSON in MySQL WrongHow to Use JSON in MySQL Wrong
How to Use JSON in MySQL Wrong
 
Extensible Data Modeling
Extensible Data ModelingExtensible Data Modeling
Extensible Data Modeling
 
Apache doris (incubating) introduction
Apache doris (incubating) introductionApache doris (incubating) introduction
Apache doris (incubating) introduction
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
Pyspark Tutorial | Introduction to Apache Spark with Python | PySpark Trainin...
Pyspark Tutorial | Introduction to Apache Spark with Python | PySpark Trainin...Pyspark Tutorial | Introduction to Apache Spark with Python | PySpark Trainin...
Pyspark Tutorial | Introduction to Apache Spark with Python | PySpark Trainin...
 
Data Federation with Apache Spark
Data Federation with Apache SparkData Federation with Apache Spark
Data Federation with Apache Spark
 
Load Data Fast!
Load Data Fast!Load Data Fast!
Load Data Fast!
 
Clean Architecture Applications in Python
Clean Architecture Applications in PythonClean Architecture Applications in Python
Clean Architecture Applications in Python
 
HBaseCon 2012 | Lessons learned from OpenTSDB - Benoit Sigoure, StumbleUpon
HBaseCon 2012 | Lessons learned from OpenTSDB - Benoit Sigoure, StumbleUponHBaseCon 2012 | Lessons learned from OpenTSDB - Benoit Sigoure, StumbleUpon
HBaseCon 2012 | Lessons learned from OpenTSDB - Benoit Sigoure, StumbleUpon
 
Laravel Design Patterns
Laravel Design PatternsLaravel Design Patterns
Laravel Design Patterns
 
Couchdb List and Show Introduction
Couchdb List and Show IntroductionCouchdb List and Show Introduction
Couchdb List and Show Introduction
 
How to Design Indexes, Really
How to Design Indexes, ReallyHow to Design Indexes, Really
How to Design Indexes, Really
 
Percona Live 2012PPT: MySQL Query optimization
Percona Live 2012PPT: MySQL Query optimizationPercona Live 2012PPT: MySQL Query optimization
Percona Live 2012PPT: MySQL Query optimization
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Elegant and Scalable Code Querying with Code Property Graphs
Elegant and Scalable Code Querying with Code Property GraphsElegant and Scalable Code Querying with Code Property Graphs
Elegant and Scalable Code Querying with Code Property Graphs
 
Preparing for Scala 3
Preparing for Scala 3Preparing for Scala 3
Preparing for Scala 3
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 
Software Design Patterns in Laravel by Phill Sparks
Software Design Patterns in Laravel by Phill SparksSoftware Design Patterns in Laravel by Phill Sparks
Software Design Patterns in Laravel by Phill Sparks
 

En vedette

Network Intent Composition in OpenDaylight
Network Intent Composition in OpenDaylightNetwork Intent Composition in OpenDaylight
Network Intent Composition in OpenDaylightOpenDaylight
 
Hadoop-DS: Which SQL-on-Hadoop Rules the Herd
Hadoop-DS: Which SQL-on-Hadoop Rules the HerdHadoop-DS: Which SQL-on-Hadoop Rules the Herd
Hadoop-DS: Which SQL-on-Hadoop Rules the HerdIBM Analytics
 
HBaseCon2017 Transactions in HBase
HBaseCon2017 Transactions in HBaseHBaseCon2017 Transactions in HBase
HBaseCon2017 Transactions in HBaseHBaseCon
 
Scaling Teams, Processes and Architectures
Scaling Teams, Processes and ArchitecturesScaling Teams, Processes and Architectures
Scaling Teams, Processes and ArchitecturesLorenzo Alberton
 
Scalable Architectures - Taming the Twitter Firehose
Scalable Architectures - Taming the Twitter FirehoseScalable Architectures - Taming the Twitter Firehose
Scalable Architectures - Taming the Twitter FirehoseLorenzo Alberton
 
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle TreesModern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle TreesLorenzo Alberton
 
The Art of Scalability - Managing growth
The Art of Scalability - Managing growthThe Art of Scalability - Managing growth
The Art of Scalability - Managing growthLorenzo Alberton
 
Monitoring at scale - Intuitive dashboard design
Monitoring at scale - Intuitive dashboard designMonitoring at scale - Intuitive dashboard design
Monitoring at scale - Intuitive dashboard designLorenzo Alberton
 
NoSQL Databases: Why, what and when
NoSQL Databases: Why, what and whenNoSQL Databases: Why, what and when
NoSQL Databases: Why, what and whenLorenzo Alberton
 
MySQL Group Replication
MySQL Group ReplicationMySQL Group Replication
MySQL Group ReplicationKenny Gryp
 
Inno db internals innodb file formats and source code structure
Inno db internals innodb file formats and source code structureInno db internals innodb file formats and source code structure
Inno db internals innodb file formats and source code structurezhaolinjnu
 
MySQL InnoDB Cluster - Group Replication
MySQL InnoDB Cluster - Group ReplicationMySQL InnoDB Cluster - Group Replication
MySQL InnoDB Cluster - Group ReplicationFrederic Descamps
 
Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication
Percona XtraDB Cluster vs Galera Cluster vs MySQL Group ReplicationPercona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication
Percona XtraDB Cluster vs Galera Cluster vs MySQL Group ReplicationKenny Gryp
 
MySQL Best Practices - OTN LAD Tour
MySQL Best Practices - OTN LAD TourMySQL Best Practices - OTN LAD Tour
MySQL Best Practices - OTN LAD TourRonald Bradford
 
MySQL 5.7: Focus on InnoDB
MySQL 5.7: Focus on InnoDBMySQL 5.7: Focus on InnoDB
MySQL 5.7: Focus on InnoDBMario Beck
 
Mysql参数-GDB
Mysql参数-GDBMysql参数-GDB
Mysql参数-GDBzhaolinjnu
 
MySQL Group Replication
MySQL Group ReplicationMySQL Group Replication
MySQL Group ReplicationManish Kumar
 
Using Apache Spark and MySQL for Data Analysis
Using Apache Spark and MySQL for Data AnalysisUsing Apache Spark and MySQL for Data Analysis
Using Apache Spark and MySQL for Data AnalysisSveta Smirnova
 
MySQL High-Availability and Scale-Out architectures
MySQL High-Availability and Scale-Out architecturesMySQL High-Availability and Scale-Out architectures
MySQL High-Availability and Scale-Out architecturesFromDual GmbH
 
MySQL InnoDB Cluster and MySQL Group Replication @HKOSC 2017
MySQL InnoDB Cluster and MySQL Group Replication @HKOSC 2017MySQL InnoDB Cluster and MySQL Group Replication @HKOSC 2017
MySQL InnoDB Cluster and MySQL Group Replication @HKOSC 2017Ivan Ma
 

En vedette (20)

Network Intent Composition in OpenDaylight
Network Intent Composition in OpenDaylightNetwork Intent Composition in OpenDaylight
Network Intent Composition in OpenDaylight
 
Hadoop-DS: Which SQL-on-Hadoop Rules the Herd
Hadoop-DS: Which SQL-on-Hadoop Rules the HerdHadoop-DS: Which SQL-on-Hadoop Rules the Herd
Hadoop-DS: Which SQL-on-Hadoop Rules the Herd
 
HBaseCon2017 Transactions in HBase
HBaseCon2017 Transactions in HBaseHBaseCon2017 Transactions in HBase
HBaseCon2017 Transactions in HBase
 
Scaling Teams, Processes and Architectures
Scaling Teams, Processes and ArchitecturesScaling Teams, Processes and Architectures
Scaling Teams, Processes and Architectures
 
Scalable Architectures - Taming the Twitter Firehose
Scalable Architectures - Taming the Twitter FirehoseScalable Architectures - Taming the Twitter Firehose
Scalable Architectures - Taming the Twitter Firehose
 
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle TreesModern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
 
The Art of Scalability - Managing growth
The Art of Scalability - Managing growthThe Art of Scalability - Managing growth
The Art of Scalability - Managing growth
 
Monitoring at scale - Intuitive dashboard design
Monitoring at scale - Intuitive dashboard designMonitoring at scale - Intuitive dashboard design
Monitoring at scale - Intuitive dashboard design
 
NoSQL Databases: Why, what and when
NoSQL Databases: Why, what and whenNoSQL Databases: Why, what and when
NoSQL Databases: Why, what and when
 
MySQL Group Replication
MySQL Group ReplicationMySQL Group Replication
MySQL Group Replication
 
Inno db internals innodb file formats and source code structure
Inno db internals innodb file formats and source code structureInno db internals innodb file formats and source code structure
Inno db internals innodb file formats and source code structure
 
MySQL InnoDB Cluster - Group Replication
MySQL InnoDB Cluster - Group ReplicationMySQL InnoDB Cluster - Group Replication
MySQL InnoDB Cluster - Group Replication
 
Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication
Percona XtraDB Cluster vs Galera Cluster vs MySQL Group ReplicationPercona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication
Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication
 
MySQL Best Practices - OTN LAD Tour
MySQL Best Practices - OTN LAD TourMySQL Best Practices - OTN LAD Tour
MySQL Best Practices - OTN LAD Tour
 
MySQL 5.7: Focus on InnoDB
MySQL 5.7: Focus on InnoDBMySQL 5.7: Focus on InnoDB
MySQL 5.7: Focus on InnoDB
 
Mysql参数-GDB
Mysql参数-GDBMysql参数-GDB
Mysql参数-GDB
 
MySQL Group Replication
MySQL Group ReplicationMySQL Group Replication
MySQL Group Replication
 
Using Apache Spark and MySQL for Data Analysis
Using Apache Spark and MySQL for Data AnalysisUsing Apache Spark and MySQL for Data Analysis
Using Apache Spark and MySQL for Data Analysis
 
MySQL High-Availability and Scale-Out architectures
MySQL High-Availability and Scale-Out architecturesMySQL High-Availability and Scale-Out architectures
MySQL High-Availability and Scale-Out architectures
 
MySQL InnoDB Cluster and MySQL Group Replication @HKOSC 2017
MySQL InnoDB Cluster and MySQL Group Replication @HKOSC 2017MySQL InnoDB Cluster and MySQL Group Replication @HKOSC 2017
MySQL InnoDB Cluster and MySQL Group Replication @HKOSC 2017
 

Dernier

VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarPrecisely
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 

Dernier (20)

VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity Webinar
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 

Trees In The Database - Advanced data structures

  • 1. Trees in the Database Advanced Data Structures Lorenzo Alberton lorenzo@ibuildings.com DPC09, Amsterdam, 13 June 2009
  • 3. Lorenzo Alberton MDB2 Calendar Pager Translation2 Mail_Queue DB_QueryTool 2
  • 4. Lorenzo Alberton MDB2 Calendar Pager Translation2 Mail_Queue DB_QueryTool 2
  • 5. Tree Connected, undirected, acyclic graph A B C G D E F 3
  • 10. Adjacency List Model AKA “parent-child” model 4
  • 11. Adjacency List Model CREATE TABLE emp_orgchart ( emp VARCHAR(10) NOT NULL PRIMARY KEY, boss VARCHAR(10), salary DECIMAL(6,2) NOT NULL ); A emp boss salary A NULL 1000.00 B C B A 900.00 C A 900.00 D C 800.00 D E F E C 700.00 F C 600.00 5
  • 12. Adjacency List Model Finding the root node SELECT * FROM emp_orgchart WHERE boss IS NULL; Finding the leaf nodes SELECT e1.* FROM emp_orgchart AS e1 LEFT JOIN emp_orgchart AS e2 ON e1.emp = e2.boss WHERE e2.emp IS NULL; 6
  • 13. Adjacency List Model Anomalies UPDATE anomalies START TRANSACTION; emp boss salary UPDATE emp_orgchart A NULL 1000.00 SET emp = ‘C1’ B A 900.00 WHERE emp = ‘C’; C1 A 900.00 D C 800.00 UPDATE emp_orgchart E C 700.00 SET boss = ‘C1’ F C 600.00 WHERE boss = ‘C’; COMMIT; 7
  • 14. Adjacency List Model Anomalies UPDATE anomalies START TRANSACTION; emp boss salary UPDATE emp_orgchart A NULL 1000.00 SET emp = ‘C1’ B A 900.00 WHERE emp = ‘C’; C1 A 900.00 D C 800.00 UPDATE emp_orgchart E C 700.00 SET boss = ‘C1’ F C 600.00 WHERE boss = ‘C’; COMMIT; 7
  • 15. Adjacency List Model Anomalies UPDATE anomalies START TRANSACTION; UPDATE emp_orgchart SET emp = CASE emp UPDATE emp_orgchart WHEN ‘C’ THEN ‘C1’ SET emp = ‘C1’ ELSE emp END, WHERE emp = ‘C’; boss = CASE boss WHEN ‘C’ THEN ‘C1’ UPDATE emp_orgchart ELSE boss END SET boss = ‘C1’ WHERE ‘C’ IN (emp, boss); WHERE boss = ‘C’; COMMIT; 7
  • 16. Adjacency List Model Anomalies INSERT anomalies 8
  • 17. Adjacency List Model Anomalies INSERT anomalies INSERT INTO emp_orgchart (emp, boss) VALUES (‘G’, ‘H’), (‘H’, ‘G’); G H 8
  • 18. Adjacency List Model Anomalies INSERT anomalies INSERT INTO emp_orgchart (emp, boss) VALUES (‘G’, ‘H’), (‘H’, ‘G’); G H INSERT INTO emp_orgchart VALUES (‘M’, ‘M’); M 8
  • 19. Adjacency List Model Anomalies DELETE anomalies DELETE FROM emp_orgchart WHERE emp = ‘C’; A B C D E F 9
  • 20. Adjacency List Model Anomalies DELETE anomalies DELETE FROM emp_orgchart WHERE emp = ‘C’; A B C D E F 9
  • 21. Fixing the Adjacency List Model CREATE TABLE emp ( id INTEGER DEFAULT 0 PRIMARY KEY, name VARCHAR(10) NOT NULL, salary DECIMAL (6,2) NOT NULL CHECK (salary >= 0.00), ... ); CREATE TABLE orgchart ( emp_id INTEGER NOT NULL DEFAULT 0 -- vacant REFERENCES emp(id) ON DELETE SET DEFAULT ON UPDATE CASCADE, boss_id INTEGER -- NULL means root node REFERENCES emp(id), ... ); 10
  • 22. Fixing the Adjacency List Model -- cannot be your own boss CHECK ((boss_id <> emp_id) OR (boss_id = 0 AND emp_id = 0)), 11
  • 23. Fixing the Adjacency List Model -- cannot be your own boss CHECK ((boss_id <> emp_id) OR (boss_id = 0 AND emp_id = 0)), -- prevent longer cycles UNIQUE (emp_id, boss_id), 11
  • 24. Fixing the Adjacency List Model -- cannot be your own boss CHECK ((boss_id <> emp_id) OR (boss_id = 0 AND emp_id = 0)), -- prevent longer cycles UNIQUE (emp_id, boss_id), -- connected graph (edges = nodes - 1) CHECK ((SELECT COUNT(*) FROM orgchart) - 1 = (SELECT COUNT(boss_id) FROM orgchart)), 11
  • 25. Fixing the Adjacency List Model -- cannot be your own boss CHECK ((boss_id <> emp_id) OR (boss_id = 0 AND emp_id = 0)), -- prevent longer cycles UNIQUE (emp_id, boss_id), -- connected graph (edges = nodes - 1) CHECK ((SELECT COUNT(*) FROM orgchart) - 1 = (SELECT COUNT(boss_id) FROM orgchart)), -- one root only CHECK ((SELECT COUNT(*) FROM orgchart WHERE boss_id IS NULL) = 1), 11
  • 26. Adjacency List Model - Navigation Loops / Self-Joins procedural code SELECT o1.emp AS e1, o2.emp AS e2, CREATE PROCEDURE o3.emp AS e3 TreeTraversal (IN FROM emp_orgchart AS o1 current_emp_id INT) LEFT OUTER JOIN BEGIN emp_orgchart AS o2 ... ON o1.emp = o2.boss LEFT OUTER JOIN emp_orgchart AS o3 ON o2.emp = o3.boss WHERE o1.emp = ‘A’; 12
  • 27. Adjacency List Model - Deletion 13
  • 28. Adjacency List Model - Deletion A B C D E F 13
  • 29. Adjacency List Model - Deletion A B C D x E F 13
  • 30. Adjacency List Model - Deletion A A B C B C D x E F D E F 13
  • 31. Adjacency List Model - Deletion A A A B C B C D x E F B D D E E F F 13
  • 32. Adjacency List Model - Deletion A A A A B C B C B C D x E F B D D E E F F D E F 13
  • 33. Adjacency List Model - Deletion A A A A B C B C B D C D x E F B D D E E F F D E F 13
  • 34. Adjacency List Model - Deletion A A A A B C B C B D C D x E F B D D E E F F D E F Requires traversal (deferred constraints) 13
  • 35. Path Enumeration Model aka Materialized Path 14
  • 36. Path Enumeration Model CREATE TABLE emp_orgchart ( emp_id CHAR(1) NOT NULL PRIMARY KEY -- if using a separator, don’t use it in the ID CHECK (REPLACE(emp_id, ‘/’, ‘’) = emp_id), emp_name VARCHAR(10) NOT NULL, path_string VARCHAR(512) NOT NULL ); emp_id emp_name path_string A A Anthony A B Beryl AB B C C Charles AC D Denise ACD E Ellen ACE D E F F Frank ACF 15
  • 37. Path Enumeration Model -- prevent cycles (nodes appearing twice: ‘ABCA’) CHECK (NOT EXISTS( SELECT * FROM emp_orgchart AS D1, emp_orgchart AS P1 WHERE LENGTH(REPLACE(P1.path_string, D1.emp_id, ‘’)) < LENGTH(P1.path_string) - LENGTH(D1.emp_id)) )) -- No path can be longer than the number of nodes CHECK((SELECT MAX(LENGTH(path_string)) FROM emp_orgchart AS E1) <= (SELECT COUNT(emp_id) * LENGTH(emp_id) FROM emp_orgchart AS E2)) 16
  • 39. Path Enumeration Model Depth of the node 17
  • 40. Path Enumeration Model Depth of the node • LENGTH(path_string) / LENGTH(emp_id) 17
  • 41. Path Enumeration Model Depth of the node • LENGTH(path_string) / LENGTH(emp_id) • LENGTH(path_string) - LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1 17
  • 42. Path Enumeration Model Depth of the node • LENGTH(path_string) / LENGTH(emp_id) • LENGTH(path_string) - LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1 17
  • 43. Path Enumeration Model Depth of the node • LENGTH(path_string) / LENGTH(emp_id) • LENGTH(path_string) - LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1 Searching for subordinates 17
  • 44. Path Enumeration Model Depth of the node • LENGTH(path_string) / LENGTH(emp_id) • LENGTH(path_string) - LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1 Searching for subordinates • SELECT * FROM emp_orgchart WHERE path_string LIKE ‘%’ || :parent_emp_id || ‘%’; 17
  • 45. Path Enumeration Model Depth of the node • LENGTH(path_string) / LENGTH(emp_id) • LENGTH(path_string) - LENGTH(REPLACE(path_string, ‘/’, ‘’)) + 1 Searching for subordinates • SELECT * FROM emp_orgchart WHERE path_string LIKE ‘%’ || :parent_emp_id || ‘%’; • SELECT * FROM emp_orgchart WHERE path_string LIKE (SELECT path_string FROM emp_orgchart WHERE emp_id = :parent_emp_id) || ‘%’; 17
  • 46. Path Enumeration Model Searching for superiors SELECT SUBSTRING(P1.path_string FROM seq * LENGTH(P1.emp_id) FOR LENGTH(P1.emp_id)) AS emp_id FROM emp_orgchart AS P1, sequence AS S1 WHERE P1.emp_id = :search_emp_id AND S1.seq <= LENGTH(path_string)/ LENGTH(emp_id); 18
  • 47. Path Enumeration Model Deleting a subtree: DELETE FROM emp_orgchart WHERE path_string LIKE ( SELECT path_string FROM emp_orgchart WHERE emp_id = :deleted_node) || ‘%’; Deleting a single node: START TRANSACTION; DELETE FROM emp_orgchart WHERE emp_id = :deleted_node; UPDATE emp_orgchart SET path_string = REPLACE(path_string, :deleted_node, ‘’); COMMIT; 19
  • 48. Path Enumeration Model Insertion of a new node INSERT INTO emp_orgchart VALUES ( :new_emp_id, -- ‘M’ :new_name, -- ‘Maggie’ (SELECT path_string FROM emp_orgchart WHERE emp_id = :boss_of_new_emp) -- ‘D’ || :new_emp_id -- ‘M’ ); emp_id emp_name path_string D Denise ACD M Maggie ACDM 20
  • 49. Path Enumeration Model Insertion of a new node INSERT INTO emp_orgchart VALUES ( :new_emp_id, -- ‘M’ :new_name, -- ‘Maggie’ (SELECT path_string FROM emp_orgchart WHERE emp_id = :boss_of_new_emp) -- ‘D’ || :new_emp_id -- ‘M’ ); emp_id emp_name path_string D Denise ACD M Maggie ACDM 20
  • 50. Path Enumeration Model Insertion of a new node INSERT INTO emp_orgchart VALUES ( :new_emp_id, -- ‘M’ :new_name, -- ‘Maggie’ (SELECT path_string FROM emp_orgchart WHERE emp_id = :boss_of_new_emp) -- ‘D’ || :new_emp_id -- ‘M’ ); emp_id emp_name path_string D Denise ACD M Maggie ACDM 20
  • 51. Path Enumeration Model Splitting the path string into nodes SELECT CASE WHEN SUBSTRING(‘/’ || P1.path_string || ‘/’ FROM S1.seq FOR 1) = ‘/’ THEN SUBSTRING(‘/’ || P1.path_string || ‘/’ FROM (S1.seq + 1) FOR CharIndex(‘/’ , ‘/’ || P1.path_string || ‘/’, S1.seq + 1) - S1.seq - 1 ELSE NULL END AS emp_id FROM sequence AS S1, emp_orgchart AS P1 WHERE S1.seq BETWEEN 1 AND LENGTH(P1.path_string) + 1 AND SUBSTRING(‘/’ || P1.path_string || ‘/’ FROM S1.seq FOR 1) = ‘/’ 21
  • 52. Path Enumeration Model emp_name edge_path Edge Anthony 1. Beryl 1.1. Enumeration Charles 1.2. Model Denise 1.2.1. Ellen 1.2.2. Frank 1.2.3. Anthony Beryl Charles Denise Ellen Frank 22
  • 53. Nested Set Model aka Modified Preorder Tree Traversal (MPTT) 23
  • 54. Nested Set Model A C B D E F 24
  • 55. Nested Set Model A C B D E F A 1 12 B C 2 3 4 11 D E F 5 6 7 8 9 10 24
  • 56. Nested Set Model CREATE TABLE orgchart ( emp VARCHAR(10) NOT NULL PRIMARY KEY, lft INTEGER NOT NULL, rgt INTEGER NOT NULL ); A 1 12 B C 2 3 4 11 D E F 5 6 7 8 9 10 25
  • 57. Nested Set Model CREATE TABLE orgchart ( emp VARCHAR(10) NOT NULL PRIMARY KEY, lft INTEGER NOT NULL, rgt INTEGER NOT NULL ); A 1 12 B C 1 A 12 2 3 4 11 D E F 5 6 7 8 9 10 2 B 3 4 C 11 D E F 5 6 7 8 9 10 25
  • 58. Nested Set Model Finding root node 1 A 12 2 B 3 4 C 11 D E F 5 6 7 8 9 10 26
  • 59. Nested Set Model Finding root node SELECT * FROM orgchart WHERE lft = 1; 1 A 12 2 B 3 4 C 11 D E F 5 6 7 8 9 10 26
  • 60. Nested Set Model Finding root node SELECT * FROM orgchart WHERE lft = 1; 1 A 12 Finding leaf nodes 2 B 3 4 C 11 D E F 5 6 7 8 9 10 26
  • 61. Nested Set Model Finding root node SELECT * FROM orgchart WHERE lft = 1; 1 A 12 Finding leaf nodes SELECT * 2 B 3 4 C 11 FROM orgchart WHERE lft = (rgt - 1); D E F 5 6 7 8 9 10 26
  • 62. Nested Set Model Finding root node SELECT * FROM orgchart WHERE lft = 1; 1 A 12 Finding leaf nodes SELECT * 2 B 3 4 C 11 FROM orgchart WHERE lft = (rgt - 1); D E F Finding subtrees 5 6 7 8 9 10 26
  • 63. Nested Set Model Finding root node SELECT * FROM orgchart WHERE lft = 1; 1 A 12 Finding leaf nodes SELECT * 2 B 3 4 C 11 FROM orgchart WHERE lft = (rgt - 1); D E F Finding subtrees 5 6 7 8 9 10 SELECT Mgrs.emp AS boss Workers.emp AS worker FROM orgchart AS Mgrs, orgchart AS Workers WHERE Workers.lft > Mgrs.lft AND Workers.lft < Mgrs.rgt 26
  • 64. Nested Set Model Finding root node SELECT * FROM orgchart WHERE lft = 1; 1 A 12 Finding leaf nodes SELECT * 2 B 3 4 C 11 FROM orgchart WHERE lft = (rgt - 1); D E F Finding subtrees 5 6 7 8 9 10 SELECT Mgrs.emp AS boss Workers.emp AS worker FROM orgchart AS Mgrs, orgchart AS Workers WHERE Workers.lft > Mgrs.lft BETWEEN Mgrs.lft AND Mgrs.rgt AND Workers.lft < Mgrs.rgt 26
  • 65. Nested Set Model Finding the level of a node 27
  • 66. Nested Set Model Finding the level of a node SELECT o2.emp, COUNT(o1.emp) AS lvl FROM orgchart AS o1, orgchart AS o2 WHERE o2.lft BETWEEN o1.lft AND o1.rgt GROUP BY o2.emp; 27
  • 67. Nested Set Model Finding the level of a node SELECT o2.emp, COUNT(o1.emp) AS lvl FROM orgchart AS o1, orgchart AS o2 WHERE o2.lft BETWEEN o1.lft AND o1.rgt GROUP BY o2.emp; Finding the height of the tree 27
  • 68. Nested Set Model Finding the level of a node SELECT o2.emp, COUNT(o1.emp) AS lvl FROM orgchart AS o1, orgchart AS o2 WHERE o2.lft BETWEEN o1.lft AND o1.rgt GROUP BY o2.emp; Finding the height of the tree SELECT MAX(lvl) AS height FROM ( SELECT o2.emp, COUNT(o1.emp) - 1 FROM orgchart AS o1, orgchart AS o2 WHERE o2.lft BETWEEN o1.lft AND o1.rgt GROUP BY o2.emp) AS L1(emp, lvl); 27
  • 69. Nested Set Model Finding relative position SELECT CASE WHEN :emp1 = :emp2 THEN :emp1 || ‘ is ’ || :emp2 WHEN o1.lft BETWEEN o2.lft AND o2.rgt THEN :emp1 || ‘ subordinate to ’ || :emp2 WHEN o2.lft BETWEEN o1.lft AND o1.rgt THEN :emp2 || ‘ subordinate to ’ || :emp1 ELSE :emp1 || ‘ no relation to ’ || :emp2 END FROM orgchart AS o1, orgchart AS o2 WHERE o1.emp = :emp1 AND o2.emp = :emp2; 28
  • 70. Nested Set Model Deleting subtrees DELETE FROM orgchart WHERE lft BETWEEN (SELECT lft FROM orgchart WHERE emp = :start_node) AND (SELECT rgt FROM orgchart Filling gaps WHERE emp = :start_node); CREATE VIEW LftRgt (seq) AS SELECT lft FROM orgchart UNION ALL SELECT rgt FROM orgchart; UPDATE orgchart SET lft = (SELECT COUNT(*) FROM LftRgt WHERE seq <= lft), rgt = (SELECT COUNT(*) FROM LftRgt WHERE seq <= rgt) 29
  • 71. Nested Set Model Deleting a single node DELETE FROM orgchart WHERE emp = ‘C’; A C B D E F 30
  • 72. Nested Set Model Deleting a single node DELETE FROM orgchart WHERE emp = ‘C’; A B D E F 30
  • 73. Nested Set Model Deleting a single node CREATE PROCEDURE downsize(IN removed VARCHAR(10)) LANGUAGE SQL DETERMINISTIC UPDATE orgchart SET emp = CASE WHEN orgchart.emp = removed AND orgchart.lft + 1 = orgchart.rgt --leaf THEN ‘{vacant}’ WHEN orgchart.emp = removed AND orgchart.lft + 1 <> orgchart.rgt -- promote subordinate and vacate THEN (SELECT o1.emp FROM orgchart AS o1 WHERE orgchart.lft + 1 = o1.lft) WHEN orgchart.emp = (SELECT o1.emp FROM orgchart AS o1 WHERE orgchart.lft + 1 = o1.lft) THEN ‘{vacant}’ ELSE emp END; 31
  • 74. Nested Set Model Deleting a single node CREATE PROCEDURE downsize(IN removed VARCHAR(10)) LANGUAGE SQL DETERMINISTIC UPDATE orgchart SET emp = CASE WHEN orgchart.emp = removed AND orgchart.lft + 1 = orgchart.rgt --leaf THEN ‘{vacant}’ WHEN orgchart.emp = removed AND orgchart.lft + 1 <> orgchart.rgt -- promote subordinate and vacate THEN (SELECT o1.emp FROM orgchart AS o1 WHERE orgchart.lft + 1 = o1.lft) WHEN orgchart.emp = (SELECT o1.emp FROM orgchart AS o1 WHERE orgchart.lft + 1 = o1.lft) THEN ‘{vacant}’ ELSE emp END; 31
  • 75. Nested Set to Adjacency List SELECT B.id AS boss, P.emp, P.lft, P.rgt FROM orgchart as P LEFT OUTER JOIN emp AS B ON B.lft = (SELECT MAX(S.lft) FROM orgchart AS S WHERE P.lft > S.lft AND P.lft < S.rgt); boss emp lft rgt NULL Anthony 1 12 Anthony Beryl 2 3 Anthony Charles 4 11 Charles Denise 5 6 Charles Ellen 7 8 Charles Frank 9 10 32
  • 76. Frequent Insertion Trees Avoid overhead (locking + updating) with larger spreads and bigger gaps emp lft rgt Anthony 100 1200 Beryl 200 300 Charles 400 1100 Denise 500 600 Ellen 700 800 Frank 900 1000 33
  • 77. Frequent Insertion Trees Avoid overhead (locking + updating) with larger spreads and bigger gaps emp lft rgt Anthony 100 1200 Beryl 200 300 Charles 400 1100 Denise 500 600 Ellen 700 800 Frank 900 1000 Datatype of (lft, rgt)? - INTEGER (full range) - FLOAT / REAL / DOUBLE - NUMERIC(p,s) / DECIMAL(p,s) 33
  • 78. Frequent Insertion Trees Avoid overhead (locking + updating) with larger spreads and bigger gaps emp lft rgt Anthony 100 1200 Beryl 200 300 Charles 400 1100 Denise 500 600 Ellen 700 800 Frank 900 1000 Datatype of (lft, rgt)? - INTEGER (full range) - FLOAT / REAL / DOUBLE - NUMERIC(p,s) / DECIMAL(p,s) 33
  • 79. Frequent Insertion Trees Avoid overhead (locking + updating) with larger spreads and bigger gaps emp lft rgt Anthony 100 1200 Beryl 200 300 Charles 400 1100 Denise 500 600 Ellen 700 800 Frank 900 1000 Datatype of (lft, rgt)? - INTEGER (full range) - FLOAT / REAL / DOUBLE - NUMERIC(p,s) / DECIMAL(p,s) 33
  • 80. Frequent Insertion Trees Avoid overhead (locking + updating) with larger spreads and bigger gaps emp lft rgt Anthony 100 1200 Beryl 200 300 Charles 400 1100 Denise 500 600 Ellen 700 800 Frank 900 1000 Datatype of (lft, rgt)? - INTEGER (full range) - FLOAT / REAL / DOUBLE - NUMERIC(p,s) / DECIMAL(p,s) 33
  • 81. Hybrid Models Adjacency List with Nested Sets (node, parent, lft, rgt) Nested Sets with depth Adjacency List with depth ... Denormalisation to save subselects or joins 34
  • 83. Nested Intervals Model Rational numbers (a/b, with a and b integers) ((p.lft <= c.lft) AND (c.rgt <= p.rgt)) 0/5 A 5/5 1/5 B 2/5 3/5 C 4/5 36
  • 85. Nested Intervals Model a b a+(b-a)/3 a+2(b-a)/3 37
  • 86. Nested Intervals Model Finding GCD (greatest common divisor) CREATE FUNCTION gcd(IN x INTEGER, IN y INTEGER) RETURNS INTEGER LANGUAGE SQL DETERMINISTIC BEGIN WHILE x <> y DO IF x > y THEN SET x = x - y; END IF; IF y > x THEN SET y = y - x; END IF; END WHILE; RETURN x; END; 38
  • 87. Nested Intervals Model Binary Node (x, y) Fractions 39
  • 88. Nested Intervals Model Binary Node (x, y) Fractions First node (1, 1/2) 39
  • 89. Nested Intervals Model Binary Node (x, y) Fractions First node (1, 1/2) depth-first convergence point 39
  • 90. Nested Intervals Model Binary Node (x, y) Fractions First child of first node (1, 3/4) First node (1, 1/2) depth-first convergence point 39
  • 91. Nested Intervals Model Binary Node (x, y) Fractions First child of first node (1, 3/4) First node (1, 1/2) depth-first convergence point breadth-first convergence point 39
  • 92. Nested Intervals Model Binary Node (x, y) Fractions First child of first node (1, 3/4) First node (1, 1/2) depth-first convergence point breadth-first convergence point 39
  • 93. Nested Intervals Model Binary Node (x, y) Fractions First child of first node (1, 3/4) First node (1, 1/2) depth-first convergence point breadth-first convergence point 39
  • 95. Nested Intervals Model CREATE FUNCTION x_numer( IN numer INT, IN denom INT ) RETURNS INTEGER BEGIN DECLARE ret_num INTEGER; DECLARE ret_den INTEGER; SET ret_num = numer + 1; SET ret_den = 2 * denom; WHILE FLOOR(ret_num/2) = ret_num/2 DO SET ret_num = ret_num/2; SET red_den = ret_den/2; END WHILE; RETURN ret_num; -- ret_den -- for x_denom() END; 40
  • 96. Nested Intervals Model CREATE FUNCTION parent_numer(IN numer INTEGER, IN denom INTEGER) RETURNS INTEGER LANGUAGE SQL DETERMINISTIC BEGIN DECLARE ret_num INTEGER; DECLARE ret_den INTEGER; IF numer = 3 THEN RETURN CAST(NULL AS INTEGER) END IF; SET ret_num = (numer - 1)/2; SET ret_den = denom/2; WHILE FLOOR((ret_num - 1)/4) = (ret_num - 1)/4 DO SET ret_num = (ret_num + 1)/2; SET red_den = ret_den/2; END WHILE; RETURN ret_num; -- ret_den for parent_denom() END; 41
  • 97. Nested Intervals Model Similar functions for: sibling_numer(), sibling_denom() child_numer(), child_denom() enumerated_path(), distance() path_numer(), path_denom() 42
  • 98. Nested Intervals Model Similar functions for: sibling_numer(), sibling_denom() child_numer(), child_denom() enumerated_path(), distance() path_numer(), path_denom() INSERT INTO orgchart (name, numer, denom) VALUES (‘Anthony’, path_numer(‘1’), path_denom(‘1’)), (‘Beryl’, path_numer(‘1.1’), path_denom(‘1.1’)), (‘Charles’, path_numer(‘1.2’), path_denom(‘1.2’)), (‘Denise’, path_numer(‘1.2.1’), path_denom(‘1.2.1’)); 42
  • 99. Nested Intervals Encodings Interval Halving average: (lft + rgt) / 2 43
  • 100. Nested Intervals Encodings Interval Halving average: (lft + rgt) / 2 Farey Fractions a/b and c/d neighbours => bc -ad = 1 mediant: (lft_num + rgt_num) (lft_den + rgt_den) 43
  • 101. Nested Intervals Encodings Continued Fractions 1.1.2.1 Reverse (or additive) Continued Fractions 44
  • 103. Oracle: CONNECT BY PRIOR Traversing the tree SELECT emp, boss FROM emp_orgchart START WITH boss IS NULL CONNECT BY [NOCYCLE] PRIOR emp = boss; emp boss A NULL B A G B C A D C E C F C 46
  • 104. Oracle: CONNECT BY PRIOR Traversing the tree SELECT emp, boss FROM emp_orgchart START WITH boss = ‘C’ IS NULL CONNECT BY [NOCYCLE] PRIOR emp = boss; emp boss D C E C F C 46
  • 105. Oracle: CONNECT BY PRIOR Traversing the tree SELECT emp, boss, salary, LEVEL AS lvl, LPAD(' ', 2*(LEVEL-1)) || emp AS tree, CONNECT_BY_IS_LEAF AS is_leaf FROM emp_orgchart CONNECT BY PRIOR emp = boss START WITH boss IS NULL ORDER SIBLINGS BY salary DESC; emp boss salary lvl tree is_leaf A NULL 1000.00 1 A 0 B A 900.00 2 B 0 G B 800.00 3 G 1 C A 900.00 2 C 0 D C 800.00 3 D 1 E C 700.00 3 E 1 F C 600.00 3 F 1 47
  • 106. Oracle: CONNECT BY PRIOR Determining the relationship between two nodes SELECT COUNT(*) AS ‘is_subordinate’ FROM emp_orgchart WHERE emp = :subordinate AND LEVEL > 1 START WITH emp = :superior CONNECT BY PRIOR emp = boss; 48
  • 107. Oracle: CONNECT BY PRIOR Determining the relationship between two nodes SELECT COUNT(*) AS ‘is_subordinate’ FROM emp_orgchart WHERE emp = :subordinate AND LEVEL > 1 START WITH emp = :superior CONNECT BY PRIOR emp = boss; A subordinate of C? 0 F subordinate of A? 1 48
  • 108. Oracle: CONNECT_BY_ROOT Determining the ancestor of a node SELECT emp_id, CONNECT_BY_ROOT emp_id AS root FROM orgchart START WITH boss = ‘A’ CONNECT BY PRIOR emp_id = boss; emp_id root B B G B C C D C E C F C 49
  • 109. Oracle: SYS_CONNECT_BY_PATH Materialized Path View SELECT emp_id, SYS_CONNECT_BY_PATH (emp_id,'.') AS path_string FROM orgchart START WITH boss IS NULL CONNECT BY PRIOR emp_id = boss ORDER BY 2; emp_id path_string A .A B .A.B C .A.C D .A.C.D E .A.C.E F .A.C.F 50
  • 111. Common Table Expressions CREATE TABLE emp_orgchart ( emp VARCHAR(10) PRIMARY KEY, boss VARCHAR(10) REFERENCES emp_orgchart(emp_id), salary TEXT ); INSERT INTO emp_orgchart (emp, boss, salary) VALUES (‘A’, NULL, 1000.00), (‘B’, ‘A’, 900.00), (‘C’, ‘A’, 900.00), A (‘D’, ‘C’, 800.00), (‘E’, ‘C’, 700.00), (‘F’, ‘C’, 600.00), B C (‘G’, ‘B’, 800.00); G D E F 52
  • 112. Common Table Expressions WITH RECURSIVE hierarchy AS ( -- non recursive term SELECT * FROM emp_orgchart WHERE boss IS NULL UNION ALL -- recursive term SELECT E1.* FROM emp_orgchart AS E1 JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT * FROM hierarchy ORDER BY emp; 53
  • 113. Common Table Expressions WITH RECURSIVE hierarchy AS ( -- non recursive term SELECT * FROM emp_orgchart WHERE boss IS NULL UNION ALL -- recursive term SELECT E1.* FROM emp_orgchart AS E1 JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT * FROM hierarchy ORDER BY emp; 53
  • 114. Common Table Expressions WITH RECURSIVE hierarchy AS ( -- non recursive term SELECT * FROM emp_orgchart WHERE boss IS NULL UNION ALL -- recursive term SELECT E1.* FROM emp_orgchart AS E1 JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT * FROM hierarchy ORDER BY emp; 53
  • 115. Common Table Expressions WITH RECURSIVE hierarchy AS ( -- non recursive term SELECT * FROM emp_orgchart WHERE boss IS NULL emp boss salary UNION ALL A NULL 1000.00 -- recursive term B A 900.00 SELECT E1.* C A 900.00 FROM emp_orgchart AS E1 D C 800.00 JOIN hierarchy AS E2 E C 700.00 ON E1.boss = E2.emp F C 600.00 ) SELECT * G B 800.00 FROM hierarchy ORDER BY emp; 53
  • 116. Common Table Expressions WITH RECURSIVE hierarchy AS ( SELECT *, 1 AS lvl, CAST(emp AS TEXT) AS tree, emp || ‘.’ AS path FROM emp_orgchart WHERE boss IS NULL UNION ALL SELECT E1.*, E2.lvl + 1 AS lvl, LPAD(E1.emp, lvl * 2, ‘ ’) AS tree, E2.path || E1.emp || ‘.’ AS path FROM emp_orgchart JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT * FROM hierarchy ORDER BY path; 54
  • 117. Common Table Expressions WITH RECURSIVE hierarchy AS ( SELECT *, 1 AS lvl, CAST(emp AS TEXT) AS tree, emp || ‘.’ AS path FROM emp_orgchart WHERE boss IS NULL UNION ALL SELECT E1.*, E2.lvl + 1 AS lvl, LPAD(E1.emp, lvl * 2, ‘ ’) AS tree, E2.path || E1.emp || ‘.’ AS path FROM emp_orgchart JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT * FROM hierarchy ORDER BY path; 54
  • 118. Common Table Expressions WITH RECURSIVE hierarchy AS ( SELECT *, 1 AS lvl, CAST(emp AS TEXT) AS tree, emp || ‘.’ AS path FROM emp_orgchart WHERE boss IS NULL UNION ALL SELECT E1.*, E2.lvl + 1 AS lvl, LPAD(E1.emp, lvl * 2, ‘ ’) AS tree, E2.path || E1.emp || ‘.’ AS path FROM emp_orgchart JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT * FROM hierarchy ORDER BY path; 54
  • 119. Common Table Expressions WITH RECURSIVE hierarchy AS ( SELECT *, 1 AS lvl, CAST(emp AS TEXT) AS tree, emp || ‘.’ AS path FROM emp_orgchart WHERE boss IS NULL UNION ALL SELECT E1.*, E2.lvl + 1 AS lvl, LPAD(E1.emp, lvl * 2, ‘ ’) AS tree, E2.path || E1.emp || ‘.’ AS path FROM emp_orgchart JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT * FROM hierarchy ORDER BY path; 54
  • 120. Common Table Expressions WITH RECURSIVE hierarchy AS ( SELECT *, 1 AS lvl, CAST(emp AS TEXT) AS tree, emp || ‘.’ AS path FROM emp_orgchart WHERE boss IS NULL UNION ALL SELECT E1.*, E2.lvl + 1 AS lvl, LPAD(E1.emp, lvl * 2, ‘ ’) AS tree, E2.path || E1.emp || ‘.’ AS path FROM emp_orgchart JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT * FROM hierarchy ORDER BY path; 54
  • 121. Common Table Expressions WITH RECURSIVE hierarchy AS ( SELECT *, 1 AS lvl, emp CAST(emp salary boss AS TEXT) AS tree, tree lvl path emp || ‘.’ AS path A NULL 1000.00 1 A A. FROM emp_orgchart WHERE boss IS NULL B A 900.00 2 B A.B. UNION ALL SELECT E1.*, G B 800.00 3 G A.B.G. E2.lvl + 1 AS lvl, C LPAD(E1.emp, lvl * 2, ‘ ’)CAS tree, A 900.00 2 A.C. E2.path || E1.emp || ‘.’ AS path D C 800.00 FROM emp_orgchart 3 D A.C.D. JOIN hierarchy AS E2 E C 700.00 3 E A.C.E. ON E1.boss = E2.emp ) F C 600.00 3 F A.C.F. SELECT * FROM hierarchy ORDER BY path; 54
  • 122. Common Table Expressions WITH RECURSIVE hierarchy AS ( SELECT *, 1 AS lvl, CAST(emp AS TEXT) AS tree FROM emp_orgchart WHERE boss = ‘A’ UNION ALL SELECT E1.*, E2.lvl + 1 AS lvl, LPAD(E1.emp, depth * 2, ‘ ’) AS tree FROM emp_orgchart JOIN hierarchy AS E2 ON E1.boss = E2.emp WHERE E2.lvl < 3 -- termination condition ) SELECT * FROM hierarchy ORDER BY path; 55
  • 123. Common Table Expressions WITH RECURSIVE hierarchy AS ( SELECT *, 1 AS lvl, CAST(emp AS TEXT) AS tree FROM emp_orgchart WHERE boss = ‘A’ UNION ALL SELECT E1.*, E2.lvl + 1 AS lvl, LPAD(E1.emp, depth * 2, ‘ ’) AS tree FROM emp_orgchart JOIN hierarchy AS E2 ON E1.boss = E2.emp ) SELECT *, COALESCE((SELECT 0 FROM emp_orgchart E3 WHERE hierarchy.emp = E3.boss FETCH FIRST ROW ONLY), 1) AS is_leaf FROM hierarchy; 56
  • 124. And the winner is... 57
  • 125. And the winner is... 57
  • 126. Questions ? 58
  • 127. Resources Joe Celko, “Trees and Hierarchies in SQL for Smarties”, Morgan Kaufmann: http://www.amazon.com/dp/1558609202/ Vadim Tropashko, various articles and papers: http://www.dbazine.com/top-auth/top-auth-trop/ http://www.sigmod.org/sigmod/record/issues/ 0506/p47-article-tropashko.pdf http://arxiv.org/pdf/cs/0402051 59
  • 128. Thank you! Contact details: Lorenzo Alberton lorenzo@ibuildings.com http://www.alberton.info http://joind.in/talk/view/585