Traversing Hierarchies
|
|
|
- Luke Hampton
- 9 years ago
- Views:
Transcription
1
2 Nielsen c17.tex V4-07/21/ :57pm Traversing Hierarchies T raditionally, SQL has had a hard time getting along with data that doesn t fit well into a relational grid, and that includes hierarchical data. The lack of an elegant solution became obvious when working with family trees, bills of materials, organizational charts, layers of jurisdictions, or modeling O-O class inheritance. At best, the older methods of handling hierarchies were more of a clumsy work-around than a solution. The problems surrounding hierarchical data involve modeling the data, navigating the tree, selecting multiple generations of ancestors or descendents, or manipulating the tree i.e., moving portions of the tree to another location or inserting items. When the requirements demand a many-to-many relationship, such as a bill of materials, the relationships become even more complex. New query methods, new data types, and a better understanding of hierarchical information by the SQL community have coalesced to make this an area where SQL Server offers intelligent, scalable solutions to hierarchical problems. Is managing hierarchical data as easy as SEECT * from foo? No. Hierarchies still don t fit the traditional relational model so it takes some work to understand and code a database that includes a hierarchy. The initial question when working with hierarchical data is how to store the hierarchy, as hierarchies aren t natural to the relational model. There are several possibilities to choose from. In this chapter I ll explain three techniques (there are other methods but this chapter focuses on three), each with its own unique pros and cons: Adjacency list: By far, the most popular method Materialized path: My personal favorite method HierarchyID: Microsoft s new method Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 399 IN THIS CHAPTER Hierarchical patterns Hierarchical user-defined functions (UDFs) Recursive CTE queries Materialized lists HierarchyID data type Page 399
3 Part III Beyond Relational What s New with Hierarchies? SQL Server 2005 introduced ANSI SQL 99 s recursive common table expressions (CTEs), which lessened the pain of querying hierarchies modeled using the adjacency list pattern. Recursive CTEs are simpler and often faster than the SQL Server 2000 methods of writing a user-defined function to iteratively query each level. The big news for SQL Server 2008 is the HierarchyID data type a fast, compact CLR data type with several methods for querying and managing hierarchies. Hierarchies are common in the real world, which is why they are so important for database design and development. The word hierarchy comes from the Greek and was first used in English in 1880 to describe the order of angles. I highly recommend you take the time to read the Wikipedia article on hierarchies fascinating stuff. Simple hierarchies only have a one parent to many children relationship and may be modeled using any of the three techniques. Examples of simple hierarchies include the following: Organizational charts Object-oriented classes Jurisdictions Taxonomy, or a species tree Network marketing schemes File system directory folders More complex hierarchies, referred to in the mathematics world as graphs, involve multiple cardinalities and can only be modeled using variations of the adjacency list pattern: Genealogies: A child may have multiple parent relationships. Bill of materials: An assembly may consist of multiple sub-assemblies or parts, and the assembly may be used in multiple parent assemblies. Social Network Follows: A person may follow multiple other people, and multiple people may follow the person. Complex organizational charts: An employee may report to one supervisor for local administration duties and another supervisor for technical issues on a global scale. 400
4 Traversing Hierarchies 17 This chapter walks through the three aforementioned patterns (adjacency lists, materialized paths, and HierarchyIDs) for storing hierarchical data and presents several ways of working with the data for each pattern. For each method, I present the tasks in the flow that make the most sense for that method. It s possible that some hierarchies have more than one top node. For example, a jurisdiction hierarchy with countries, states, counties, and cities could have multiple country nodes at the top. This pattern is sometimes referred to as a hierarchical forest (with many trees.) Because the material for this chapter exceeds the allotted page count, you can find several additional code examples in the chapter script file, which you can download from Adjacency List Pattern The traditional pattern used to model hierarchical data is the adjacency list pattern, informally called the self-join pattern, which was presented by Dr. Edgar F. Codd. The adjacency list pattern stores both the current node s key and its immediate parent s key in the current node row. (This chapter refers to the two data elements in the data pair as current node and parent node.) The most familiar example of the adjacency list pattern is a simple organizational chart like the one in the AdventureWorks2008 sample database, partially illustrated in Figure In a basic organizational chart, there s a one-to-many relationship between employees who play the role of supervisor, and employees who report to supervisors. Supervisors may have multiple employees reporting to them, but every employee can have only one supervisor. An employee may both be a supervisor and report to another supervisor. The adjacency lists pattern handles this one-to-many relationship by storing the parent node s primary key in the current node. This allows multiple current nodes to point to a single parent node. In the case of the basic organizational chart, the employee is the current node, and the manager is the parent node. The employee s row points to the employee s manager by storing the manager s ID in the employee s ManagerID column. Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 401
5 Part III Beyond Relational FIGURE 17-1 Jean Trenary and her crew are the able Information Service Department at AdventureWorks. 1 Ken Sánchez Chief Executive Officer 263 Jean Trenary Information Services Manager Adventure Works 2008 Information Service Department 264 Stephanie Conroy Network Manager 265 Ashvini Sharma Network Administrator 266 Peter Connelly Network Administrator 267 Karen Berg Application Specialist 268 Ramesh Meyyappan Application Specialist 269 Dan Bacon Application Specialist 272 Janaina Bueno Application Specialist 270 François Ajenstat Database Administrator 271 Dan Wilson Database Administrator The next query result shows the data from the Information Service Department: BusinessEntityID ManagerID Name JobTitle Manager Jean Trenary Information Services Manager 1 Ken Sánchez 264 Stephanie Conroy Network Manager 263 Jean Trenary 267 Karen Berg Application Specialist 263 Jean Trenary 268 Ramesh Meyyappan Application Specialist 263 Jean Trenary 269 Dan Bacon Application Specialist 263 Jean Trenary 270 François Ajenstat Database Administrator 263 Jean Trenary 271 Dan Wilson Database Administrator 263 Jean Trenary 272 Janaina Bueno Application Specialist 263 Jean Trenary 265 Ashvini Sharma Network Administrator 264 Stephanie Conroy 266 Peter Connelly Network Administrator 264 Stephanie Conroy 402
6 Traversing Hierarchies 17 To examine one row from the employee perspective, Karen Berg s BusinessEntityID (PK) is 264. Her ManagerID is 263. That s the BusinessEntityID for Jean Trenary, so Karen reports to Jean. From the supervisor s point of view, his BusinessEntityID is stored in each of his direct report s rows in the ManagerID column. For example, Jean Trenary s BusinessEntityID is 263, so 263 is stored in the ManagerID column of everyone who reports directly to her. To maintain referential integrity, the ManagerID column has a foreign key constraint that refers to the BusinessEntityID column (the primary key) in the same table, as shown in Figure The ManagerID column allows nulls so that the top person of the organization chart can report to no one. FIGURE 17-2 The Employee table has a foreign key reference from the ManagerID column to the same table s primary key. That s why this pattern is often called the self-join pattern. Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 403
7 Part III Beyond Relational Restoring AdventureWorks2008 s Adjacency List With the advent of the HierarchyID data type in SQL Server 2008, Microsoft removed the adjacency list pattern from AdventureWorks2008 and replaced it with HierarchyID. The following script repairs AdventureWorks2008 and readies the database for experimentation with the adjacency list pattern: ALTER TABLE HumanResources.Employee ADD ManagerID INT CONSTRAINT FK_AdjPairs FOREIGN KEY(ManagerID) REFERENCES HumanResources.Employee(BusinessEntityID); GO -- Update new ManagerID Column using join condition to match UPDATE E SET ManagerID = M.BusinessEntityID FROM HumanResources.Employee AS E JOIN HumanResources.Employee AS M ON M.OrganizationNode = E.OrganizationNode.GetAncestor(1); CREATE INDEX IxParentID ON HumanResources.Employee (ManagerID) AdventureWorks2008 is now ready for some adjacency list fun with Ken Sánchez, the CEO; Jean Trenary, the IT Manager; and François Ajenstat, the DBA. Single-level queries The simplest hierarchical task is to match every node with a direct connection one level up the hierarchy. In this case, it means listing all AdventureWorks2008 employees and their supervisor. The crux of the query is the self-join between two instances of the employee table represented in the LEFT OUTER JOIN between the employee s (E) ManagerID column and the manager s (M) BusinessEntityID column. There s still one physical employee table, but the query contains two references to the table and joins the two table references together, i.e., the query is joining the table back to itself. Notice that because it s an outer join, an employee without a manager (i.e., the CEO) will still show up in the result list: -- basic self-join query SELECT E.BusinessEntityID as Employee, M.BusinessEntityID as Manager FROM HumanResources.Employee as E LEFT OUTER JOIN HumanResources.Employee as M ON E.ManagerID = M.BusinessEntityID; 404
8 Traversing Hierarchies 17 Result (abbreviated): Employee Manager Null Of course, listing integers isn t very useful. The next query adds some meat to the bones and fleshes out the data into a readable result set: -- Employees and their Direct Supervisors SELECT E.BusinessEntityID AS EmpID, EP.FirstName + + EP.LastName AS EmpName, E.JobTitle AS EmpTitle, E.ManagerID AS [MgrID], MP.FirstName + + MP.LastName AS MgrName, M.JobTitle AS MgrTitle FROM HumanResources.Employee AS E -- the employee JOIN Person.Person AS EP -- the employee s contact info ON E.BusinessEntityID = EP.BusinessEntityID LEFT OUTER JOIN HumanResources.Employee AS M -- the mgr(if there is one) ON E.ManagerID = M.BusinessEntityID LEFT JOIN Person.Person AS MP -- the manager s contact info ON M.BusinessEntityID = MP.BusinessEntityID ORDER BY E.ManagerID, E.BusinessEntityID; The abbreviated result is shown in Figure FIGURE 17-3 Results from the query showing every employee and his manager. Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 405
9 Part III Beyond Relational The reverse of find all managers, which searches one level up the hierarchy query, is searching down the hierarchy. This query uses a downward looking join to locate every employee who has direct reports. The key to understanding this query is the self-join between the Employee table as M, representing the managers, and the Employee as E, representing the employees: -- Every Manager and their direct Reports SELECT M.BusinessEntityID AS MgrID, MP.FirstName + + MP.LastName AS MgrName, M.JobTitle AS MgrTitle, E.BusinessEntityID AS EmpID, EP.FirstName + + EP.LastName AS EmpName, E.JobTitle AS EmpTitle FROM HumanResources.Employee AS M -- the manager JOIN Person.Person AS MP -- the manager s contact info ON M.BusinessEntityID = MP.BusinessEntityID JOIN HumanResources.Employee AS E -- the direct report ON E.ManagerID = M.BusinessEntityID JOIN Person.Person AS EP -- the manager s contact info ON E.BusinessEntityID = EP.BusinessEntityID ORDER BY M.BusinessEntityID The result is shown in Figure FIGURE 17-4 Results of the query showing every manager and his direct reports. The last adjacency list single-level query performs a count of each manager s direct reports. Here, the work is being done in the subquery, which groups by the ManagerID column and counts the number or rows for each ManagerID: -- Everyone who has Direct Reports w/count SELECT M.BusinessEntityID as ID, MP.FirstName + + MP.LastName AS Manager, M.JobTitle, C.DirectReports FROM HumanResources.Employee AS M -- the manager JOIN Person.Person AS MP -- the manager s contact info ON M.BusinessEntityID = MP.BusinessEntityID JOIN (SELECT ManagerID, COUNT(*) AS DirectReports FROM HumanResources.Employee 406
10 Traversing Hierarchies 17 WHERE ManagerID IS NOT NULL GROUP BY ManagerID) AS C ON M.BusinessEntityID = C.ManagerID; ORDER BY Manager Result (abbreviated): ID Manager JobTitle DirectReports A. Scott Wright Master Scheduler Amy Alberts European Sales Manager 3 47 Andrew Hill Production Supervisor - WC Brenda Diaz Production Supervisor - WC Brian Welcker Vice President of Sales Christian Kleinerman Maintenance Supervisor 4... Subtree queries The preceding queries work well with one level. If you need to return all the nodes for two levels, then you could add another self-join. As the number of levels needed increases, the queries become complex and the query is fixed to a certain number of levels. A continuing parade of self-joins is not the answer. SQL queries should be able to handle any amount of data, so an adjacency list subtree query should be able to handle any number of levels. There are two solutions to the subtree problem when using the adjacency model: a recursive CTE or a looping user-defined function. Recursive CTE down the hierarchy The most direct solution to the subtree problem is the recursive common table expression, introduced in SQL Server This variant of the CTE (the basic CTE is covered in Chapter 11, Including Data with Subqueries and CTEs ) uses a UNION ALL and two SELECT statements. The first SELECT statement defines the anchor node from which the recursion will start, i.e., the top of the subtree. When the recursion starts, the row(s) returned by this query are added to the CTE. The second SELECT defines how rows are recursively added to the result set. This SELECT statement joins with the CTE itself similar to the earlier self-join and uses the UNION ALL to add the rows to the output of the CTE. The key is that the second SELECT will continue to self-join through the layers of the hierarchy until no more rows are found. The loop stops executing when no more data is returned from the recursive step of the CTE. The first example focuses on the recursive nature of the CTE. The first SELECT in the CTE locates the employee with a ManagerID of null, which should be the top of the hierarchy. The name of the CTE is OrgPath, so when the second select joins with OrgPath it can find all the related nodes. The CTE continues to execute the second SELECT for every level of the hierarchy until the hierarchy ends: -- Find all - Recursive CTE down the OrgChart -- All employees who report to the CEO -- simple query Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 407
11 Part III Beyond Relational WITH OrgPath (BusinessEntityID, ManagerID, lv) AS ( -- Anchor SELECT BusinessEntityID, ManagerID, 1 FROM HumanResources.Employee WHERE ManagerID IS NULL -- should only be EmployeeID 1 -- Recursive Call UNION ALL SELECT E.BusinessEntityID, E.ManagerID, lv + 1 FROM HumanResources.Employee AS E JOIN OrgPath ON E.ManagerID = OrgPath.BusinessEntityID ) SELECT BusinessEntityID, ManagerID, lv FROM OrgPath ORDER BY Lv, BusinessEntityID OPTION (MAXRECURSION 20); Result (abbreviated): BusinessEntityID ManagerID lv NULL Because you join to the CTE in the recursive section of the CTE, you can use columns from this iteration to calculate the level in the hierarchy. In the previous query, the Lv column is calculated using the lv column from the previous iteration + 1. Thus, each iteration is given a sequential level number. If the adjacency list data had a cyclic error (A reports to B, who reports to C, who reports to A), then the recursive query could run forever, in which case the maxrecursion option limits the levels of recursion. If the recursive CTE hits the maxrecursion limit and there s still data yet unprocessed, it will raise a 530, level 16 error, so even if the requirement is to return five levels of the hierarchy, option(maxrecursion 5) will return an error. Horrors! A solution is to use a WHERE clause in the second SELECT: WHERE Lv <= 3 This will safely limit the second query to return the first four levels of the hierarchy without throwing an error. 408
12 Traversing Hierarchies 17 The next query extends the previous recursive CTE by adding joins to flesh out the data. It also uses a different anchor node Jean Trenary, Adventure Works IT Manager: -- Find Subtree - Recursive CTE -- All employees who report to IT Manager -- full query with joins WITH OrgPath (BusinessEntityID, ManagerID, lv) AS ( -- Anchor SELECT BusinessEntityID, ManagerID, 1 FROM HumanResources.Employee WHERE BusinessEntityID = Jean Trenary - IS Manager -- Recursive Call UNION ALL SELECT E.BusinessEntityID, E.ManagerID, lv + 1 FROM HumanResources.Employee AS E JOIN OrgPath ON E.ManagerID = OrgPath.BusinessEntityID ) SELECT Lv, Emp.BusinessEntityID, C.FirstName + + C.LastName AS [Name], Emp.JobTitle, OrgPath.ManagerID, M.FirstName + + M.LastName AS [Manager] FROM HumanResources.Employee AS Emp JOIN OrgPath ON Emp.BusinessEntityID = OrgPath.BusinessEntityID JOIN Person.Person AS C ON C.BusinessEntityID = Emp.BusinessEntityID LEFT JOIN Person.Person AS M ON Emp.ManagerID = M.BusinessEntityID ORDER BY Lv, BusinessEntityID OPTION (MAXRECURSION 20); Result (abbreviated): BusinessEntityID ManagerID Lv Name JobTitle Manager Jean Trenary Information Services Manager 1 Ken Sánchez Stephanie Conroy Network Manager 263 Jean Trenary Karen Berg Application Specialist 263 Jean Trenary Ramesh Meyyappan Application Specialist 263 Jean Trenary Dan Bacon Application Specialist 263 Jean Trenary François Ajenstat Database Administrator 263 Jean Trenary Dan Wilson Database Administrator 263 Jean Trenary Janaina Bueno Application Specialist 263 Jean Trenary Ashvini Sharma Network Administrator 264 Stephanie Conroy Peter Connelly Network Administrator 264 Stephanie Conroy... Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 409
13 Part III Beyond Relational User-defined function down the hierarchy SQL Server 2005 s recursive CTE is not the only way to skin a hierarchy. Before 2005, hierarchies were handled with stored procedures or user-defined functions that looped through the hierarchy layers adding each layer as a set to a temp table or table variable effectively doing the same thing as a CTE but with T-SQL. The following multiple-statement table-valued user-defined function accepts an EmployeeID as a parameter. The function returns this employee and all the employees below them in the organization tree. The function definition includes the structure for the returned table variable, The function first inserting the anchor node, the employee for the EmployeeID passed to the function. This method jumps ahead a bit, using an advanced programming feature of SQL Server to solve the hierarchical problem. For more information about one of my personal favorite features of SQL Server, see Chapter 25, Building User-Defined Functions. The WHILE loop continues to INSERT the next hierarchy level until no more rows are found (@@rowcount > 0). Even though this is a loop, it s still performing nice set-based inserts, one for every hierarchy level. If the hierarchy has a million nodes and is nine levels deep, then nine set-based inserts complete the entire task from top to bottom: -- User-Defined Functions for Navigating Adjacency list CREATE FUNCTION dbo.orgtree (@BusinessEntityID INT) TABLE (BusinessEntityID INT, ManagerID INT, Lv INT) AS BEGIN INT = 1 -- insert the top level (anchor node) (BusinessEntityID, ManagerID, Lv) SELECT BusinessEntityID, FROM HumanResources.Employee AS E -- the employee WHERE BusinessEntityID -- Loop through each lower levels > 0 BEGIN insert the Next level of employees (BusinessEntityID, ManagerID, Lv) SELECT NextLevel.BusinessEntityID, FROM HumanResources.Employee AS NextLevel AS CurrentLevel ON CurrentLevel.BusinessEntityID = NextLevel.ManagerID WHERE CurrentLevel.Lv
14 Traversing Hierarchies 17 END RETURN END; -- end of function A table-valued function returns a result set so it s called in the FROM clause. The following query returns AdventureWorks2008 s entire organizational chart: -- test UDF -- find all -- simple query SELECT * FROM dbo.orgtree(1); Result (abbreviated):... BusinessEntityID ManagerID Lv NULL Best Practice The recursive CTE in this case is about twice as fast as the user-defined function. However, the function can include more variations of code, so it s useful to know both methods. Just as with the recursive CTE, it s easy to expand the query and include the data necessary for a human-readable result set. Just like the previous recursive CTE example, this query finds only the subtree of those who work for Jean Trenary in the IT dept: -- find subtree -- all who work in IT -- full query with joins SELECT Lv, Emp.BusinessEntityID, Emp.JobTitle, C.FirstName + + C.LastName AS [Name], OrgTree.ManagerID, M.FirstName + + M.LastName AS [Manager] FROM HumanResources.Employee AS Emp JOIN dbo.orgtree (263) -- Jean Trenary, IT Manager ON Emp.BusinessEntityID = OrgTree.BusinessEntityID JOIN Person.Person AS C Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 411
15 Part III Beyond Relational ON C.BusinessEntityID = Emp.BusinessEntityID LEFT JOIN Person.Person AS M ON Emp.ManagerID = M.BusinessEntityID ORDER BY Lv, BusinessEntityID; Result (abbreviated): BusinessEntityID ManagerID Lv Name JobTitle Manager Jean Trenary Information Services Manager 1 Ken Sánchez Stephanie Conroy Network Manager 263 Jean Trenary Karen Berg Application Specialist 263 Jean Trenary Ramesh Meyyappan Application Specialist 263 Jean Trenary Dan Bacon Application Specialist 263 Jean Trenary François Ajenstat Database Administrator 263 Jean Trenary Dan Wilson Database Administrator 263 Jean Trenary Janaina Bueno Application Specialist 263 Jean Trenary Ashvini Sharma Network Administrator 264 Stephanie Conroy Peter Connelly Network Administrator 264 Stephanie Conroy... A nice feature of the table-valued user-defined function is that it can be called from the CROSS APPLY (new in SQL Server 2005), which executes the function once for every row in the outer query. Here, the CROSS APPLY is used with the function to generate an extensive list of every report under every BusinessEntityID from HumanResources.Employee: -- using Cross Apply to report all node under everyone SELECT E.BusinessEntityID, OT.BusinessEntityID, OT.Lv FROM HumanResources.Employee AS E CROSS APPLY dbo.orgtree(businessentityid) AS OT; The next query builds on the previous query, adding a GROUP BY to present a count of the number of reports under every manager. Because it explodes out every manager with its complete subtree, this query returns not 290 rows, but 1,308: -- Count of All Reports SELECT E.BusinessEntityID, COUNT(OT.BusinessEntityID)-1 AS ReportCount FROM HumanResources.Employee E CROSS APPLY dbo.orgtree(businessentityid) OT GROUP BY E.BusinessEntityID HAVING COUNT(OT.BusinessEntityID) > 1 ORDER BY COUNT(OT.BusinessEntityID) DESC; Result (abbreviated): BusinessEntityID BusinessEntityID Lv
16 Traversing Hierarchies 17 Recursive CTE looking up the hierarchy The previous adjacency list subtree queries all looked down the hierarchical tree. Searching up the tree returns the path from the node in question to the top of the hierarchy for an organizational chart, it would return the chain of command from the current node to the top of the organizational chart. The technical term for this search is an ancestor search. The queries to search up the hierarchy are similar to the downward-looking queries, only the direction of the join is modified. The following queries demonstrate the modification. This query returns François the DBA s chain of command to the CEO using a recursive CTE: Result: Adjacency list -- navigating up the tree -- Recursive CTE WITH OrgPathUp (BusinessEntityID, ManagerID, lv) AS ( -- Anchor SELECT BusinessEntityID, ManagerID, 1 FROM HumanResources.Employee WHERE BusinessEntityID = François Ajenstat the DBA -- Recursive Call UNION ALL SELECT E.BusinessEntityID, E.ManagerID, lv + 1 FROM HumanResources.Employee AS E JOIN OrgPathUp ON OrgPathUp.ManagerID = E.BusinessEntityID ) SELECT Lv, Emp.BusinessEntityID, C.FirstName + + C.LastName AS [Name], Emp.JobTitle FROM HumanResources.Employee Emp JOIN OrgPathUp ON Emp.BusinessEntityID = OrgPathUp.BusinessEntityID JOIN Person.Person AS C ON C.BusinessEntityID = Emp.BusinessEntityID LEFT JOIN Person.Person AS M ON Emp.ManagerID = M.BusinessEntityID ORDER BY Lv DESC, BusinessEntityID OPTION (MAXRECURSION 20); BusinessEntityID Lv Name JobTitle Ken Sánchez Chief Executive Officer Jean Trenary Information Services Manager François Ajenstat Database Administrator Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 413
17 Part III Beyond Relational Searching up the hierarchy with a user-defined function Modifying the recursive CTE to search up the hierarchy to find the chain of command, instead of search down the hierarchy to find the subtree, was as simple as changing the join criteria. The same is true for a user-defined function. The next function searches up the hierarchy and is called for François the DBA. The modified join is shown in bold: Result : -- Classic UDF CREATE FUNCTION dbo.orgtreeup (@BusinessEntityID INT) TABLE (BusinessEntityID INT, ManagerID INT, Lv INT) AS BEGIN INT = 1 -- insert the starting level (anchor node) (BusinessEntityID, ManagerID, Lv) SELECT BusinessEntityID, FROM HumanResources.Employee AS E -- the employee WHERE BusinessEntityID -- Loop through each lower levels > 0 BEGIN insert the Next level of employees (BusinessEntityID, ManagerID, Lv) SELECT NextLevel.BusinessEntityID, FROM HumanResources.Employee AS NextLevel AS CurrentLevel ON NextLevel.BusinessEntityID = CurrentLevel.ManagerID WHERE CurrentLevel.Lv - 1 END RETURN END; go -- calling the Function -- chain of command up from François SELECT * FROM dbo.orgtreeup(270); -- François Ajenstat the DBA BusinessEntityID ManagerID Lv NULL 3 414
18 Traversing Hierarchies 17 Is the node an ancestor? A common programming task when working with hierarchies is answering the question, Is node A in node B subtree? In practical terms, it s asking, Does François, the DBA, report to Jean Trenary, the IT manager? Using an adjacency list to answer that question from an adjacency list is somewhat complicated, but it can be done by leveraging the subtree work from the previous section. Answering the question Does employee 270 report to node 263? is the same question as Is node 270 an ancestor of node 263? Both questions can be expressed in SQL as, Is the ancestor node in current node s the ancestor list? The OrgTreeUp() user-defined function returns all the ancestors of a given node, so reusing this user-defined function is the simplest solution: SELECT True WHERE : Jean Trenary IN (SELECT BusinessEntityID FROM OrgTreeUp(270)); : François Ajenstat the DBA Result: True Determining the node s level Because each node only knows about itself, there s no inherent way to determine the node s level without scanning up the hierarchy. Determining a node s level requires either running a recursive CTE or user-defined function to navigate up the hierarchy and return the column representing the level. Once the level is returned by the recursive CTE or user-defined function, it s easy to update a column with the lv value. Reparenting the adjacency list As with any data, there are three types of modifications: inserts, updates, and deletes. With a hierarchy, inserting at the bottom of the node is trivial, but inserting into the middle of the hierarchy, updating a node to a different location in the hierarchy, or deleting a node in the middle of the hierarchy can be rather complex. The term used to describe this issue is reparenting assigning a new parent to a node or set of nodes. For example, in AdventureWorks2008, IT Manager Jean Trenary reports directly to CEO Ken Sánchez, but what if a reorganization positions the IT dept under Terri Duffy, VP of Engineering? How many of the nodes would need to be modified, and how would they be updated? That s the question of reparenting the hierarchy. Because each node only knows about itself and its direct parent node, reparenting an adjacency list is trivial. To move the IT dept under the VP of Engineering, simply update Jean Trenary s ManagerID value: UPDATE HumanResources.Employee SET ManagerID = 2 -- Terri Duffy, Vice President of Engineering WHERE BusinessEntityID = 263; -- Jean Trenary IT Manager Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 415
19 Part III Beyond Relational Deleting a node in the middle of the hierarchy is potentially more complex but is limited to modifying n nodes, where n is the number of nodes that have the node being deleted as a parent. Each node under the node to be deleted must be reassigned to another node. By default, that s probably the deleted node s ManagerID. Indexing an adjacency list Indexing an adjacency list pattern hierarchy is rather straightforward. Create a non-clustered index on the column holding the parent node ID. The current node ID column is probably the primary key and the clustered index and so will be automatically included in the non-clustered index. The parent ID index will gather all the subtree values by parent ID and perform fast index seeks. The following code was used to index the parent ID column when the adjacency list pattern was restored to AdventureWorks2008 at the beginning of this chapter: CREATE INDEX IxParentID ON HumanResources.Employee (ManagerID); If the table is very wide (over 25 columns) and large (millions of rows) then a non-clustered index on the primary key and the parent ID will provide a narrow covering index for navigation up the hierachy. Cyclic errors As mentioned earlier, every node in the adjacency list pattern knows only about itself and its parent node. Therefore, there s no SQL constraint than can possibly test for or prevent a cyclic error. If someone plays an April Fools Day joke on Jean Trenary and sets her ManagerID to, say, 270, so she reports to the DBA (gee, who might have permission to do that?), it would introduce a cyclic error into the hierarchy: UPDATE HumanResources.Employee SET ManagerID = François Ajenstat the DBA WHERE BusinessEntityID = Jean Trenary IT Manager The cyclic error will cause the OrgTree function to loop from Jean to François to Jean to François forever, or until the query is stopped. Go ahead and try it: SELECT True WHERE François Ajenstat the DBA IN (SELECT BusinessEntityID FROM OrgTree(263)); Now set it back to avoid errors in the next section: UPDATE HumanResources.Employee SET ManagerID = 1 the CEO WHERE BusinessEntityID = Jean Trenary IT Manager To locate cyclic errors in the hierarchy, a stored procedure or function must navigate both up and down the subtrees of the node in question and use code to detect and report an out-of-place duplication. Download the latest code to check for cyclic errors from 416
20 Traversing Hierarchies 17 Adjacency list variations The basic adjacency list pattern is useful for situations that include only a one-parent-to-multiple-nodes relationship. With a little modification, an adjacency list can also handle more, but it s not sufficient for most serious production database hierarchies. Fortunately, the basic data-pair pattern is easily modified to handle more complex hierarchies such as bills of materials, genealogies, and complex organizational charts. Bills of materials/multiple cardinalities When there s a many-to-many relationship between current nodes and parent nodes, an associative table is required, similar to how an associative table is used in any other many-to-many cardinality model. For example, an order may include multiple products, and each product may be on multiple orders, so the order detail table serves as an associative table between the order and the product. The same type of many-to-many problem commonly exists in manufacturing when designing schemas for bills of materials. For example, part a23 may be used in the manufacturing of multiple other parts, and part a23 itself might have been manufactured from still other parts. In this way, any part may be both a child and parent of multiple other parts. To build a many-to-many hierarchical bill of materials, the bill of materials serves as the adjacency table between the current part(s) and the parent parts(s), both of which are stored in the same Parts table, as shown in Figure The same pattern used to navigate a hierarchy works for a bill of materials system as well it just requires working through the BillOfMaterials table. The following query is similar to the previous subtree recursive CTE. If finds all the parts used to create a given assembly in manufacturing this is commonly called a parts explosion report. In this instance, the query does a parts explosion for Product 777 Adventure Works popular Mountain-100 bike in Black with a 44 frame: WITH PartsExplosion (ProductAssemblyID, ComponentID, lv, Qty) AS ( -- Anchor SELECT ProductID, ProductID, 1, CAST(0 AS DECIMAL (8,2)) FROM Production.Product WHERE ProductID = Mountain-100 Black, Recursive Call UNION ALL SELECT BOM.ProductAssemblyID, BOM.ComponentID, lv + 1, PerAssemblyQty FROM PartsExplosion CTE JOIN (SELECT * FROM Production.BillOfMaterials WHERE EndDate IS NULL ) AS BOM ON CTE.ComponentID = BOM.ProductAssemblyID ) SELECT lv, PA.NAME AS Assembly, PC.NAME AS Component, Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 417
21 Part III Beyond Relational CAST(Qty AS INT) as Qty FROM PartsExplosion AS PE JOIN Production.Product AS PA ON PE.ProductAssemblyID = PA.ProductID JOIN Production.Product AS PC ON PE.ComponentID = PC.ProductID ORDER BY Lv, ComponentID ; FIGURE 17-5 The bill of materials structure in AdventureWorks uses an adjacency table to store which parts (ComponentID) are used to manufacture which other parts (ProductAssembyID). The result is a complete list of all the parts required to make a mountain bike: lv Assembly Component Qty Mountain-100 Black, 44 Mountain-100 Black, Mountain-100 Black, 44 HL Mountain Seat Assembly 1 2 Mountain-100 Black, 44 HL Mountain Frame - Black,
22 Traversing Hierarchies 17 2 Mountain-100 Black, 44 HL Headset 1 2 Mountain-100 Black, 44 HL Mountain Handlebars 1 2 Mountain-100 Black, 44 HL Mountain Front Wheel 1 2 Mountain-100 Black, 44 HL Mountain Rear Wheel Chain Stays Metal Sheet Handlebar Tube Metal Sheet BB Ball Bearing Cup-Shaped Race 2 4 BB Ball Bearing Cone-Shaped Race 2 4 HL Hub HL Spindle/Axle 1 4 HL Hub HL Spindle/Axle 1 4 HL Hub HL Shell 1 4 HL Hub HL Shell 1 4 HL Fork Steerer 1 5 Fork End Metal Sheet Blade Metal Sheet Fork Crown Metal Sheet Steerer Metal Sheet 6 1 Adjacency list pros and cons The adjacency list pattern is common and well understood, with several points in its favor: Reparenting is trivial. It s easy to manually decode and understand. On the con side, the adjacency list pattern has these concerns: Consistency requires additional care and manual checking for cyclic errors. Performance is reasonable, but not as fast as the materialized list or hierarchyid when retrieving a subtree. The adjacency list pattern is hindered by the need to build the hierarchy if you need to navigate or query related nodes in a hierarchy. This needs to be done iteratively using either a loop in a user-defined function or a recursive CTE. Returning data though a user-defined function also presents some overhead. The Materialized-Path Pattern The materialized-path pattern is another excellent method to store and navigate hierarchical data. Basically, it stores a denormalized, comma-delimited representation of the list of the current node s complete ancestry, including every generation of parents from the top of the hierarchy down to the current node. A common materialized path is a file path: c:\users\pn\documents\sqlserver2009bible\authorreview\submitted François Ajenstat, the DBA, has a hierarchy chain of command that flows from Ken Sánchez (ID: 1) the CEO, to Jean Trenary (ID: 263) the IT Manager, and then down to François (ID: 270). Therefore, his materialized path would be as follows: 1, 263, 270 Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 419
23 Part III Beyond Relational The following scalar user-defined function generates the materialized path programmatically: CREATE FUNCTION dbo.materializedpath INT) RETURNS VARCHAR(200) AS BEGIN VARCHAR(200) = -- Loop through Hierarchy > 0 BEGIN = ISNULL(RTRIM( CAST(@BusinessEntityID AS VARCHAR(10)))+,, ) = ManagerID FROM Humanresources.Employee WHERE BusinessEntityID END END; Executing the function for François Ajenstat (ID:270) returns his materialized path: Result: Select dbo.materializedpath(270) as MaterializedPath MaterializedPath ,263,270, Because the materialized path is stored as a string, it may be indexed, searched, and manipulated as a string, which has its pros and cons. These are discussed later in the chapter. Modifying AdventureWorks2008 for Materialized Path The following script modifies AdventureWorks2008 and builds a materialized path using the previously added ManagerID data and the newly created MaterializedPath user-defined function: ALTER TABLE HumanResources.Employee ADD MaterializedPath VARCHAR(200); continued 420
24 Traversing Hierarchies 17 continued Go UPDATE HumanResources.Employee SET MaterializedPath = dbo.materializedpath(businessentityid); CREATE INDEX IxMaterializedPath ON HumanResources.Employee (MaterializedPath); SELECT BusinessEntityID, ManagerID, MaterializedPath FROM HumanResources.Employee; Result (abbreviated): BusinessEntityID ManagerID MaterializedPath NULL 1, 2 1 1,2, 3 2 1,2,3, 4 3 1,2,3,4, 5 3 1,2,3,5, 6 3 1,2,3,6, 7 3 1,2,3,7, 8 7 1,2,3,7,8, 9 7 1,2,3,7,9, ,263, ,263,264, ,263,264,265, ,263,264,266, ,263,267, ,263,268, ,263,269, ,263,270,... The way the tasks build on each other for a materialized path are very different from the flow of tasks for an adjacency list; therefore, this section first explains subtree queries. The flow continues with ancestor checks and determining the level, which is required for single-level queries. Enforcing the structure of the hierarchy ensuring that every node actually has a parent is a bit oblique when using the materialized-path method. However, one chap, Simon Sabin (SQL Server MVP in the U.K., all-around good guy, and technical editor for this chapter) has an ingenious method. Instead of explaining it here, I ll direct you to his excellent website: Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 421
25 Part III Beyond Relational Subtree queries The primary work of a hierarchy is returning the hierarchy as a set. The adjacency list method used similar methods for scanning up or down the hierarchy. Not so with materialized path. Searching down a materialized path is a piece of cake, but searching up the tree is a real pain. Searching down the hierarchy with materialized path Navigating down the hierarchy and returning a subtree of all nodes under a given node is where the materialized path method really shines. Check out the simplicity of this query: Result: SELECT BusinessEntityID, ManagerID, MaterializedPath FROM HumanResources.Employee WHERE MaterializedPath LIKE 1,263,% BusinessEntityID ManagerID MaterializedPath ,263, ,263,264, ,263,264,265, ,263,264,266, ,263,267, ,263,268, ,263,269, ,263,270, ,263,271, ,263,272 That s all it takes to find a node s subtree. Because the materialized path for every node in the subtree is just a string that begins with the subtree s parent s materialized path, it s easily searched with a LIKE function and a % wildcard in the WHERE clause. It s important that the LIKE search string includes the comma before the % wildcard; otherwise, searching for 1,263% would find 1,2635, which would be an error, of course. Searching up the hierarchy with materialized path Searching up the hierarchy means searching for the all the ancestors, or the chain of command, for a given node. The nice thing about a materialized path is that the full list of ancestors is right there in the materialized path. There s no need to read any other rows. Therefore, to get the parent nodes, you need to parse the materialized path to return the IDs of each parent node and then join to this set of IDs to get the parent nodes. The trick is to extract it quickly. Unfortunately, SQL Server lacks a simple split function. There are two options: build a CLR function that uses the C# split function or build a T-SQL scalar user-defined function to parse the string. 422
26 Traversing Hierarchies 17 A C# CLR function to split a string is a relatively straightforward task: using Microsoft.SqlServer.Server; using System.Data.SqlClient; using System;using System.Collections; public class ListFunctionClass { [SqlFunction(FillRowMethodName = "FillRow", TableDefinition = "list nvarchar(max)")] public static IEnumerator ListSplitFunction(string list) { string[] listarray = list.split(new char[] {, }); Array array = listarray; return array.getenumerator(); } public static void FillRow(Object obj, out String sc) { sc = (String)obj; } } Adam Machanic, SQL Server MVP and one of the sharpest SQL Server programmers around, went on a quest to write the fastest CLR split function possible. The result is posted on SQLBlog.com at But I m a T-SQL guy, so unless there s a compelling need to use CLR, I ll opt for T-SQL. There are a number of T-SQL string-split solutions available. I ve found that the performance depends on the length of the delimited strings. Erland Sommerskog s website analyzes several T-SQL split solutions: Of Erland s solutions, the one I prefer for shorter length strings such as these is in the ParseString user-defined function: -- up the hierarchy -- parse the string CREATE -- alter FUNCTION dbo.parsestring (@list varchar(200)) TABLE (ID INT) AS BEGIN -- code by Erland Sommarskog -- Erland s Website: Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 423
27 Part III Beyond @nextpos int, int, int = = 1 > 0 BEGIN + 1) = CASE > 0 ELSE len(@list) + 1 END - 1 (ID) VALUES + END RETURN END go -- SELECT ID FROM HumanResources.Employee CROSS APPLY dbo.parsestring(materializedpath) WHERE BusinessEntityID = 270 go -- VARCHAR(200) = MaterializedPath FROM HumanResources.Employee WHERE BusinessEntityID = 270 SELECT E.BusinessEntityID, MaterializedPath FROM dbo.parsestring(@matpath) JOIN HumanResources.Employee E ON ParseString.ID = E.BusinessEntityID ORDER BY MaterializedPath Is the node in the subtree? Because the materialized-path pattern is so efficient at finding subtrees, the best way to determine whether a node is in a subtree is to reference the WHERE-like subtree query in a WHERE clause, similar to the adjacency list solution: 424
28 Traversing Hierarchies Does 270 work for 263 SELECT True WHERE 270 IN (SELECT BusinessEntityID FROM HumanResources.Employee WHERE MaterializedPath LIKE 1,263,% ) Determining the node level Determining the current node level using the materialized-path pattern is as simple as counting the commas in the materialized path. The following function uses CHARINDEX to locate the commas and make quickworkofthetask: CREATE FUNCTION MaterializedPathLevel (@Path VARCHAR(200)) RETURNS TINYINT AS BEGIN TINYINT = TINYINT = 0; >0 BEGIN; += 1; + 1 ); END; - 1 END; Testing the function: Result: SELECT dbo.materializedpathlevel( 1,20,56,345,1010 ) As Level Level A function may be easily called within an update query, so pre-calculating and storing the level is a trivial process. The next script adds a Level column, updates it using the new function, and then takes a look at the data: ALTER TABLE HumanResources.Employee ADD Level TINYINT UPDATE HumanResources.Employee SET Level = dbo.materializedpathlevel(materializedpath) Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 425
29 Part III Beyond Relational SELECT BusinessEntityID, MaterializedPath, Level FROM HumanResources.Employee Result (abbreviated): BusinessEntityID MaterializedPath Level , 1 2 1,2, 2 3 1,2,3, 3 4 1,2,3,4, 4 5 1,2,3,5, 4 6 1,2,3,6, 4 7 1,2,3,7, 4 8 1,2,3,7,8, 5 9 1,2,3,7,9, ,2,3,7,10, 5 Storing the level can be useful; for example, being able to query the node s level makes writing single-level queries significantly easier. Using the function in a persisted calculated column with an index works great. Single-level queries Whereas the adjacency list pattern was simpler for doing single-level queries, rather than returning complete subtrees, the materialized-path pattern excels at returning subtrees, but it s more difficult to return just a single level. Although neither solution excels at returning a specific level in a hierarchy on its own, it is possible with the adjacency pattern but requires some recursive functionality. For the materialized-path pattern, if the node s level is also stored in table, then the level can be easily added to the WHERE clause, and the queries become simple. This query locates all the nodes one level down from the CEO. The CTE locates the MaterializedPath and the Level for the CEO, and the main query s join conditions filter the query to the next level down: -- Query Search 1 level down WITH CurrentNode(MaterializedPath, Level) AS (SELECT MaterializedPath, Level FROM HumanResources.Employee WHERE BusinessEntityID = 1) SELECT BusinessEntityID, ManagerID, E.MaterializedPath, E.Level FROM HumanResources.Employee E JOIN CurrentNode C ON E.MaterializedPath LIKE C.MaterializedPath + % AND E.Level = C.Level
30 Traversing Hierarchies 17 Result: BusinessEntityID ManagerID MaterializedPath Level ,16, ,2, ,234, ,25, ,263, ,273, 2 An advantage of this method over the single join method used for finding single-level queries for the adjacency list pattern is that this method can be used to find any specific level, not just the nearest level. Locating the single-level query up the hierarchy is the same basic outer query, but the CTE/subquery uses the up-the-hierarchy subtree query instead, parsing the materialized path string. Reparenting the materialized path Because the materialized-path pattern stores the entire tree in the materialized path value in each node, when the tree is modified by inserting, updating, or deleting a node, the entire affected subtree must have its materialized path recalculated. Each node s path contains the path of its parent node, so if the parent node s path changes, so do the children. This will propagate down and affect all descendants of the node being changed. The brute force method is to reexecute the user-defined function that calculates the materialized path. A more elegant method, when it applies, is to use the REPLACE T-SQL function. Indexing the materialized path Indexing the materialized path requires only a non-clustered index on the materialized path column. Because the level column is used in some searches, depending on the usage, it s also a candidate for a non-clustered index. If so, then a composite index of the level and materialized path columns would be the best-performing option. Materialized path pros and cons There are some points in favor of the materialized-path pattern: The strongest point in its favor is that in contains the actual references to every node in its hierarchy. This gives the pattern considerable durability and consistency. If a node is deleted or updated accidentally, the remaining nodes in its subtree are not orphaned. The tree can be reconstructed. If Jean Trenary is deleted, the materialized path of the IT department employees remains intact. Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 427
31 Part III Beyond Relational The materialized-path pattern is the only pattern that can retrieve an entire subtree with a single index seek. It s wicked fast. Reading a materialized path is simple and intuitive. The keys are there to read in plain text. On the down side, there are a number of issues, including the following: The key sizes can become large; at 10 levels deep with an integer key, the keys can be bytes in size. This is large for a key. Constraining the hierarchy is difficult without the use of triggers or complex check constraints. Unlike the adjacency list pattern, you cannot easily enforce that a parent node exists. Simple operations like get me the parent node are more complex without the aid of helper functions. Inserting new nodes requires calculating the materialized path, and reparenting the materialized path requires recalculating the materialized paths for every node in the affected subtree. For an OLTP system this can be a very expensive operation and lead to a large amount of contention. Offloading the maintenance of the hierarchy to a background process can alleviate this. An option is to combine adjacency and path solutions; one provides ease of maintenance and one provides performance for querying. The materialized path is my favorite hierarchy pattern and the one I use in Nordic (my SQL Server object relational façade) to store the class structure. Using the New HierarchyID For SQL Server 2008, Microsoft has released a new data type targeted specifically at solving the hierarchy problem. Working through the materialized-path pattern was a good introduction to HierarchyID because HierarchyID is basically a binary version of materialized path. HierarchyID is implemented as a CLR data type with CLR methods, but you don t need to enable CLR to use HierarchyID. Technically speaking, the CLR is always running. Disabling the CLR only disables installing and running user-programmed CLR assemblies. To jump right into the HierarchyID, this first query exposes the raw data. The OrganizationalNode column in the HumanResources.Employee table is a HierarchyID column. The second column simply returns the binary data from OrganizationalNode. The third column, HierarchyID.ToString() uses the.tostring() method to converrt the HierarchyID data to text. The column returns the values stored in a caluculated column that s set to the.getlevel() method: -- View raw HierarchyID Data SELECT E.BusinessEntityID, P.FirstName + + P.LastName as Name, OrganizationNode, OrganizationNode.ToString() as HierarchyID.ToString(), OrganizationLevel FROM HumanResources.Employee E 428
32 Traversing Hierarchies 17 JOIN Person.Person P ON E.BusinessEntityID = P.BusinessEntityID Result (abbreviated): BusinessEntityID OrganizationNode HierarchyID.ToString() OrganizationLevel x / 0 2 0x58 /1/ x68 /2/ x78 /3/ x84 /4/ x8C /5/ x94 /6/ 1 3 0x5AC0 /1/1/ x6AC0 /2/1/ 2 In the third column, you can see data that looks similar to the materialized path pattern, but there s a significant difference. Instead of storing a delimited path of ancestor primary keys, HierarchyID is intended to store the relative node position, as shown in Figure FIGURE 17-6 The AdventureWorks Information Services Department with HierarchyID nodes displayed 1 Ken Sánchez / 263 Jean Trenary /5/ Adventure Works 2008 Information Service Department 264 Stephanie Conroy /5/1/ 265 Ashvini Sharma /5/1/1/ 266 Peter Connelly /5/1/2/ 267 Karen Berg /5/2/ 268 Ramesh Meyyappan /5/3/ 269 Dan Bacon /5/4/ 272 Janaina Bueno /5/7/ 270 François Ajenstat /5/5/ 271 Dan Wilson /5/6/ Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 429
33 Part III Beyond Relational Walking through a few examples in this hierarchy, note the following: TheCEOistherootnode,sohisHierarchyID is just /. If all the nodes under Ken were displayed, then Jean would be the fifth node. Her relative node position is the fifth node under Ken, so her HierarchyID is /5/. Stephanie is the first node under Jean, so her HierarchyID is /5/1/. Ashivini is the first node under Stephanie, so his node is /5/1/1/. Selecting a single node Even though HierarchyID stores the data in binary, it s possible to filter by a HierarchyID data type column in a WHERE clause using the text form of the data: SELECT E.BusinessEntityID, P.FirstName + + P.LastName as Name, E.JobTitle FROM HumanResources.Employee E JOIN Person.Person P ON E.BusinessEntityID = P.BusinessEntityID WHERE OrganizationNode = /5/5/ Result: BusinessEntityID Name JobTitle François Ajenstat Database Administrator Scanning for ancestors Searching for all ancestor nodes is relatively easy with HierarchyID. There s a great CLR method, IsDescendantOf(), that tests any node to determine whether it s a descendant of another node and returns either true or false. The following WHERE clause tests each row to determine whether is a descendent of that row s OrganizationNode: = 1 The full query returns the ancestor list for François. The script must first store François HierarchyID value in a local variable. Because the variable is a HierarchyID, theisdescendantof() method may be applied. The fourth column displays the same test used in the WHERE clause: HierarchyID = OrganizationNode FROM HumanResources.Employee WHERE OrganizationNode = /5/5/ -- François Ajenstat the DBA SELECT E.BusinessEntityID, P.FirstName + + P.LastName as Name, as Test FROM HumanResources.Employee E JOIN Person.Person P ON E.BusinessEntityID = P.BusinessEntityID = 1 430
34 Traversing Hierarchies 17 Result: BusinessEntityID Name JobTitle Test Ken Sánchez Chief Executive Officer Jean Trenary Information Services Manager François Ajenstat Database Administrator 1 Performing a subtree search The IsDescendantOf() method is easily flipped around to perform a subtree search locating all descendants. The trick is that either side of the IsDescendantOf() method can use a variable or column. In this case the variable goes in the parameter and the method is applied to the column. The result is the now familiar AdventureWorks Information Service Department: Result: HierarchyID = OrganizationNode FROM HumanResources.Employee WHERE OrganizationNode = /5/ -- Jean Trenary - IT Manager SELECT E.BusinessEntityID, P.FirstName + + P.LastName as Name, OrganizationNode.ToString() as HierarchyID.ToString(), OrganizationLevel FROM HumanResources.Employee E JOIN Person.Person P ON E.BusinessEntityID = P.BusinessEntityID WHERE OrganizationNode.IsDescendantOf(@ManagerNode) = 1 BusinessEntityID Name HierarchyID.ToString() OrganizationLevel Jean Trenary /5/ Stephanie Conroy /5/1/ Ashvini Sharma /5/1/1/ Peter Connelly /5/1/2/ Karen Berg /5/2/ Ramesh Meyyappan /5/3/ Dan Bacon /5/4/ François Ajenstat /5/5/ Dan Wilson /5/6/ Janaina Bueno /5/7/ 2 Single-level searches Single-level searches were presented first for the adjcency list pattern because they were the simpler searches. For HierarchyID searches, a single-level search is more complex and builds on the previous searches. In fact, a single-level HierarchyID search is really nothing more than an IsDescendantOf() search with the organizational level filter in the WHERE clause. Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 431
35 Part III Beyond Relational The following script adds the level to the WHERE cause of the previous script and finds only those members of the Information Servies Department who report directly to Jean: INT = = OrganizationLevel FROM HumanResources.Employee WHERE OrganizationNode = /5/ -- Jean Trenary - IT Manager SELECT E.BusinessEntityID, P.FirstName + + P.LastName as Name, OrganizationNode, OrganizationNode.ToString() as HierarchyID.ToString(), OrganizationLevel FROM HumanResources.Employee E JOIN Person.Person P ON E.BusinessEntityID = P.BusinessEntityID WHERE OrganizationNode.IsDescendantOf(@ManagerNode) = 1 AND OrganizationLevel + 1 Result: BusinessEntityID Name HierarchyID.ToString() OrganizationLevel Stephanie Conroy /5/1/ Karen Berg /5/2/ Ramesh Meyyappan /5/3/ Dan Bacon /5/4/ François Ajenstat /5/5/ Dan Wilson /5/6/ Janaina Bueno /5/7/ 2 Inserting new nodes Inserting the root node into a HierarchyID hierarchy must start with the binary root node. The getroot() method returns a root node value. Inserting additional nodes into HierarchyID s relative node position hierarchy first requires determining which nodes are already there. The GetDescendant() method can be used to generate the next node position. You can download additional hierarchical sample code from Performance The HierarchyID data type is a compact data type optimized for storing relative node postion. As such, it takes less space than a character-based materialized path. The HierarchyID node column should be indexed, which will aid subtree-type searches. There are specific Query Optimizer optimizations for indexing and HierarchyID, but I have found that materialized path is still slightly faster than HierarchyID. 432
36 Traversing Hierarchies 17 If the searches are primarily along a specific level, then another index keyed by level column and the HierarchyID node column will be of use. However, I ve found that this type of search is rarely used in the production hierarchies I ve worked with. HierarchyID pros and cons The new HierarchyID is not without controversy. It s new and gets plenty of press and demo time, but I m not sure it s a problem that needed another solution. On the pro side, HierarchyID has the following advantage: It s faster than the adjacency list pattern. On the con side: HierarchyID embeds data within a binary data type so it s more difficult to navigate and diagnose. Storing only the relative node position is risky. If a node is moved or deleted without very careful coding, it can be nearly impossible to correct the orphaned nodes. Adjacency list and materialized path both store the actual primary keys values, so they are both more robust than HierarchyID. Although Microsoft intends the HierarchyID to use a relative node postion, the contents of the data type accept any numeric values up to 45 bytes per node position (space between the /n/.) There s no reason why you can t insert a primary key instead of the relative node postion. It won t be as compact, but it will be more robust. Summary Hierarchical data can present a challenge if you re not armed with patterns and solutions, but knowing the possible patterns and having several navigational methods in your toolset will increase the odds that your next hierarchical data project will be successful. Adjacency pairs is the most common hierarchy solution, as it s easy to work with and well understood. Unless your requirement is very high performance when searching for all ancestors, stick with the known solution. If the hierarchy is the crux of the database and most functions use the hierarchy in some way, then go with the materialized-path solution. My Nordic software navigates the class hierarchy in nearly every query, so I tested the three patterns with a million-node hierarchy. For searching a subtree of descendents, materialized path was slightly faster than HierarchyID. For finding all ancestors, materialized path was significantly faster than HierarchyID. Both easily beat the adjacency list pattern. The next chapter continues with the theme of working with non-relational data and looks at SQL Server s new spatial data types. Excerpted from Microsoft SQL Server 2008 Bible ( ). Posted with permission. 433
FHE DEFINITIVE GUIDE. ^phihri^^lv JEFFREY GARBUS. Joe Celko. Alvin Chang. PLAMEN ratchev JONES & BARTLETT LEARN IN G. y ti rvrrtuttnrr i t i r
: 1. FHE DEFINITIVE GUIDE fir y ti rvrrtuttnrr i t i r ^phihri^^lv ;\}'\^X$:^u^'! :: ^ : ',!.4 '. JEFFREY GARBUS PLAMEN ratchev Alvin Chang Joe Celko g JONES & BARTLETT LEARN IN G Contents About the Authors
Database Design Patterns. Winter 2006-2007 Lecture 24
Database Design Patterns Winter 2006-2007 Lecture 24 Trees and Hierarchies Many schemas need to represent trees or hierarchies of some sort Common way of representing trees: An adjacency list model Each
Go Beyond VFP's SQL with SQL Server
Go Beyond VFP's SQL with SQL Server Tamar E. Granor Tomorrow's Solutions, LLC Voice: 215-635-1958 Email: [email protected] The subset of SQL in Visual FoxPro is useful for many tasks. But
RECURSIVE COMMON TABLE EXPRESSIONS DATABASE IN ORACLE. Iggy Fernandez, Database Specialists INTRODUCTION
RECURSIVE COMMON TABLE EXPRESSIONS IN ORACLE DATABASE 11G RELEASE 2 Iggy Fernandez, Database Specialists INTRODUCTION Oracle was late to the table with recursive common table expressions which have been
SQL Server. 2012 for developers. murach's TRAINING & REFERENCE. Bryan Syverson. Mike Murach & Associates, Inc. Joel Murach
TRAINING & REFERENCE murach's SQL Server 2012 for developers Bryan Syverson Joel Murach Mike Murach & Associates, Inc. 4340 N. Knoll Ave. Fresno, CA 93722 www.murach.com [email protected] Expanded
SQL Server Database Coding Standards and Guidelines
SQL Server Database Coding Standards and Guidelines http://www.sqlauthority.com Naming Tables: Stored Procs: Triggers: Indexes: Primary Keys: Foreign Keys: Defaults: Columns: General Rules: Rules: Pascal
Oracle Database: SQL and PL/SQL Fundamentals NEW
Oracle University Contact Us: + 38516306373 Oracle Database: SQL and PL/SQL Fundamentals NEW Duration: 5 Days What you will learn This Oracle Database: SQL and PL/SQL Fundamentals training delivers the
Course ID#: 1401-801-14-W 35 Hrs. Course Content
Course Content Course Description: This 5-day instructor led course provides students with the technical skills required to write basic Transact- SQL queries for Microsoft SQL Server 2014. This course
SQL DATA DEFINITION: KEY CONSTRAINTS. CS121: Introduction to Relational Database Systems Fall 2015 Lecture 7
SQL DATA DEFINITION: KEY CONSTRAINTS CS121: Introduction to Relational Database Systems Fall 2015 Lecture 7 Data Definition 2 Covered most of SQL data manipulation operations Continue exploration of SQL
Relational Database Basics Review
Relational Database Basics Review IT 4153 Advanced Database J.G. Zheng Spring 2012 Overview Database approach Database system Relational model Database development 2 File Processing Approaches Based on
Querying Microsoft SQL Server 20461C; 5 days
Lincoln Land Community College Capital City Training Center 130 West Mason Springfield, IL 62702 217-782-7436 www.llcc.edu/cctc Querying Microsoft SQL Server 20461C; 5 days Course Description This 5-day
Oracle Database: SQL and PL/SQL Fundamentals
Oracle University Contact Us: 1.800.529.0165 Oracle Database: SQL and PL/SQL Fundamentals Duration: 5 Days What you will learn This course is designed to deliver the fundamentals of SQL and PL/SQL along
Querying Microsoft SQL Server
Course 20461C: Querying Microsoft SQL Server Module 1: Introduction to Microsoft SQL Server 2014 This module introduces the SQL Server platform and major tools. It discusses editions, versions, tools used
Best Practices for Multi-Dimensional Design using Cognos 8 Framework Manager
Best Practices for Multi-Dimensional Design using Cognos 8 Framework Manager Bruce Zornes The Boeing Company Business Intelligence & Competency Center Best Practice: Knowledge and Experience Use Best Practice
MOC 20461C: Querying Microsoft SQL Server. Course Overview
MOC 20461C: Querying Microsoft SQL Server Course Overview This course provides students with the knowledge and skills to query Microsoft SQL Server. Students will learn about T-SQL querying, SQL Server
SQL Server Table Design - Best Practices
CwJ Consulting Ltd SQL Server Table Design - Best Practices Author: Andy Hogg Date: 20 th February 2015 Version: 1.11 SQL Server Table Design Best Practices 1 Contents 1. Introduction... 3 What is a table?...
1. INTRODUCTION TO RDBMS
Oracle For Beginners Page: 1 1. INTRODUCTION TO RDBMS What is DBMS? Data Models Relational database management system (RDBMS) Relational Algebra Structured query language (SQL) What Is DBMS? Data is one
SQL Server. 1. What is RDBMS?
SQL Server 1. What is RDBMS? Relational Data Base Management Systems (RDBMS) are database management systems that maintain data records and indices in tables. Relationships may be created and maintained
Oracle 10g PL/SQL Training
Oracle 10g PL/SQL Training Course Number: ORCL PS01 Length: 3 Day(s) Certification Exam This course will help you prepare for the following exams: 1Z0 042 1Z0 043 Course Overview PL/SQL is Oracle's Procedural
Querying Microsoft SQL Server 2012
Course 10774A: Querying Microsoft SQL Server 2012 Length: 5 Days Language(s): English Audience(s): IT Professionals Level: 200 Technology: Microsoft SQL Server 2012 Type: Course Delivery Method: Instructor-led
Course 20461C: Querying Microsoft SQL Server Duration: 35 hours
Course 20461C: Querying Microsoft SQL Server Duration: 35 hours About this Course This course is the foundation for all SQL Server-related disciplines; namely, Database Administration, Database Development
Querying Microsoft SQL Server Course M20461 5 Day(s) 30:00 Hours
Área de formação Plataforma e Tecnologias de Informação Querying Microsoft SQL Introduction This 5-day instructor led course provides students with the technical skills required to write basic Transact-SQL
Course 10774A: Querying Microsoft SQL Server 2012
Course 10774A: Querying Microsoft SQL Server 2012 About this Course This 5-day instructor led course provides students with the technical skills required to write basic Transact-SQL queries for Microsoft
Course 10774A: Querying Microsoft SQL Server 2012 Length: 5 Days Published: May 25, 2012 Language(s): English Audience(s): IT Professionals
Course 10774A: Querying Microsoft SQL Server 2012 Length: 5 Days Published: May 25, 2012 Language(s): English Audience(s): IT Professionals Overview About this Course Level: 200 Technology: Microsoft SQL
HP Quality Center. Upgrade Preparation Guide
HP Quality Center Upgrade Preparation Guide Document Release Date: November 2008 Software Release Date: November 2008 Legal Notices Warranty The only warranties for HP products and services are set forth
There are four technologies or components in the database system that affect database performance:
Paul Nielsen Presented at PASS Global Summit 2006 Seattle, Washington The database industry is intensely driven toward performance with numerous performance techniques and strategies. Prioritizing these
Introducing Microsoft SQL Server 2012 Getting Started with SQL Server Management Studio
Querying Microsoft SQL Server 2012 Microsoft Course 10774 This 5-day instructor led course provides students with the technical skills required to write basic Transact-SQL queries for Microsoft SQL Server
Improving SQL Server Performance
Informatica Economică vol. 14, no. 2/2010 55 Improving SQL Server Performance Nicolae MERCIOIU 1, Victor VLADUCU 2 1 Prosecutor's Office attached to the High Court of Cassation and Justice 2 Prosecutor's
MOC 20461 QUERYING MICROSOFT SQL SERVER
ONE STEP AHEAD. MOC 20461 QUERYING MICROSOFT SQL SERVER Length: 5 days Level: 300 Technology: Microsoft SQL Server Delivery Method: Instructor-led (classroom) COURSE OUTLINE Module 1: Introduction to Microsoft
Using SQL Server Management Studio
Using SQL Server Management Studio Microsoft SQL Server Management Studio 2005 is a graphical tool for database designer or programmer. With SQL Server Management Studio 2005 you can: Create databases
Retrieving Data Using the SQL SELECT Statement. Copyright 2006, Oracle. All rights reserved.
Retrieving Data Using the SQL SELECT Statement Objectives After completing this lesson, you should be able to do the following: List the capabilities of SQL SELECT statements Execute a basic SELECT statement
Data Tool Platform SQL Development Tools
Data Tool Platform SQL Development Tools ekapner Contents Setting SQL Development Preferences...5 Execution Plan View Options Preferences...5 General Preferences...5 Label Decorations Preferences...6
SQL Server An Overview
SQL Server An Overview SQL Server Microsoft SQL Server is designed to work effectively in a number of environments: As a two-tier or multi-tier client/server database system As a desktop database system
Contents WEKA Microsoft SQL Database
WEKA User Manual Contents WEKA Introduction 3 Background information. 3 Installation. 3 Where to get WEKA... 3 Downloading Information... 3 Opening the program.. 4 Chooser Menu. 4-6 Preprocessing... 6-7
Introduction to Querying & Reporting with SQL Server
1800 ULEARN (853 276) www.ddls.com.au Introduction to Querying & Reporting with SQL Server Length 5 days Price $4169.00 (inc GST) Overview This five-day instructor led course provides students with the
Oracle Database: SQL and PL/SQL Fundamentals
Oracle University Contact Us: +966 12 739 894 Oracle Database: SQL and PL/SQL Fundamentals Duration: 5 Days What you will learn This Oracle Database: SQL and PL/SQL Fundamentals training is designed to
Toad for Data Analysts, Tips n Tricks
Toad for Data Analysts, Tips n Tricks or Things Everyone Should Know about TDA Just what is Toad for Data Analysts? Toad is a brand at Quest. We have several tools that have been built explicitly for developers
Physical Database Design Process. Physical Database Design Process. Major Inputs to Physical Database. Components of Physical Database Design
Physical Database Design Process Physical Database Design Process The last stage of the database design process. A process of mapping the logical database structure developed in previous stages into internal
Efficient Interval Management in Microsoft SQL Server
Efficient Interval Management in Microsoft SQL Server Itzik Ben-Gan, SolidQ Last modified: August, 0 Agenda Inefficiencies of classic interval handling Solution: RI-tree by Kriegel, Pötke and Seidl of
Duration Vendor Audience 5 Days Oracle End Users, Developers, Technical Consultants and Support Staff
D80198GC10 Oracle Database 12c SQL and Fundamentals Summary Duration Vendor Audience 5 Days Oracle End Users, Developers, Technical Consultants and Support Staff Level Professional Delivery Method Instructor-led
AV-005: Administering and Implementing a Data Warehouse with SQL Server 2014
AV-005: Administering and Implementing a Data Warehouse with SQL Server 2014 Career Details Duration 105 hours Prerequisites This career requires that you meet the following prerequisites: Working knowledge
Developing Microsoft SQL Server Databases MOC 20464
Developing Microsoft SQL Server Databases MOC 20464 Course Outline Module 1: Introduction to Database Development This module introduces database development and the key tasks that a database developer
Using the Query Analyzer
Using the Query Analyzer Using the Query Analyzer Objectives Explore the Query Analyzer user interface. Learn how to use the menu items and toolbars to work with SQL Server data and objects. Use object
Geodatabase Programming with SQL
DevSummit DC February 11, 2015 Washington, DC Geodatabase Programming with SQL Craig Gillgrass Assumptions Basic knowledge of SQL and relational databases Basic knowledge of the Geodatabase We ll hold
2874CD1EssentialSQL.qxd 6/25/01 3:06 PM Page 1 Essential SQL Copyright 2001 SYBEX, Inc., Alameda, CA www.sybex.com
Essential SQL 2 Essential SQL This bonus chapter is provided with Mastering Delphi 6. It is a basic introduction to SQL to accompany Chapter 14, Client/Server Programming. RDBMS packages are generally
Database design 1 The Database Design Process: Before you build the tables and other objects that will make up your system, it is important to take time to design it. A good design is the keystone to creating
Introducing DocumentDB
David Chappell Introducing DocumentDB A NoSQL Database for Microsoft Azure Sponsored by Microsoft Corporation Copyright 2014 Chappell & Associates Contents Why DocumentDB?... 3 The DocumentDB Data Model...
IT2305 Database Systems I (Compulsory)
Database Systems I (Compulsory) INTRODUCTION This is one of the 4 modules designed for Semester 2 of Bachelor of Information Technology Degree program. CREDITS: 04 LEARNING OUTCOMES On completion of this
Tutorials for Project on Building a Business Analytic Model Using Data Mining Tool and Data Warehouse and OLAP Cubes IST 734
Cleveland State University Tutorials for Project on Building a Business Analytic Model Using Data Mining Tool and Data Warehouse and OLAP Cubes IST 734 SS Chung 14 Build a Data Mining Model using Data
Advanced Query for Query Developers
for Developers This is a training guide to step you through the advanced functions of in NUFinancials. is an ad-hoc reporting tool that allows you to retrieve data that is stored in the NUFinancials application.
Oracle Database 10g Express
Oracle Database 10g Express This tutorial prepares the Oracle Database 10g Express Edition Developer to perform common development and administrative tasks of Oracle Database 10g Express Edition. Objectives
Partitioning under the hood in MySQL 5.5
Partitioning under the hood in MySQL 5.5 Mattias Jonsson, Partitioning developer Mikael Ronström, Partitioning author Who are we? Mikael is a founder of the technology behind NDB
Data Compression in Blackbaud CRM Databases
Data Compression in Blackbaud CRM Databases Len Wyatt Enterprise Performance Team Executive Summary... 1 Compression in SQL Server... 2 Perform Compression in Blackbaud CRM Databases... 3 Initial Compression...
CIS 631 Database Management Systems Sample Final Exam
CIS 631 Database Management Systems Sample Final Exam 1. (25 points) Match the items from the left column with those in the right and place the letters in the empty slots. k 1. Single-level index files
Optimizing the Performance of the Oracle BI Applications using Oracle Datawarehousing Features and Oracle DAC 10.1.3.4.1
Optimizing the Performance of the Oracle BI Applications using Oracle Datawarehousing Features and Oracle DAC 10.1.3.4.1 Mark Rittman, Director, Rittman Mead Consulting for Collaborate 09, Florida, USA,
Oracle Database 10g: Introduction to SQL
Oracle University Contact Us: 1.800.529.0165 Oracle Database 10g: Introduction to SQL Duration: 5 Days What you will learn This course offers students an introduction to Oracle Database 10g database technology.
Once the schema has been designed, it can be implemented in the RDBMS.
2. Creating a database Designing the database schema... 1 Representing Classes, Attributes and Objects... 2 Data types... 5 Additional constraints... 6 Choosing the right fields... 7 Implementing a table
PeopleSoft Query Training
PeopleSoft Query Training Overview Guide Tanya Harris & Alfred Karam Publish Date - 3/16/2011 Chapter: Introduction Table of Contents Introduction... 4 Navigation of Queries... 4 Query Manager... 6 Query
Instant SQL Programming
Instant SQL Programming Joe Celko Wrox Press Ltd. INSTANT Table of Contents Introduction 1 What Can SQL Do for Me? 2 Who Should Use This Book? 2 How To Use This Book 3 What You Should Know 3 Conventions
Creating Database Tables in Microsoft SQL Server
Creating Database Tables in Microsoft SQL Server Microsoft SQL Server is a relational database server that stores and retrieves data for multi-user network-based applications. SQL Server databases are
Physical Design. Meeting the needs of the users is the gold standard against which we measure our success in creating a database.
Physical Design Physical Database Design (Defined): Process of producing a description of the implementation of the database on secondary storage; it describes the base relations, file organizations, and
Relational Databases and SQLite
Relational Databases and SQLite Charles Severance Python for Informatics: Exploring Information www.pythonlearn.com SQLite Browser http://sqlitebrowser.org/ Relational Databases Relational databases model
SQL Server 2008 Core Skills. Gary Young 2011
SQL Server 2008 Core Skills Gary Young 2011 Confucius I hear and I forget I see and I remember I do and I understand Core Skills Syllabus Theory of relational databases SQL Server tools Getting help Data
Jeremy Kashel Tim Kent Martyn Bullerwell. Chapter No.2 "Master Data Services Overview"
Jeremy Kashel Tim Kent Martyn Bullerwell Chapter No.2 "Master Data Services Overview" Master Data Services Overview In this chapter, we will provide an overview of SQL Server 2008 R2 Master Data Services
How To Improve Performance In A Database
1 PHIL FACTOR GRANT FRITCHEY K. BRIAN KELLEY MICKEY STUEWE IKE ELLIS JONATHAN ALLEN LOUIS DAVIDSON 2 Database Performance Tips for Developers As a developer, you may or may not need to go into the database
Programming Database lectures for mathema
Programming Database lectures for mathematics students April 25, 2015 Functions Functions are defined in Postgres with CREATE FUNCTION name(parameter type,...) RETURNS result-type AS $$ function-body $$
Fundamentals of Database Design
Fundamentals of Database Design Zornitsa Zaharieva CERN Data Management Section - Controls Group Accelerators and Beams Department /AB-CO-DM/ 23-FEB-2005 Contents : Introduction to Databases : Main Database
A Brief Introduction to MySQL
A Brief Introduction to MySQL by Derek Schuurman Introduction to Databases A database is a structured collection of logically related data. One common type of database is the relational database, a term
Essentials of SQL. Essential SQL 11/06/2010. NWeHealth, The University of Manchester
NWeHealth, The University of Manchester Essentials of SQL Exercise Booklet WITH ANSWERS Queries modified from various internet resources including SQLZoo.net Dr. Georgina Moulton Education and Development
Oracle Database 12c: Introduction to SQL Ed 1.1
Oracle University Contact Us: 1.800.529.0165 Oracle Database 12c: Introduction to SQL Ed 1.1 Duration: 5 Days What you will learn This Oracle Database: Introduction to SQL training helps you write subqueries,
The Relational Model. Ramakrishnan&Gehrke, Chapter 3 CS4320 1
The Relational Model Ramakrishnan&Gehrke, Chapter 3 CS4320 1 Why Study the Relational Model? Most widely used model. Vendors: IBM, Informix, Microsoft, Oracle, Sybase, etc. Legacy systems in older models
Course 20464C: Developing Microsoft SQL Server Databases
Course 20464C: Developing Microsoft SQL Server Databases Module 1: Introduction to Database DevelopmentThis module introduces database development and the key tasks that a database developer would typically
Commercial Database Software Development- A review.
Commercial Database Software Development- A review. A database software has wide applications. A database software is used in almost all the organizations. Over 15 years many tools have been developed
Introduction to SQL for Data Scientists
Introduction to SQL for Data Scientists Ben O. Smith College of Business Administration University of Nebraska at Omaha Learning Objectives By the end of this document you will learn: 1. How to perform
1Z0-117 Oracle Database 11g Release 2: SQL Tuning. Oracle
1Z0-117 Oracle Database 11g Release 2: SQL Tuning Oracle To purchase Full version of Practice exam click below; http://www.certshome.com/1z0-117-practice-test.html FOR Oracle 1Z0-117 Exam Candidates We
4 Simple Database Features
4 Simple Database Features Now we come to the largest use of iseries Navigator for programmers the Databases function. IBM is no longer developing DDS (Data Description Specifications) for database definition,
Access Queries (Office 2003)
Access Queries (Office 2003) Technical Support Services Office of Information Technology, West Virginia University OIT Help Desk 293-4444 x 1 oit.wvu.edu/support/training/classmat/db/ Instructor: Kathy
Developing Web Applications for Microsoft SQL Server Databases - What you need to know
Developing Web Applications for Microsoft SQL Server Databases - What you need to know ATEC2008 Conference Session Description Alpha Five s web components simplify working with SQL databases, but what
In This Lecture. SQL Data Definition SQL SQL. Notes. Non-Procedural Programming. Database Systems Lecture 5 Natasha Alechina
This Lecture Database Systems Lecture 5 Natasha Alechina The language, the relational model, and E/R diagrams CREATE TABLE Columns Primary Keys Foreign Keys For more information Connolly and Begg chapter
Master Data Services. SQL Server 2012 Books Online
Master Data Services SQL Server 2012 Books Online Summary: Master Data Services (MDS) is the SQL Server solution for master data management. Master data management (MDM) describes the efforts made by an
20464C: Developing Microsoft SQL Server Databases
20464C: Developing Microsoft SQL Server Databases Course Details Course Code: Duration: Notes: 20464C 5 days This course syllabus should be used to determine whether the course is appropriate for the students,
Intellect Platform - Parent-Child relationship Basic Expense Management System - A103
Intellect Platform - Parent-Child relationship Basic Expense Management System - A103 Interneer, Inc. Updated 2/29/2012 Created by Erika Keresztyen Fahey 2 Parent-Child relationship - A103 - Basic Expense
SQL Server Query Tuning
SQL Server Query Tuning A 12-Step Program By Thomas LaRock, Technical Evangelist and Head Geek Confio Software 4772 Walnut Street, Suite 100 Boulder, CO 80301 www.confio.com Introduction Query tuning is
A Migration Methodology of Transferring Database Structures and Data
A Migration Methodology of Transferring Database Structures and Data Database migration is needed occasionally when copying contents of a database or subset to another DBMS instance, perhaps due to changing
Oracle SQL. Course Summary. Duration. Objectives
Oracle SQL Course Summary Identify the major structural components of the Oracle Database 11g Create reports of aggregated data Write SELECT statements that include queries Retrieve row and column data
Developing Microsoft SQL Server Databases 20464C; 5 Days
Developing Microsoft SQL Server Databases 20464C; 5 Days Lincoln Land Community College Capital City Training Center 130 West Mason Springfield, IL 62702 217-782-7436 www.llcc.edu/cctc Course Description
Microsoft Access Basics
Microsoft Access Basics 2006 ipic Development Group, LLC Authored by James D Ballotti Microsoft, Access, Excel, Word, and Office are registered trademarks of the Microsoft Corporation Version 1 - Revision
Database Design and Normalization
Database Design and Normalization 3 CHAPTER IN THIS CHAPTER The Relational Design Theory 48 46 Database Design Unleashed PART I Access applications are database applications, an obvious statement that
SQL Query Performance Tuning: Tips and Best Practices
SQL Query Performance Tuning: Tips and Best Practices Pravasini Priyanka, Principal Test Engineer, Progress Software INTRODUCTION: In present day world, where dozens of complex queries are run on databases
Querying Microsoft SQL Server (20461) H8N61S
HP Education Services course data sheet Querying Microsoft SQL Server (20461) H8N61S Course Overview In this course, you will learn the technical skills required to write basic Transact-SQL (T-SQL) queries
ICAB4136B Use structured query language to create database structures and manipulate data
ICAB4136B Use structured query language to create database structures and manipulate data Release: 1 ICAB4136B Use structured query language to create database structures and manipulate data Modification
The Relational Model. Why Study the Relational Model? Relational Database: Definitions. Chapter 3
The Relational Model Chapter 3 Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 1 Why Study the Relational Model? Most widely used model. Vendors: IBM, Informix, Microsoft, Oracle, Sybase,
Saskatoon Business College Corporate Training Centre 244-6340 [email protected] www.sbccollege.ca/corporate
Microsoft Certified Instructor led: Querying Microsoft SQL Server (Course 20461C) Date: October 19 23, 2015 Course Length: 5 day (8:30am 4:30pm) Course Cost: $2400 + GST (Books included) About this Course
Database Administration with MySQL
Database Administration with MySQL Suitable For: Database administrators and system administrators who need to manage MySQL based services. Prerequisites: Practical knowledge of SQL Some knowledge of relational
Chapter 6: Physical Database Design and Performance. Database Development Process. Physical Design Process. Physical Database Design
Chapter 6: Physical Database Design and Performance Modern Database Management 6 th Edition Jeffrey A. Hoffer, Mary B. Prescott, Fred R. McFadden Robert C. Nickerson ISYS 464 Spring 2003 Topic 23 Database
MS-50401 - Designing and Optimizing Database Solutions with Microsoft SQL Server 2008
MS-50401 - Designing and Optimizing Database Solutions with Microsoft SQL Server 2008 Table of Contents Introduction Audience At Completion Prerequisites Microsoft Certified Professional Exams Student
Design and Implementation
Pro SQL Server 2012 Relational Database Design and Implementation Louis Davidson with Jessica M. Moss Apress- Contents Foreword About the Author About the Technical Reviewer Acknowledgments Introduction
