1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft SQL Server 2008 R2 Unleashed- P165 potx

10 260 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 189,17 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

For example, to add a child part to the Bodynode node /2/, you can use the GetDescendantmethod without any arguments to add the new row below Bodynode at node/2/1/: INSERT Parts_hierarch

Trang 1

with a slash sign used as a separator between the levels For example, you can run the

following query to get both the binary and logical representations of the hidvalue:

select cast(hid as varbinary(6)) as hid,

substring(hid.ToString(), 1, 12) as path,

lvl,

partid,

partname

From parts_hierarchy

go

hid path lvl partid partname

- - - -

-0x / 0 22 Car

0x58 /1/ 1 1 DriveTrain

0x68 /2/ 1 23 Body

0x78 /3/ 1 24 Frame

0x5AC0 /1/1/ 2 2 Engine

0x5B40 /1/2/ 2 3 Transmission

0x5BC0 /1/3/ 2 4 Axle

0x5C20 /1/4/ 2 12 Drive Shaft

0x5B56 /1/2/1/ 3 9 Flywheel

0x5B5A /1/2/2/ 3 10 Clutch

0x5B5E /1/2/3/ 3 16 Gear Box

0x5AD6 /1/1/1/ 3 5 Radiator

0x5ADA /1/1/2/ 3 6 Intake Manifold

0x5ADE /1/1/3/ 3 7 Exhaust Manifold

0x5AE1 /1/1/4/ 3 8 Carburetor

0x5AE3 /1/1/5/ 3 13 Piston

0x5AE5 /1/1/6/ 3 14 Crankshaft

0x5AE358 /1/1/5/1/ 4 21 Piston Rings

0x5AE158 /1/1/4/1/ 4 11 Float Valve

0x5B5EB0 /1/2/3/1/ 4 15 Reverse Gear

0x5B5ED0 /1/2/3/2/ 4 17 First Gear

0x5B5EF0 /1/2/3/3/ 4 18 Second Gear

0x5B5F08 /1/2/3/4/ 4 19 Third Gear

0x5B5F18 /1/2/3/5/ 4 20 Fourth Gear

As stated previously, the values stored in aHierarchyidcolumn provide topological sorting

of the nodes in the hierarchy TheGetLevelmethod can be used to produce the level in the

hierarchy (as it was to store the level in the computedlvlcolumn in theParts_hierarchy

table) Using thelvlcolumn or theGetLevelmethod, you can easily produce a graphical

depiction of the hierarchy by simply sorting the rows byhidand generating indentation

for each row based on thelvlcolumn, as shown in the following example:

Trang 2

SELECT

REPLICATE(‘ ’, lvl)

+ right(‘>’,lvl)

+ partname AS partname

FROM Parts_hierarchy

order by hid

go

partname

-Car

>DriveTrain

>Engine

->Radiator

->Intake Manifold

->Exhaust Manifold

->Carburetor

->Float Valve

->Piston

->Piston Rings

->Crankshaft

>Transmission

->Flywheel

->Clutch

->Gear Box

->Reverse Gear

->First Gear

->Second Gear

->Third Gear

->Fourth Gear

>Axle

>Drive Shaft

>Body

>Frame

To return only the subparts of a specific part, you can use the IsDescendantOfmethod

The parameter passed to this method is a node’s Hierarchyidvalue The method returns 1

if the queried node is a descendant of the input node For example, the following query

returns all subparts of the engine:

select child.partid, child.partname, child.lvl

from

parts_hierarchy as parent

inner join

parts_hierarchy as child

on parent.partname = ‘Engine’

and child.hid.IsDescendantOf(parent.hid) = 1

Trang 3

go

partid partname lvl

-

-2 Engine -2

5 Radiator 3

6 Intake Manifold 3

7 Exhaust Manifold 3

8 Carburetor 3

13 Piston 3

14 Crankshaft 3

21 Piston Rings 4

11 Float Valve 4

You can also use the IsDescendantOfmethod to return all parent parts of a given part: select parent.partid, parent.partname, parent.lvl from parts_hierarchy as parent inner join parts_hierarchy as child on child.partname = ‘Piston’ and child.hid.IsDescendantOf(parent.hid) = 1 go partid partname lvl -

-22 Car 0

1 DriveTrain 1

2 Engine 2

13 Piston 3

To return a specific level of subparts for a given part, you can use the GetAncestor

method You pass this method an integer value indicating the level below the parent you

