mysql nested datasets #jdnl13
TRANSCRIPT
NESTED DATA SETS(THINK ACL)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 1
INTRODUCTION
Eli Aschkenasy themodularway.com Oracle certified (doesn’t really mean anything) GE sourcing database project Agenda
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
AGENDA
Introduction (5min) Simple Explanation of Nested Data Sets (10min) Types of Hierarchies (5min) The Joomla Way (5min) Basic Functions (15min) Advanced Functions (10min) The Ten Commandments (for ever…)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
WELCOME TO OUR DEMO TEAM (COURTESY OF MS POWERPOINT TEMPLATES)
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
lft, rgt
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
CEO
VP
Financial
Support Marketing Sales Development
Research
position
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
container
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
container
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
container
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
container
AGENDA
Introduction (5min) Simple Explanation of Nested Data Sets (10min) Types of Hierarchies (5min) The Joomla Way (5min) Basic Functions (15min) Advanced Functions (10min) The Ten Commandments (for ever…)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 6
TYPES OF HIERARCHIES
Static nodes and static edges A chart of accounts in an accounting
system will probably not change much over time.
This is probably best done with a hierarchical encoding scheme rather than a table.
Static nodes and dynamic edges For example, an Internet Newsgroup
message board. Obviously you cannot add a node to a tree without adding an edge, but the content of the messages (nodes) never change once they are posted; however, new replies can be posted as subordinates to any existing message (edge).
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 7
TYPES OF HIERARCHIES
Dynamic nodes and static edges This is the classic organizational chart in
which the organization stays the same, but the people holding the offices rotate frequently.
This is assuming that your company does not reorganize more often than its personnel turns over.
Dynamic nodes and dynamic edges
The fastest path from the fire station to a particular home address will not necessarily be the same route at 5:00 AM as it will be at 5:00 PM.
Once the fire is put out, the node that represented the burning house can disappear from the tree and the next fire location becomes a to which we must find a path.
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 8
TYPES OF HIERARCHIES
Dynamic nodes and static edges This is the classic organizational chart in
which the organization stays the same, but the people holding the offices rotate frequently.
This is assuming that your company does not reorganize more often than its personnel turns over.
Dynamic nodes and dynamic edges
The fastest path from the fire station to a particular home address will not necessarily be the same route at 05:00 Hrs. as it will be at 17:00 Hrs.
Once the fire is put out, the node that represented the burning house can disappear from the tree and the next fire location becomes a to which we must find a path.
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
AGENDA
Introduction (5min) Simple Explanation of Nested Data Sets (10min) Types of Hierarchies (5min) The Joomla Way (5min) Basic Functions (15min) Advanced Functions (10min) The Ten Commandments (for ever…)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 10
THE JOOMLA WAY - JTableNested
http://docs.joomla.org/Using_nested_sets Table creation (required fields)CREATE TABLE IF NOT EXISTS `#__nestedsets` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(10) UNSIGNED NOT NULL DEFAULT '0', `lft` int(11) NOT NULL DEFAULT '0', `rgt` int(11) NOT NULL DEFAULT '0', `level` int(10) UNSIGNED NOT NULL DEFAULT '0', `title` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL DEFAULT '', `access` tinyint(3) UNSIGNED NOT NULL DEFAULT '0', `path` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `idx_left_right` (`lft`,`rgt`)) DEFAULT CHARSET=utf8;
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 11
THE JOOMLA WAY - JTableNested
http://docs.joomla.org/Using_nested_sets Creating Root Node$sql = 'INSERT INTO ckm_profiles' . ' SET parent_id = 0' . ', lft = 0' . ', rgt = 1' . ', level = 0' . ', title = '.$db->quote( 'root' ) . ', alias = '.$db->quote( 'root' ) . ', access = 1' . ', path = '.$db->quote( '' ) ;
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 12
THE JOOMLA WAY - JTableNested
http://docs.joomla.org/Using_nested_sets Basic Functions: getRootId() and update data (just like JTable)
$rootId = $table->getRootId();if ($rootId === false) { $rootId = $table->addRoot();}
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 13
$table->bind( $data_array );$table->check();$table->store();
THE JOOMLA WAY - JTableNested
http://docs.joomla.org/Using_nested_sets Inserting Node$table = JTable::getInstance( 'yourtable' );$table->setLocation( $reference_id, 'first-child' );$table->bind( $data_array );$table->id = 0;$table->check();$table->store();
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 14
THE JOOMLA WAY - JTableNested
http://docs.joomla.org/Using_nested_sets Basic Functions$table->isLeaf $subtree = $table->getTree( $id ); $pathNodes = $table->getPath( $id ); $table->publish( $id, $state, $userId )
$table->orderUp( $id ) $key = $this->_tbl_key; $reference_id = JRequest::getInt( 'reference' );$this->$key = JRequest::getInt( 'id' ); $relation = 'last-
child';$delta = -2; $node_id
= JRequest::getInt( 'id' );$table->move( $delta ); $table-
>moveByReference( $reference_id, $relation, $node_id );
$table->delete( $node_id )
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 15
AGENDA
Introduction (5min) Simple Explanation of Nested Data Sets (10min) Types of Hierarchies (5min) The Joomla Way (5min) Basic Functions (15min) Advanced Functions (10min) The Ten Commandments (for ever…)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 16
NESTED SETS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 17
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
lft, rgt
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 18
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Root NodeSELECT *FROM OrgchartWHERE lft = 1;
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 19
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Leaf Node (PHP check in J)
SELECT *FROM OrgchartWHERE(rgt - lft) = 1;
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 19
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Leaf Node (PHP check in J)
SELECT *FROM OrgchartWHERE(rgt - lft) = 1;
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 19
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Leaf Node (PHP check in J)
SELECT *FROM OrgchartWHERE lft = (rgt-1);
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 19
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Leaf Node (PHP check in J)
SELECT a, b, cFROM OrgchartWHERE lft = (rgt-1);
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Total Nodes (not in J)
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Total Nodes (not in J)
((rgt – lft)+1) / 2
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 21
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
SubordinatesSELECT Mgrs.name AS manager, Workers.name AS workerFROM Orgchart AS Mgrs, Orgchart AS WorkersWHERE Workers.lft > Mgrs.lft AND Workers.lft < Mgrs.rgt;
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Level of node (J has info in row)
SELECT O2.name, COUNT(O1.name) AS levelFROM OrgChart AS O1, OrgChart AS O2WHERE O2.lft BETWEEN O1.lft AND O1.rgtGROUP BY O2.name;
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Maximum Height of TreeSELECT MAX( hlevel ) AS heightFROM ( SELECT 02.name, COUNT( O1.id ) -1 AS hlevel FROM OrgChart AS O1, OrgChart AS O2 WHERE O2.lft BETWEEN O1.lft AND O1.rgt GROUP BY O2.id) AS L1
BASIC FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Age of Child NodeSELECT Workers.nameFROM OrgChart AS Mgrs, OrgChart AS WorkersWHERE Mgrs.lft = 2AND Workers.lft = Mgrs.lft + 1;
AGENDA
Introduction (5min) Simple Explanation of Nested Data Sets (10min) Types of Hierarchies (5min) The Joomla Way (5min) Basic Functions (15min) Advanced Functions (10min) The Ten Commandments (for ever…)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 25
ADVANCED FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 26
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Path between Nodes (J is path to root)
SELECT O2.name, (SELECT COUNT(*) FROM OrgChart AS O4 WHERE O4.lft BETWEEN O1.lft AND O1.rgt AND O2.lft BETWEEN O4.lft AND O4.rgt) AS path_nbrFROM OrgChart AS O1, OrgChart AS O2, OrgChart AS O3WHERE O1.lft = 2AND O3.lft = 19AND O2.lft BETWEEN O1.lft AND O1.rgtAND O3.lft BETWEEN O2.lft AND O2.rgt;
ADVANCED FUNCTIONS
Children to Parent Mom dies and Grandma adopts the kids. In effect the position itself is removed. This is a vertical promotion of an entire
subtree.
Child node to the deleted node’s position
Give the business to the oldest son. The problem is that when the son is
promoted, this leaves a vacancy in his former position.
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
Deleting Nodes (J is simple (?))
ADVANCED FUNCTIONSSibling moves over to the vacant position
Dad dies and his oldest brother takes over the business.
This assumes that there is such a brother to take the vacant position.
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 28
Deleting Nodes (J is simple (?))
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - THEMODULARWAY
ADVANCED FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
29
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Deleting Nodes (J is simple (?))// Delete the node and all of its children.$query = $this->_db->getQuery(true);$query->delete();$query->from($this->_tbl);$query->where('lft BETWEEN ' . (int) $node->lft . ' AND ' . (int)
$node->rgt);$this->_runQuery($query,
'JLIB_DATABASE_ERROR_DELETE_FAILED');
// Compress the left values.$query = $this->_db->getQuery(true);$query->update($this->_tbl);$query->set('lft = lft - ' . (int) $node->width);$query->where('lft > ' . (int) $node->rgt);$this->_runQuery($query,
'JLIB_DATABASE_ERROR_DELETE_FAILED');
// Compress the right values.$query = $this->_db->getQuery(true);$query->update($this->_tbl);$query->set('rgt = rgt - ' . (int) $node->width);$query->where('rgt > ' . (int) $node->rgt);$this->_runQuery($query,
'JLIB_DATABASE_ERROR_DELETE_FAILED');
ADVANCED FUNCTIONS
Find width of subtree: (rgt-lft)+1 Find offset of subtree: (old lft-new left) Store original lft Add width to lft and rgt where lft>=new left (creating gap) Change lft and rgt of subtree to lft-offset and rgt-offset where lft between cur_lft and
cur_left+width (filling gap) Subtract width from lft and rgt where lft>=new lft+width (connecting right)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 30
Moving Subtrees (J is simple)
ADVANCED FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 31
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Moving Subtrees (J is simple)
ADVANCED FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 31
1
2
3 45 67
8 9
10 1
1
12 1
3
14
15
18
19
17
16
20
21
22
Moving Subtrees (J is simple)
ADVANCED FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang
Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 32
1
2
3 4 9 10 1
5
16 1
7
18
19
22
23
21
20
24
21
22
11
12
13
14
Moving Subtrees (J is simple)width = (16-13)+1 = 4orig_lft = 13offset = (orig_lft-new_lft)+width = 12
ADVANCED FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang
Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 33
1
2
3 45 10 1
5
16
22
23
21
24
21
22
11
12
13
14
6 7
89
Moving Subtrees (J is simple)width = (16-13)+1 = 4orig_lft = 13offset = (orig_lft-new_lft)+width = 12
ADVANCED FUNCTIONS
Terry Earls
Charlotte Weiss
Rob Walters
Manuel Oliveira
Dan Wilson
Chen Yang
Phyllis Harris
Mark Hanson
Maureen Magnotta
Patricia Doyle
Mike Nash
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 34
1
2
3 4 5 10 1
5
16
18
19
17
20
21
22
11
12
13
14
6 7
89
Moving Subtrees (J is simple)width = (16-13)+1 = 4orig_lft = 13offset = (orig_lft-new_lft)+width = 12
AGENDA
Introduction (5min) Simple Explanation of Nested Data Sets (10min) Types of Hierarchies (5min) The Joomla Way (5min) Basic Functions (15min) Advanced Functions (10min) The Ten Commandments
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 35
TEN COMMANDMENTS
I am not the Lord thy God, test on your own
Thou shalt think if Nested Sets are what you need
Thou shalt utilize native Joomla! if adequate
Thou must add index to rgt Honor thy table locks
Thou shalt think about a-synch data Thou shalt separate entities from
hierarchy Hierarchy Leafs are still categories (Thou
shalt) Thou shalt allow entities belonging to
many nodes
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 36
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 37
HET EINDEja, ik spreek vloeiend nederlands...