32
Построение индекса по иерархии записей в реляционной БД Андрей Майоров. BYTE-force

Построение индекса по иерархии записей в реляционной базе данных

  • Upload
    sqalab

  • View
    1.087

  • Download
    2

Embed Size (px)

DESCRIPTION

Андрей Майоров, BYTE-force, Ярославль, Россия

Citation preview

  • 1. . BYTE-force

2. .Object * id . name , . , Relation * parent . child 3. . , . . 4. ? . . . ... 5. Photo by http://www.flickr.com/photos/shannonpatrick17/ 6. CONNECT BY Oracle employee SELECT nameemployee_idFROM employeenameSTART WITH name = 'John' manager CONNECT BY PRIOR employee_id = manager John, , , etc. LEVEL . 7. CONNECT BY , . , . Oracle. 8. Common Table Expressions WITH t( employee, name ) AS ( SELECTemployee_id, name FROMemployee WHERE name = 'John' UNION ALL SELECTnext.employee_id, next.name FROMemployee as nextINNER JOIN t ON t.employee_id = next.manager ) SELECT name FROM t SELECT CTE START WITH, CONNECT BY PRIOR. 9. CTE CONNECT BY . . UNION ALL , . CTE , (MySQL, Firebird, PostgreSQL .). 10. , . CTE. . , . 11. ... . , , . 12. ? . : Lineage (materialized path) 13. Lineage () - http://www.sqlteam.com/article/more-trees-hierarchies-in-sql EmployeeIDNameBossID Denis Eaton-Hogg1001Denis Eaton-HoggNULL Bobbi Flekman Ian Faith1002Bobbi Flekman 1001David St. Hubbins1003Ian Faith 1002Nigel TufnelDerek Smalls1004David St. Hubbins 10031005Nigel Tufnel10031006Derek Smalls1003 Node ParentNodeEmployeeID DepthLineage100NULL1001 0/101100 1002 1/100/102101 1003 2/100/101/103102 1004 3/100/101/102/104102 1005 3/100/101/102/105102 1006 3/100/101/102/ 14. Lineage . . . . . 15. ID Name ParentID 1 1NULL2 2 13 5 3 16 4 1 4 537 8 6 3 - http://www.osp.ru/os/2003/04/182942/7 48 41 1 16 ID LeftRightLevel IsLeaf11 16 1 N22 32 Y 2 2 3 4 3 9104 1534 92 N41015 2 N55 63 Y67 83 Y 5 5 6 7 6 8 11 712 13 8 1471112 3 Y81314 3 Y 16. . . . 17. Image by http://www.flickr.com/photos/36041246@N00/3344 18. Object RelationMapidparentnamechilddistancecount Relationparentchild 19. . . covering index. . Object RelationMapidparent namechild distance. count 20. 1 , . 2 3 4 5 . 6 7 . . 21. 7 8A 1 : 8 7 ( 1). 3 8 7 , 45 7. 7, 7.8 22. 7 8 8 7 ( 1). B 1 8 7 ( + 1). 3 7 8 4 5 ( + 1). , 7, 7 9 A, . 8 9 3 8 9 A 7 1. 23. Bx 1 7 x cx 3 dx, 45 y 8 cy dy, 7 y x cx*cy dx+dy+1. 8: 1 * 2 = 2 9 A : 1 + 2 +1 = 4y 24. parent - child : foreachx in descendants( child ), dx in distances( x, child ),y in ancestors( parent ), dy in distances( parent, y ) count(x,child,dx)*count(parent,y,dy) x y dx+dy+1. count(x,y,d) x y d ancestors(x) descendants(x) x distances(x, x) == [ ] 25. Object RelationMapidparentnamechilddistancecount Relationparent RelationMap child . . 26. SQL: SELECT d.child, a.parent, a.distance + d.distance + 1,sum( a.count * d.count ) FROM ( SELECT * FROM RelationMap WHEREchild = @iParent UNION SELECT @iParent, @iParent, 0, 1) AS a,( SELECT * FROM RelationMap WHEREparent = @iChild UNION SELECT @iChild, @iChild, 0, 1) AS d GROUP BY d.object, a.ancestor, a.distance + d.distance + 1 27. , @iParent . 0 1. , @iChild . . , . , . , . . 28. SQL: UPDATE RelationMap SETcount = om.count + st.count FROM @tSubTree st JOIN RelationMap om ON st.child = om.child ANDst.parent = om.parent ANDst.distance = om.distanceINSERT INTO RelationMap SELECT st.child, st.parent, st.distance, st.count FROM @tSubTree st LEFT JOIN RelationMap om ON st.child = om.child ANDst.parent = om.parent ANDst.distance = om.distance WHERE om.child IS NULL 29. SQL: UPDATE RelationMap SETcount = om.count - st.count FROM @tSubTree st JOIN RelationMap om ON st.child = om.child ANDst.parent = om.parent ANDst.distance = om.distanceDELETE FROM RelationMap WHEREcount = 0 30. . . . . , , @iParent @iChild (.. ). . 31. , . RelationMap, . , . 32. . . . : http://blogs.byte-force.com/files/folders/articles_ru/entry1148.aspx