want to display The function returns the Hierarchyidvalue of the ancestor n levels above

the queried node For example, the following query returns all the subparts two levels

down from the drivetrain:

select child.partid, child.partname

from

parts_hierarchy as parent

inner join

parts_hierarchy as child

on parent.partname = ‘Drivetrain’

and child.hid.GetAncestor(2) = parent.hid

go

Trang 4

partid partname lvl

-

-9 Flywheel 3

10 Clutch 3

16 Gear Box 3

5 Radiator 3

6 Intake Manifold 3

7 Exhaust Manifold 3

8 Carburetor 3

13 Piston 3

14 Crankshaft 3

Modifying the Hierarchy

The script in Listing 42.15 performs the initial population of the Parts_hierarchytable

What if you need to add additional records into the table? Let’s look at how to use the

GetDescendantmethod to add new records at different levels of the hierarchy

For example, to add a child part to the Bodynode (node /2/), you can use the

GetDescendantmethod without any arguments to add the new row below Bodynode at

node/2/1/:

INSERT Parts_hierarchy (hid, partid, partname)

select hid.GetDescendant(null, null), 25, ‘left front fender’

from Parts_hierarchy

where partname = ‘Body’

To add a new row as a higher descendant node at the same level as the left front fender

inserted in the previous example, you use the GetDescendantmethod again, but this time

passing the Hierarchyidof the existing child node as the first parameter This specifies

that the new node will follow the existing node, becoming /2/2/ There are a couple of

ways to specify the Hierarchyidof the existing child node You can retrieve it from the

table as a Hierarchyiddata type, or if you know the string representation of the node,

you can use the Parsemethod The Parsemethod converts a canonical string

representa-tion of a hierarchical value to Hierarchyid.Parseis also called implicitly when a

conver-sion from a string type to Hierarchyidoccurs, as in CAST(input AS hierarchyid).Parseis

essentially the opposite of the ToStringmethod

INSERT Parts_hierarchy (hid, partid, partname)

select hid.GetDescendant(hierarchyid::Parse(‘/2/1/’), null), 26, ‘right

front fender’

from Parts_hierarchy

where partname = ‘Body’

Trang 5

Now, what if you need to add a new node between the two existing nodes you just added?

Again, you use the GetDescendantmethods, but this time, you pass it the hierarchy IDs of

both existing nodes between which you want to insert the new node:

declare @child1 hierarchyid,

@child2 hierarchyid

select @child1 = hid from Parts_hierarchy where partname = ‘left front fender’

select @child2 = hid from Parts_hierarchy where partname = ‘right front fender’

INSERT Parts_hierarchy (hid, partid, partname)

select hid.GetDescendant(@child1, @child2), 27, ‘front bumper’

from Parts_hierarchy

where partname = ‘Body’

Now, let’s run a query of the Bodysubtree to examine the newly inserted child nodes:

select child.partid, child.partname, child.lvl,

substring(child.hid.ToString(), 1, 12) as path

from

parts_hierarchy as parent

inner join

parts_hierarchy as child

on parent.partname = ‘Body’

and child.hid.IsDescendantOf(parent.hid) = 1

order by child.hid

go

partid partname lvl path

- - -

-23 Body 1 /2/

25 left front fender 2 /2/1/

27 front bumper 2 /2/1.1/

26 right front fender 2 /2/2/

Notice that the first child added (left front fender) has a node path of /2/1/, and the

second row added (right front fender) has a node path of /2/2/ The new child node

inserted between these two nodes (front bumper) was given a node path of /2/1.1/so

that it maintains the designated topological ordering of the nodes

What if you need to make other types of changes within hierarchies? For example, you

might need to move a whole subtree of parts from one part to another (that is, move a

part and all its subordinates) To move nodes or subtrees in a hierarchy, you can use the

GetReparentedValuemethod of the Hierarchyiddata type You invoke this method on

theHierarchyidvalue of the node you want to reparent and provide as inputs the value

of the old parent and the value of the new parent

Note that this method doesn’t change the Hierarchyidvalue for the existing node that

you want to move Instead, it returns a new Hierarchyidvalue that you can use to update

Trang 6

the target node’s Hierarchyidvalue Logically, the GetReparentedValuemethod simply

substitutes the part of the existing node’s path that represents the old parent’s path with

the new parent’s path For example, if the path of the existing node is /1/2/1/, the path

of the old parent is /1/2/, and the path of the new parent is /2/1/3/, the

GetReparentedValuemethod would return /2/1/3/1/

You have to be careful, though If the target parent node already has child nodes, the

GetReparentedValuemethod may not produce a unique hierarchy path If you reparent

node/1/2/1/from old parent /1/2/to new parent /2/1/3/, and /2/1/3/already has a

child/2/1/3/1/, you generate a duplicate value To avoid this situation when moving a

single node from one parent to another, you should not use the GetReparentedValue

method but instead use the GetDescendantmethod to produce a completely new value for

the single node For example, let’s assume you want to move the Flywheelpart from the

Transmissionnode to the Enginenode A sample approach is shown in Listing 42.16 This

example uses the GetDescendantmethod to generate a new Hierarchyidunder the Engine

node following the last child node and updates the hidcolumn for the Flywheelrecord to

the new Hierarchyidgenerated

declare @newhid hierarchyid,

@maxchild hierarchyid

first, find the max child node under the Engine node

this is the node we will move the Flywheel node after

select @maxchild = max(child.hid)

from

parts_hierarchy as parent

inner join

parts_hierarchy as child

on parent.partname = ‘Engine’

and child.hid.GetAncestor(1) = parent.hid

select ‘Child to insert after’ = @maxchild.ToString()

Now, generate a new descendant hid for the Engine node

after the max child node

select @newhid = hid.GetDescendant(@maxchild, null)

from Parts_hierarchy

where partname = ‘Engine’

Update the hid for the Flywheel node to the new hid

update Parts_hierarchy

set hid = @newhid

where partname = ‘Flywheel’

go

Child to insert after

-/1/1/6/

Trang 7

If you need to move an entire subtree within a hierarchy, you can use the

GetReparentedValuemethod in conjunction with theGetDescendantmethod For

example, suppose you want to move the wholeEnginesubtree from its current parent node

ofDrivetrainto the new parent node ofCar TheCarnode obviously already has children

If you want to avoid conflicts, the best approach is to generate a newHierarchyidvalue for

the root node of the subtree You can achieve this with the following steps:

1 Use the GetDescendantmethod to produce a completely new Hierarchyidvalue for

the root node of the subtree

2 Update the Hierarchyidvalue of all nodes in the subtree to the value returned by

theGetReparentedValuemethod

Because you are generating a completely new Hierarchyidvalue under the target parent,

this new child node has no existing children, which avoids any duplicate Hierarchyid

values Listing 42.17 provides an example for changing the parent node of the Engine

subtree from DrivetraintoCar

DECLARE

@old_root AS HIERARCHYID,

@new_root AS HIERARCHYID,

@new_parent_hid AS HIERARCHYID,

@max_child as hierarchyid

Get the hid of the new parent

select @new_parent_hid = hid

FROM dbo.parts_hierarchy

WHERE partname = ‘Car’

Get the hid of the current root of the subnode

Select @old_root = hid

FROM dbo.parts_hierarchy

WHERE partname = ‘Engine’

Get the max hid of child nodes of the new parent

select @max_child = MAX(hid)

FROM parts_hierarchy

WHERE hid.GetAncestor(1) = @new_parent_hid

get a new hid for the moving child node

that is after the current max child node of the new parent

SET @new_root = @new_parent_hid.GetDescendant (@max_child, null)

Next, reparent the moving child node and all descendants

UPDATE dbo.parts_hierarchy

Trang 8

SET hid = hid.GetReparentedValue(@old_root, @new_root)

WHERE hid.IsDescendantOf(@old_root) = 1

Now, let’s reexamine the hierarchy after the updates made in Listings 42.16 and 42.17:

SELECT

left(REPLICATE(‘ ’, lvl)

+ right(‘>’,lvl)

+ partname, 30) AS partname,

hid.ToString() AS path

FROM Parts_hierarchy

order by hid

go

partname path

-

-Car /

>DriveTrain /1/

>Transmission /1/2/

->Clutch /1/2/2/

->Gear Box /1/2/3/

->Reverse Gear /1/2/3/1/

->First Gear /1/2/3/2/

->Second Gear /1/2/3/3/

->Third Gear /1/2/3/4/

->Fourth Gear /1/2/3/5/

>Axle /1/3/

>Drive Shaft /1/4/

>Body /2/

>left front fender /2/1/

>front bumper /2/1.1/

>right front fender /2/2/

>Frame /3/

>Engine /4/

>Radiator /4/1/

>Intake Manifold /4/2/

>Exhaust Manifold /4/3/

>Carburetor /4/4/

->Float Valve /4/4/1/

>Piston /4/5/

->Piston Rings /4/5/1/

>Crankshaft /4/6/

>Flywheel /4/7/

Trang 9

As you can see from the results, the Flywheelnode is now under the Enginenode, and the

entireEnginesubtree is now under the Carnode

Using FILESTREAM Storage

In versions of SQL Server prior to SQL Server 2008, there were two ways of storing

unstructured data: as a binary large object (BLOB) in an image or varbinary(max)column,

or in files outside the database, separate from the structured relational data, storing a

refer-ence or pathname to the file in a varcharcolumn Neither of these methods is ideal for

handling unstructured data Storing the data outside the database makes managing the

unstructured data and keeping it associated with structured data more complex This

approach lacks transactional consistency, coordinating backups and restores with the

structured data in the database is difficult, and implementing proper data security can be

quite cumbersome

Storing the unstructured data in the database solves the transactional consistency,

backup/restore, and security issues, but BLOBs have different usage patterns than

tional data SQL Server’s storage engine is primarily concerned with doing I/O on

rela-tional data stored in pages and extents, not streaming large BLOBs I/O performance

typically degrades dramatically if the size of the BLOB data increases beyond 1MB

Accessing BLOB data stored inside a SQL Server database is generally slower than storing it

externally in a location such as the NTFS file system In addition, BLOB storage is not as

efficient as the file system for storing large data values, so more storage space is required

FILESTREAM storage, introduced in SQL Server 2008, helps to solve the issues with using

unstructured data by integrating the SQL Server Database Engine with the NTFS file

system for storing unstructured data such as documents and images on the file system

with a pointer to the data in the database The file pointer is implemented in SQL Server

as a varbinary(max)column, and the actual data is stored in files in the file system

In addition to enabling client applications to leverage the rich NTFS streaming APIs and

the performance of the file system for storing and retrieving unstructured data, other

advantages of FILESTREAM storage include the following:

You are able to use T-SQL statements to insert, update, query, and back up

FILESTREAM data even though the actual data resides outside the database in the

NTFS file system

You are able to maintain transactional consistency between the unstructured data

and corresponding structured data

You are able to enforce the same level of security on the unstructured data as with

your relational data using built-in SQL Server security mechanisms

Trang 10

FILESTREAM uses the NT system cache for caching file data rather than caching the

data in the SQL Server buffer pool, leaving more memory available for query

processing

FILESTREAM storage also eliminates the size limitation of BLOBS stored in the

data-base Whereas standard imageandvarbinary(max)columns have a size limitation of

2GB, the sizes of the FILESTREAM BLOBs are limited only by the available space of

the file system

Columns with the FILESTREAMattribute set can be managed just like any other BLOB

column in SQL Server Administrators can use the manageability and security capabilities

of SQL Server to integrate FILESTREAM data management with the rest of the data in the

relational database—without needing to manage the file system data separately This

includes maintenance operations such as backup and restore, complete integration with

the SQL Server security model, and full-transaction support to ensure data-level

consis-tency between the relational data in the database and the unstructured data physically

stored on the file system The database administrator does not need to manage the file

system data separately

Whether you should use database storage or file system storage for your BLOB data is

determined by the size and use of the unstructured data If the following conditions are

true, you should consider using FILESTREAM:

The objects being stored as BLOBS are, on average, larger than 1MB

Fast read access is important

You are developing applications that use a middle tier for application logic

Enabling FILESTREAM Storage

If you decide to use FILESTREAM storage, it first needs to be enabled at both the Windows

level as well as at the SQL Server Instance level FILESTREAM storage can be enabled

auto-matically during SQL Server installation or manually after installation

If you are enabling FILESTREAM during SQL Server installation, you need to provide the

Windows share location where the FILESTREAM data will be stored You can also choose

whether to allow remote clients to access the FILESTREAM data For more information on

how to enable FILESTREAM storage during installation, see Chapter 8, “Installing SQL

Server 2008.”

If you did not enable the FILESTREAM option during installation, you can enable it for a

running instance of SQL Server 2008 at any time using SQL Server Configuration Manager

(SSCM) In SSCM, right-click on the SQL Server Service and select Properties Then select

the FILESTREAM tab, which provides similar options as those displayed during SQL Server

installation (see Figure 42.1) This enables SQL Server to work directly with the Windows

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN