仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 736|回复: 8
打印 上一主题 下一主题

[学习教程] MSSQL网站制作之在 SQL Server 2005 中利用表值函数来实...

[复制链接]
冷月葬花魂 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:23:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
两个到底是哪一个给出了MySQL这个名字至今依然是个迷,包括开发者在内也不知道。server|函数|数据|数据库GyorgyFekete和AlexSzalay
约翰霍普金丝年夜学

JimGray
Microsoft(接洽作者)

合用于
MicrosoftSQLServer2005

择要:本文申明了怎样利用C#和表值函数将空间搜刮函数(“临近点的点”和“多边形内的点”)增加到MicrosoftSQLServer2005。利用此库能够在不编写任何特别代码的情形下向使用程序中增加空间搜刮。此库完成了来自约翰霍普金丝年夜学的大众域C#分层三角网格(HTM)算法。该C#库利用一组标量值函数和表值函数毗连到SQLServer2005。这些函数起空间索引的感化。
您能够下载本文档的MicrosoftWord版本。

本页内容
简介
表值函数:次要观点
利用表值函数增加空间索引
数据集
典范查询
停止语
附录A:参考材料
附录B:基础HTM例程

简介
空间数据搜刮经常使用于贸易和迷信使用程序。分离在针对地理范畴构建SkyServer(http://skyserver.sdss.org/)方面的勉力,我们开辟了一种空间搜刮体系。SkyServer是一个几千GB巨细的数据库,个中收录了约莫3亿个天体工具。地理学家必要对该数据库举行的很多查询城市触及到空间搜刮。典范的查询包含:“临近此点的工具有哪些”、“此地区内包括哪些工具”和“哪些地区与此地区有堆叠”?

在本文中,我们向地理学家的赤经/赤纬(ra/dec)天球(天空)网格增加了纬度/经度(lat/lon)地球网格。这两种网格大抵不异,但并不是准确对应,传统按次lat-lon与dec-ra绝对应。这一按次上的倒置迫使我们必需明白坐标系。我们将格林尼治子午线-赤道年夜地坐标系称为LatLon坐标系。该库撑持三种坐标系:
•格林尼治纬度-经度,称为LatLon。

•地理赤经-赤纬,称为J2000。

•笛卡尔(x,y,z),称为笛卡尔。

地理学家利用弧度分作为尺度的间隔器度。因为一海里为一弧度分,因而间隔转换十分复杂。其他很多观点也极其类似。为了申明这些成绩,本文将演示怎样利用此空间库针对两个USGS数据集构建空间索引,这两个数据集是:美国乡村和美国流量计。本文利用这些索引和一些空间函数供应了多少示例,来讲明怎样搜刮临近某一点的乡村、怎样查找临近某一乡村的流量计和怎样查找某个州(多边形地区)内的流量计或乡村。
我们以为此办法具有通用性。能够向几近一切使用程序中增加空间数据中心架构和空间数据函数以便举行空间查询。这些观点也合用于其他的多维索引计划。比方,这些手艺可用于搜刮色彩空间或其他任何低维度器度空间。
前往页首
表值函数:次要观点
干系代数的次要观点是,每一个干系运算符均利用一个或多个干系,并天生一个输入干系。SQL是对这一观点的语法润色,使您能够界说干系(数据界说言语)和用选择-拔出-更新-删除语法来操纵干系。

界说本人的标量函数使您能够对干系数据库举行扩大:您能够发送邮件,能够实行命令剧本,还能够盘算非尺度标量和聚合值,比方tax()或median()。
可是,假如您能够创立表,则能够成为干系引擎的一部分:既是干系表的天生者,也是其利用者。这就是OLEDB的观点,此观点同意任何数据源天生数据流。这也是SQLServer2000表值函数包含的观点。
在Transact-SQL中完成表值函数很复杂:
createfunctiont_sql_tvfPoints()
returns@pointstable(xfloat,yfloat)
asbegin
insert@pointsvalues(1,2);
insert@pointsvalues(3,4);
return;
end

假如能够完整在Transact-SQL中实行函数,如许做就能够了。可是,在SQLServer2000中,要在Transact-SQL内部完成OLEDB数据源或表值函数的确十分坚苦。
而SQLServer2005集成了大众言语运转库,能够简单地创立表值函数。您能够创立列表、数组或恣意IEnumerable工具(能够对其举行foreach操纵的恣意工具),然后将其转换为表。
[SqlFunction(TableDefinition="xfloat,yfloat",
FillRowMethodName="FillPair")]
publicstaticIEnumerablecsPoints()
{
int[,]points={{1,2},{3,4}};
return(IEnumerable)points;
}

在VisualStudio中编译这段代码,然后单击Deploy(部署)。表值函数将被安装到数据库中。
前往页首
利用表值函数增加空间索引
关于索引,人们存在很多狐疑。现实上,索引十分复杂:它们只是带有一些特别属性的表:

•SQLServer唯一一种联系关系(按值)索引:B树。B树能够具有多字段键,但最常选择的是第一个字段。

•从观点上说,B树索引是由B树键字段、基表键字段和您要增加到索引的任何包括字段所构成的表。

•B树索引将依据索引键(比方邮政编码或客户ID)来排序,以便按该键举行查找或按次扫描会很快。

•索引一般比基表小,只包括最主要的属性,以便与反省全部表比拟,在索引中举行查找所触及的字节数小很多。一般情形下,索引十分小,乃至能完整装在主内存中,从而省往更多的磁盘存取。

•当您实行索引查找时,大概仅仅是搜刮索引(基表的垂直部分),也多是先搜刮索引,再使用基表主键将切合请求的索引逐行到场基表中(书签查找)。

中央头脑是,空间索引可为您供应一小部分数据。索引会告知您查找的地位,并一般附带一些有效的搜刮信息(专家将其称为包括列或掩盖列)。索引的选择性标明了初始缩减的水平(所示的大略子集)。找到响应的子集后,将细心反省该子集的每一个成员并舍弃假正值。中的菱形框指了然该历程。好的索引只含有大批的假正值。在整篇文章中,我们都将利用中的说法(大略子集和细心反省)。



B树和表值函数能够以下组合,以使您能够构建本人的空间索引来天生大略子集:
•创立一个函数,以天生将相干数据会萃在一同的键。比方,假如项目A和B相干,则A和B的键在B树键空间中应当是临近的。
•创立一个表值函数,以便在给出了对所需子集的申明后,前往包括一切相干值的键局限(“掩盖”)列表。

您没法一直让每一个键与其一切相干项临近,由于键是在一个维度中排序的,而相干项是在二维或更高维数的空间中与其临近。可是能够只管如许做。假正值与准确谜底的比率权衡了您所接纳的体例的优劣。
尺度办法是,找到某一条空间添补曲线,并使键空间沿该曲线穿过。比方,利用尺度墨卡托舆图,能够将东南中的每一个人分派给东南键局限,将西北中的每一个人分派给西北键局限。显现了第二种按次空间添补曲线,它横穿一切这些象限,按按次分派键。东南-东北象限中的每一个人都具有键前缀nwsw。假如您的地区与中所示的圆圈相似,就能够晓得您的键局限
  1. keybetweennwswandnwse
复制代码


此搜刮空间占全部表的八分之一,而且含有约莫75%的假正值(由圆圈外但位于两个方框内的地区暗示)。改善不年夜,但转达了一种观点。更好的索引要利用更精密的单位格分区。假如单位格充足精密,则聚合地区中的假正值就会十分少。要具体检察空间添补曲线和空间分区树,您能够参阅HananSamet[Samet]的书本。
如今,我们要界说一种空间添补曲线:分层三角网格(HTM),它出格合用于球面。地球是圆的,天球也是圆的,因而,这类球面体系关于地舆学家和地理学家来讲十分便利。我们能够对任何器度空间做一些相似的事变。空间添补曲线供应了一些键来作为空间索引的基本。那末,假如或人具有所需的地区时,我们的表值函数将为其供应一组得当的键局限供查找(中的大略选择)。这些键局限将掩盖带有球面三角形的地区(称为trixel),这与中掩盖圆圈的两个方框十分类似。搜刮函数只需检察这些trixel的键局限内的一切工具,以断定它们是不是切合请求(中的细心反省)。
我们能够用一个详细的例子举行申明,假定有一个工具表
  1. createtableObject(objIDbigintprimarykey,latfloat,--Latitudelonfloat,--LongitudeHtmIDbigint)--TheHTMkey
复制代码
和一个间隔函数dbo.fDistanceLatLon(lat1,lon1,lat2,lon2),该函数可盘算出两点之间的海里(弧度分)数。进一步假定以下表值函数给出了位于某个lat-lon点的定长半径局限内的HtmID点的键局限列表。
  1. definefunctionfHtmCoverCircleLatLon(@latfloat,@lonfloat,@radiusfloat)returns@TrixelTabletable(HtmIdStartbigint,HtmIdEndbigint)
复制代码
然后,以下查询会查找旧金山(lat,lon)=(37.8,-122.4)四周40海里局限内的点。
  1. selectO.ObjID,dbo.fDistanceLatLon(O.lat,O.lon,37.8,-122.4)fromfHtmCoverCircleLatLon(37.8,-122.4,40)asTrixelTablejoinObjectOonO.HtmIDbetweenTrixelTable.HtmIdStart--coarsetestandTrixelTable.HtmIdEndwheredbo.fDistanceLatLon(lat,lon,37.8,-122.4)<40--carefultest
复制代码
如今,我们必需界说HTM键天生函数、间隔函数和HTM掩盖函数。下一步我们将以两组美国地质空间数据集为例实行这些操纵。假如您不信任个中包括的工具达数十亿,请会见http://skyserver.sdss.org/并扫瞄一下该网站。该网站利用不异的代码来对几千GB的地理数据库举行空间查找。
本文次要报告怎样利用SQL表值函数和像HTM如许的空间添补曲线来构建空间索引。一样地,我们将HTM代码自己看成一种在别处[Szalay]存档的玄色方框,我们只存眷怎样使其在SQL使用程序内合适我们的必要。
前往页首
数据集

美国地质勘察局(USGS)搜集并公布了美国的相干数据。显现了由USGS保护的18000台用于丈量河道水流量和级其余流量计。USGS还公布了23000个地址的地名及其生齿的列表。


USGS住民点(23000个乡村)
USGS在1993年公布了地址称号及其某些属性的列表。USGS网站上有一些更新的列表,但因为它们是按州来分段的,因而很难取得一个天下局限的列表。旧的列表足以可以演示空间索引。数据格局以下:
  1. createtablePlace(PlaceNamevarchar(100)notnull,--CitynameStatechar(2)notnull,--2charstatecodePopulationintnotnull,--Numberofresidents(1990)Householdsintnotnull,--Numberofhomes(1990)LandAreaintnotnull,--AreainsqareKMWaterAreaintnotnull,--WaterareawithinlandareaLatfloatnotnull,--LatitudeindecimaldegreesLonfloatnotnull,--LongitudedecimaldegreesHtmIDbigintnotnullprimarykey--spatialindexkey)
复制代码
为了加速称号查找,我们增加了一个称号索引,但数据是按空间键会萃在一同的。临近的工具配合位于会萃B树中,并因而位于不异或相邻的磁盘页上。
  1. createindexPlace_NameonPlace(PlaceName)
复制代码
能够从USGS网站下载除HtmID数据之外的其他一切数据。能够用SQLServer2005数据导进导游来导进数据(我们已在示例数据库中举行了此操纵)。HtmID字段是依据LatLon按以下办法盘算出的:
  1. updatePlacesetHtmID=dbo.fHtmLatLon(lat,lon)
复制代码
USGS流量计(17000台仪器)
USGS自1854起一向在保护河道流量纪录。到2000年1月1日,他们已积累了凌驾43万年的丈量数据。约莫有六千个举动的丈量站处于举动形态,而有约莫四千个处于联机形态。http://waterdata.usgs.gov/nwis/rt中对这些流量计举行了具体先容。有个NOAA站点以十分便当的体例显现了来自几百个最广泛的丈量站的数据:http://weather.gov/rivers_tab.php
我们的数据库只包括美国年夜陆的丈量站(见)。关岛、阿拉斯加、夏威夷、波多黎各和维京群岛也有丈量站,但不包括在此数据库内。流量计丈量站表为:
  1. createtableStation(StationNamevarchar(100)notnull,--USGSStationNameStatechar(2)notnull,--StatelocationLatfloatnotnull,--LatitudeinDecimalLonfloatnotnull,--LongitudeinDecimalDrainageAreafloatnotnull,--DrainageArea(km2)FirstYearintnotnull,--FirstYearoperationYearsRecordedintnotnull,--Recordyears(atY2k)IsActivebitnotnull,--WasitactiveatY2k?IsRealTimebitnotnull,--OnInternetatY2K?StationNumberintnotnull,--USGSStationNumberHtmIDbigintnotnull,--HTMspatialkey--(basedonlat/lon)primarykey(htmID,StationNumber))
复制代码
如上所述,HtmID字段是依据LatLon按以下办法盘算出的:
  1. updateStationsetHtmID=dbo.fHtmLatLon(lat,lon)
复制代码
因为一个地位有多达18个丈量站,因而主键必需包含丈量站编号以便辨别它们。可是,在B树中,HTM键将一切临近的丈量站会萃在一同。为了加速查找,我们增加了丈量站编号和称号索引:
  1. createindexStation_NameonStation(StationName)createindexStation_NumberonStation(StationNumber)
复制代码
空间索引表
如今,我们就能够创立本人的空间索引了。我们本能够将字段增加到基表,但要使存储历程对多个分歧的表均无效,我们发明,只需将一切工具到场到一个空间索引中便可。您能够选择(type,HtmID)作为键来断绝分歧范例的工具;我们选择了(HtmID,key)作为键,以便将一切范例(乡村和流量计)的临近工具会萃在一同。该空间索引为:
  1. createtableSpatialIndex(HtmIDbigintnotnull,--HTMspatialkey(basedonlat/lon)Latfloatnotnull,--LatitudeinDecimalLonfloatnotnull,--LongitudeinDecimalxfloatnotnull,--Cartesiancoordinates,yfloatnotnull,--derivedfromlat-lonzfloatnotnull,--,Typechar(1)notnull,--Place(P)orgauge(G)ObjIDbigintnotnull,--ObjectIDintableprimarykey(HtmID,ObjID))
复制代码
此主题前面将对笛卡尔坐标举行申明。至于如今,我们只必要晓得,fHtmCenterPoint(HtmID)函数将前往该HTM三角形中央点的笛卡尔(x,y,z)单元向量。这就是该HTM的极限点,由于其中心被细分为无量个小的trixel。
SpatialIndex表将依据Place和Station表的数据来添补,以下所示:
  1. insertSpatialIndexselectP.HtmID,Lat,Lon,XYZ.x,XYZ.y,XYZ.z,Pastype,P.HtmIDasObjIDFromPlacePcrossapplyfHtmLatLonToXyz(P.lat,P.lon)XYZinsertSpatialIndexselectS.HtmID,Lat,Lon,XYZ.x,XYZ.y,XYZ.z,Sastype,S.StationNumberasObjIDfromStationScrossapplyfHtmLatLonToXyz(S.lat,S.lon)XYZ
复制代码
为了清算数据库,应实行以下命令:
  1. DBCCINDEXDEFRAG(spatial,Station,1)DBCCINDEXDEFRAG(spatial,Station,Station_Name)DBCCINDEXDEFRAG(spatial,Station,Station_Number)DBCCINDEXDEFRAG(spatial,Place,1)DBCCINDEXDEFRAG(spatial,Place,Place_Name)DBCCINDEXDEFRAG(spatial,SpatialIndex,1)DBCCSHRINKDATABASE(spatial,1)-1percentsparespace
复制代码
题外话:笛卡尔坐标
您能够选择跳过此部分。此部分关于利用该库并非必须的。HTM代码必需依托一种技能来避开球面多少成绩:它从球面的二维外表移到了三维空间。这就使得“在多边形内”和“在点四周”查询的反省举行得十分快。
球面上的每一个lat/lon点都能够暗示为三维空间中的一个单元向量v=(x,y,z)。北极和南极(90°和-90°)的单元向量分离为v=(0,0,1)和v=(0,0,-1)。Z代表扭转轴,XZ立体代表本初(格林尼治)子午线,其经度为0°或180°。正式的界说为:
  1. x=cos(lat)cos(lon)y=cos(lat)sin(lon)z=sin(lat)
复制代码
这些笛卡尔坐标的利用办法以下:给订单位球面上的两点p1=(x1,y1,z1)和p2=(x2,y2,z2),则它们的点乘积p1&p2=x1*x2+y1*y2+z1*z2就是这两点所代表的单元向量之间的角度的余弦值。它是一个间隔器度。显现了笛卡尔坐标怎样使得对“多边形内的点”和“临近点的点”的反省疾速举行。每一个lat/lon点均具有一个对应的(x,y,z)单元向量。


假如我们要查找p1点四周45海里(弧度分)局限内的点,则它与p1点最多成45/60度。这些点与p1的点乘积将小于d=acos(radians(45/60)。该“临近”反省即变成{p2|p2&p1<d},它将很快举行。在中,每一个年夜圆圈或小圆圈都是一个立体与该圆圈的交集,假如某一点与立体法向量的点乘积小于cos(?¨)(个中2?¨是该圆圈的弧度角直径),则该点就在圆圈外部。


笛卡尔坐标还可使得对“多边形内的点”的反省疾速举行。一切的多边形都具有年夜圆边或小圆边。这些边缘着与球面交织的某个立体散布。因而,能够经由过程与该立体垂直的单元向量v及其位移来界说这些边。比方,赤道就是向量v=(0,0,1),且位移为零。纬度60°由向量v=(0,0,1)及位移0.5来界说,而环绕巴尔的摩市的60°纬度圈由向量v=(0.179195,-0.752798,0.633392)及0.5个位移来界说。关于地址p2,假如p2&v<0.5,则该地址就位于巴尔的摩市60°纬度圈内。一样,能够经由过程盘算出三个这类点乘积来断定某个点位于HTM三角形外部仍是内部。这是HTM代码云云无效和快速的次要缘故原由之一。
我们完成了多少帮助历程来举行从LatLon到笛卡尔坐标的转换。




本文稍后将用到这些函数,它们存档在APIspecandIntellisense[Fekete]中。
在此,该库的默许设置为21级深度的HTM键(第一级将球面分红八个外表地区,随后每级将球面三角形分红四个子三角形)。从表1中可看出,21级深度的trixel相称小。最多能够将代码修正为31级深度,这是由于不克不及超越64位暗示法所占用的位数。
在表1中,每一个HTM级别城市细分球面。关于每一个级别,此表均以度数、弧度分、弧度秒和米四种单元的平方情势暗示了面积。trixel列显现了一些特性巨细:默许的21级深度的trixel约莫为0.3平方弧度秒。USGS数据在每12级深度的trixel具有约莫半个工具。
表1HTM深度面积工具/trixeldeg2
arcmin2
arcsec2
earthm2
trixel
SDSS
USGS
球面
41253
148,510,800
534,638,880,000
5.E+14
0
5157
18,563,850
66,829,860,000
6E+13
3E+8
1
1289
4,640,963
16,707,465,000
2E+13
8E+7
2
322
1,160,241
4,176,866,250
4E+12
2E+7
3
81
290,060
1,044,216,563
1E+12
5E+6
4
20
72,515
261,054,141
2E+11
1E+6
30,000
5
5
18,129
65,263,535
6E+10
3E+5
7,500
6
1
4,532
16,315,884
2E+10
1deg2
73242
1,875
7
3E-1
1,133
4,078,971
4E+9
18311
468
8
8E-2
283
1,019,743
1E+9
4578
117
9
2E-2
71
254,936
2E+8
1144
29
10
5E-3
18
63,734
6E+7
286
7
11
1E-3
4
15,933
2E+7
72
2
12
3E-4
1
3,983
4E+6
1amin2
18
0.5
13
8E-5
3E-1
996
943816
4
0.1
14
2E-5
7E-2
249
235954
1
15
5E-6
2E-2
62
58989
0.3
16
1E-6
4E-3
16
14747
.
17
3E-7
1E-3
4
3687
18
8E-8
3E-4
1
922
19
2E-8
7E-5
2E-1
230
1asec2
20
5E-9
2E-5
6E-2
58
1km2
21
1E-9
4E-6
2E-2
14
22
3E-10
1E-6
4E-3
4
23
7E-11
3E-7
9E-4
1
1m2
24
2E-11
7E-8
2E-4
2E-1
25
5E-12
2E-8
6E-5
6E-2
26
1E-12
4E-9
1E-5
1E-2

前往页首
典范查询

如今,您应该能够实行一些查询了。
查询1:查找临近点的点:查找临近某一地址的城镇
最多见的查询是查找临近某个特定地址或点的一切地址。思索以下查询,“查找马里兰州巴尔的摩市四周100海里内的一切城镇”。经由过程上面的办法来失掉掩盖巴尔的摩市四周100海里(100弧度分)局限的HTM三角形
  1. select*--findaHTMcover100NMaroundBaltimorefromfHtmCoverCircleLatLon(39.3,-76.6,100)
复制代码
它将前往表2中所示的Trixel表。即,fHtmCoverCircleLatLon()函数将前往“掩盖”该圆圈(在本例中,是单个trixel)的一组HTM三角形。该圆圈内一切工具的HTM键也位于这些三角形中之一内。如今,我们必要反省一切这些三角形并舍弃假正值(中的细心反省)。我们将依照与巴尔的摩市的间隔对谜底集举行排序,因而,假如我们必要找出比来的地址,只需选择TOP1WHEREdistance>0便可(我们要从中扫除巴尔的摩市自己)。
  1. declare@latfloat,@lonfloatselect@lat=lat,@lon=lonfromPlacewherePlace.PlaceName=BaltimoreandState=MDselectObjID,dbo.fDistanceLatLon(@lat,@lon,lat,lon)asdistancefromSpatialIndexjoinfHtmCoverCircleLatLon(@lat,@lon,100)OnHtmIDbetweenHtmIdStartandHtmIdEnd--coarsetestandtype=Panddbo.fDistanceLatLon(@lat,@lon,lat,lon)<100--carefultestorderbydistanceasc
复制代码
表2.巴尔的摩市HTM掩盖纬度圈
HtmIdStartHtmIdEnd14023068221440
14027363188735

此掩盖连接将前往2928行(大略反省);个中1122行在100航空英里之内(细心反省)。它给出了61%的假正值:全体操纵在9毫秒内完成。
因为这些是罕见的义务,因而具有针对它们的尺度函数:
  1. fHtmNearbyLatLon(type,lat,lon,radius)fHtmNearestLatLon(type,lat,lon)
复制代码
如许,上述查询就变成
  1. selectObjID,distancefromfHtmNearestLatLon(P,39.3,-76.61)
复制代码
查询2:查找某个方框内的地址
在显现正方形的舆图或窗口时,使用程序一般必要查找某个正方形视区内的一切工具。科罗拉多州几近完整是正方形的,它的东南角点为(41°N-109°3W),东北角点为(37°N-102°3E)。该州的中央点为(39°N,-105°33E),因而能够用以该点为中央的圆圈掩盖该正方形。
  1. declare@radiusfloatset@radius=dbo.fDistanceLatLon(41,-109.55,37,-102.05)/2select*fromStationwhereStationNumberin(selectObjIDfromfHtmCoverCircleLatLon(39,-105.55,@radius)joinSpatialIndexonHtmIDbetweenHtmIdStartandHtmIdEndandlatbetween37and41andlonbetween-109.05and-102.048andtype=S)OPTION(FORCEORDER)
复制代码
本例在约莫46毫秒内前往了1030个流量计。科罗拉多州的其他五个流量计恰好在其界限上,分布于间隔南纬37°纬度圈不凌驾一海里的局限内。假如将南纬从37°调剂到36.98°,则其他这五个丈量站就会呈现。(GIS体系和地理使用程序一般必要某一地区四周具有缓冲区。此HTM代码包括对缓冲区的撑持,在实践的使用程序常常会用到缓冲区。请检察参考材料[Szalay]以懂得详细操纵体例。)此掩盖圆圈前往了36个三角形。与SpatialIndex表的连接前往了1975个流量计。个中包括47%的假正值。下一节将演示怎样经由过程利用HTM地区指定多边形掩盖而非圆圈掩盖对此举行改善。
FORCEORDER子句对照贫苦:假如短少该子句,查询的运转工夫会长十倍,由于优化器会将空间索引作为内部表举行嵌套轮回连接。假如这些表更年夜(包括数百万行),优化程序有大概会接纳其他企图,但我们不克不及期望它。优化程序不成能无需提醒就可以针对上一部分中的一切查询选择准确的企图。
查询3:查找某个多边形内的地址
HTM代码同意我们将此地区指定为圆圈、矩形、凸球面或这些地区的组合。出格地,HTM库同意利用上面的线性语法来指定地区:
  1. circleSpec:=CIRCLELATLONlatlonradius|CIRCLEJ2000radecradius|CIRCLE[CARTESIAN]xyzradiusrectSpec:=RECTLATLON{latlon}2|RECTJ2000{radec}2|RECT[CARTESIAN]{xyz}2hullSpec:=CHULLLATLON{lonlat}3+|CHULLJ2000{radec}3+|CHULL[CARTESIAN]{xyz}3+convexSpec:=CONVEX[CARTESIAN]{xyzD}*areaSpec:=rectSpec|circleSpec|hullSpec|convexSpecregionSpec:=REGION{areaSpec}*|areaSpec
复制代码
上面给出了地区指定示例:
圆圈。指定一个点和巨细为1.75海里(弧度分)的半径。
  1. CIRCLELATLON39.3-76.61100CIRCLECARTESIAN0.1792-0.75280.6334100
复制代码
矩形。指定用来界说最小和最年夜lat,lon的两个角点。经度坐标以折回体例断定,即lonmin=358.0和lonmax=2.0,这是一个四度宽的局限。纬度必需介于北极和南极之间。矩形边是纬度或经度坚持稳定的直线,而非凹形和凸形的年夜圆边。
  1. RECTLATLON37-109.5541-102.05
复制代码
凹形。指定用来界说凸球面三个或更多个点,且该凸球面的边用年夜圆圈将相邻的点毗连起来。这些点必需位于单个半球内,不然会产生毛病。这些点的按次可有可无。
  1. CHULLLATLON37-109.5541-109.5541-102.05137-102.05
复制代码
凸形。以笛卡尔向量(x,y,z)及该向量单元长度的份量的情势指定恣意多个(包含零个)束缚。
  1. CONVEX-0.17886-0.63204-0.754010.00000-0.977970.20865-0.000150.000000.164090.579870.798010.000000.94235-0.334630.000000.00000
复制代码
地区。地区是零个或更多个圆圈、矩形、凹形和凸形地区的组合。
  1. REGIONCONVEX0.70.70.0-0.5CIRCLELATLON18.2-22.41.75
复制代码
能够这些地区形貌中的恣意一个使用于fHtmCoverRegion()例程,以前往一个trixel表,用来形貌掩盖该地区的一组trixel(三角形地区)。用于此科罗拉多州查询的较复杂的代码为:
  1. selectS.*from(selectObjIDfromfHtmCoverRegion(RECTLATLON37-109.5541-102.05)loopjoinSpatialIndexonHtmIDbetweenHtmIdStartandHtmIdEndandlatbetween37and41andlonbetween-109.05and-102.048andtype=S)asGjoinStationSonG.objID=S.StationNumberOPTION(FORCEORDER)
复制代码
有需要利用这类不平常的查询格局来正确告知优化器连接的实行按次(以使“强迫按次”选项准确运转)。很难以这类体例修正优化器,直到表值函数具有统计信息为止,估量它们会十分泯灭资本。您必需强迫使它们进进外部轮回连接。
此查询将前往1030个流量计,而有1365个来自掩盖局限的候选项,因而包括25%的假正值。请注重,矩形掩盖优于圆形掩盖,由于后者包括61%的假正值。关于非矩形外形的州,可使用多边形语法,但本文仅报告表值函数,而不报告HTM算法。您能够在项目中和项目标相干文档中检察HTM代码。
能够转换为凸球面举行相似的查询。
  1. selectS.*from(selectObjIDfromfHtmCoverRegion(CHULLLATLON37-109.5541-109.5541-102.0537-102.05)loopjoinSpatialIndexonHtmIDbetweenHtmIdStartandHtmIdEndandlatbetween37and41andlonbetween-109.05and-102.048andtype=S)asGjoinStationSonG.objID=S.StationNumberOPTION(FORCEORDER)
复制代码
此查询将前往1030个流量计,而有1193个来自掩盖局限的候选项,因而包括14%的假正值。在本例中,凸球面掩盖比一律的矩形掩盖更好。
查询4:初级主题:庞大地区
后面的示例给出了用于地区的语法,并对“临近点的点”和“矩形内的点”搜刮举行了叙述。地区大概会非常庞大。它们是多个凸形地区的布尔组合。我们没法在此具体注释地区的观点,但陪伴项目中的HTM库包括对地区举行布尔组合、简化地区、盘算地区极点和盘算地区面积的逻辑,还包括很多其他特征。[Fekete]、[Gray]和[Szalay]中先容了这些观点。
为了开端了解这些观点,我们以犹他州为例。它的界限可用两个矩形来近似地界说:
  1. declare@utahRegionvarchar(max)set@utahRegion=region+rectlatlon37-114.047541-109.0475--Mainpart+rectlatlon41-114.047542-111.01--OgdenandSaltLake.
复制代码
如今,我们能够用以下查询来查找犹他州中的一切流量计:
  1. selectS.*from(selectObjIDfromfHtmCoverRegion(@utahRegion)loopjoinSpatialIndexonHtmIDbetweenHtmIdStartandHtmIdEndand(((latbetween37and41)--Carefultestand(lonbetween-114.0475and-109.04))--Areweinsideor((latbetween41and42)--oneofthetwoand(lonbetween-114.0475and-111.01))--boxes?)andtype=S)asGjoinStationSonG.objID=S.StationNumberOPTION(FORCEORDER)
复制代码
掩盖前往了38个trixel。连接前往了775个丈量站。细心反省找到了犹他州中的670个丈量站,别的有怀俄名州的两个丈量站恰好位于交界处(14%的假正值)。
年夜多半州必要利用庞大很多的地区。比方,近似地将加利福尼亚州的界限连起来的地区为:
  1. declare@californiaRegionvarchar(max)set@californiaRegion=region+rectlatlon39-125--Nortwestcorner+42-120--CenterofLakeTahoe+chulllatlon39-124--Pt.Arena+39-120--LakeTahoe.+35-114.6--StartColoradoRiver+34.3-114.1--LakeHavasu+32.74-114.5--Yuma+32.53-117.1--SanDiego+33.2-119.5--SanNicholasIs+34-120.5--SanMiguelIs.+34.57-120.65--Pt.Arguelo+36.3-121.9--Pt.Sur+36.6-122.0--Monterey+38-123.03--Pt.RayesselectstationNumberfromfHtmCoverRegion(@californiaRegion)loopjoinSpatialIndexonHtmIDbetweenHtmIdStartandHtmIdEnd/*and<carefultest>*/andtype=SjoinStationSonobjID=S.StationNumberOPTION(FORCEORDER)
复制代码
掩盖前往了108个trixel,一共包括2132个丈量站。个中,1928个位于加利福尼亚州内,因而假正值比率约莫为5%。可是细心反省并不是大事。
针对地址而非丈量站举行的不异查询(包含细心反省)相似于以下代码:
  1. select*fromPlacewhereHtmIDin(selectdistinctSI.objIDfromfHtmCoverRegion(@californiaRegion)loopjoinSpatialIndexSIonSI.HtmIDbetweenHtmIdStartandHtmIdEndandSI.type=PjoinplacePonSI.objID=P.HtmIDcrossjoinfHtmRegionToTable(@californiaRegion)PolygroupbySI.objID,Poly.convexIDhavingmin(SI.x*Poly.x+SI.y*Poly.y+SI.z*Poly.z-Poly.d)>=0)OPTION(FORCEORDER)
复制代码
此查询利用加利福尼亚州的凸形半空间暗示法和[Gray]中先容的手艺来疾速反省某个点是不是位于加利福尼亚州凸球面内。它前往了885个地址,个中7个位于与加利福尼亚州毗连的亚利桑那州(多边形近似于加利福尼亚州的界限)。它在1GHz的处置器上运转了0.249秒。假如不必OPTION(FORCEORDER)子句,其运转速率将变慢,必要消费247秒。
因为此请求非常罕见,并且代码极具技能性,因而我们增加了fHtmRegionObjects(Region,Type)历程,用来从空间索引中前往工具ID。因为此历程封装了后面所示的两个技能性代码,因而这两个针对加利福尼亚州的查询变成了:
  1. select*--GetalltheCaliforniaRiverStationsfromStationwherestationNumberin--thatareinsidetheregion(selectObjIDfromfHtmRegionObjects(@californiaRegion,S))select*--GetalltheCaliforniacitiesfromPlacewhereHtmIDin--thatareinsidetheregion(selectObjIDfromfHtmRegionObjects(@californiaRegion,P))
复制代码
针对科罗拉多州和犹他州的查询也能够利用此例程来简化。
前往页首
停止语

在此所述的HTM空间索引库自己是风趣而又有效的。基于球面为“多边形内的点”查询索引数据是一种便当的办法。可是,该库还作为一个示例很好地申明了怎样经由过程增加以诸如C#、C++、VisualBasic或Java之类的言语举行实践盘算的类库来扩大SQLServer和其他数据库体系。完成功效壮大的表值函数和标量函数并将这些查询及其永世数据集成到数据库中的才能是一种十分壮大的扩大机制,它将在包管工具干系数据库的基本上传送。这仅仅是个开首。在接上去的十年中,编程言语和数据库查询言语有大概取得更好的数据集成体例。这关于使用程序开辟职员来讲将是一件功德。
具体信息请拜见:
http://msdn.microsoft.com/sql/
项目编纂:SusanneBonney
前往页首
附录A:参考材料

•[Gray]“ThereGoestheNeighborhood:RelationalAlgebraforSpatialDataSearch”。JimGray、AlexanderS.Szalay、GyorgyFekete、WilOMullane、MariaA.Nieto-Santisteban、AniruddhaR.Thakar、GerdHeber、ArnoldH.Rots,MSR-TR-2004-32,2004年4月
•[Szalay]“IndexingtheSpherewiththeHierarchicalTriangularMesh”。AlexanderS.Szalay、JimGray、GeorgeFekete、PeterZ.Kunszt、PeterKukol、AniruddhaR.Thakar,MicrosoftSQLServer2005Samples。
•[Fekete]“SQLSERVER2005HTMInterfaceRelease4”。GeorgeFekete、JimGray、AlexanderS.Szalay,2005年5月15日,MicrosoftSQLServer2005Samples。
•[Samet1]“ApplicationsofSpatialDataStructures:ComputerGraphics,ImageProcessing,andGIS”。HananSamet,Addison-Wesley,Reading,MA,1990。ISBN0-201-50300-0。
•[Samet2]“TheDesignandAnalysisofSpatialDataStructures”。HananSamet,Addison-Wesley,Reading,MA,1990。ISBN0-201-50255-0。

前往页首
附录B:基础HTM例程

本节将先容HTM例程。附带文档[Szalay]中含有效于每一个例程的手册页,而且这些例程自己带有讲明以撑持IntelliSense。
鄙人面,lat和lon以十进轨制数暗示(南部和西部纬度为负),间隔以海里(弧度分)暗示。
HTM库版本:fHtmVersion()将前往版本字符串
例程将前往一个nvarchar(max)字符串来给出HTM库版本。
利用示例:
  1. printdbo.fHtmVersion()
复制代码
前往的内容相似以下了局:
  1. C#HTM.DLLV.1.0.01August2005
复制代码
天生HTM键:fHtmLatLon(lat,lon)将前往HtmID
例程将前往该LatLon点的21级深度的HTMID。
利用示例:
  1. updatePlacesetHtmID=dbo.fHtmLatLon(Lat,Lon)
复制代码
另有fHtmXyz()fHtmEq()函数可供地理学家利用。
LatLon到XYZ:fHtmLatLonToXyz(lat,lon)将前往点(x,y,z)
例程将前往该LatLon点的笛卡尔坐标。
利用示例(这是标识函数):
  1. SelectLatLon.lat,LatLon.lon-360fromfHtmLatLonToXyz(37.4,-122.4)asXYZcrossapplyfHtmXyzToLatLon(XYZ.x,XYZ.y,XYZ.z)asLatLon
复制代码
另有fHtmEqToXyz()函数可供地理学家利用。
XYZ到LatLon:fHtmXyzToLatLon(x,y,z)将前往点(lat,lon)
例程将前往该LatLon点的笛卡尔坐标。
利用示例(这是标识函数):
  1. SelectLatLon.lat,LatLon.lon-360fromfHtmLatLonToXyz(37.4,-122.4)asXYZcrossapplyfHtmXyzToLatLon(XYZ.x,XYZ.y,XYZ.z)asLatLon
复制代码
另有fHtmXyzToEq()函数可供地理学家利用。
检察HTM键:fHtmToString(HtmID)将前往HTM字符串
假如给定了HtmID,则例程将前往一个nvarchar(32),其情势为[N|S]t1t2t3...tn,个中每一个三角数字ti均为{0,1,2,3}格局,用以申明三角网格中该深度的HTMtrixel。
利用示例:
  1. printSQLServerdevelopmentisat:+dbo.fHtmToString(dbo.fHtmLatLon(47.646,-122.123))
复制代码
前往了局:N132130231002222332302。
另有fHtmXyz()fHtmEq()函数可供地理学家利用。
HTMtrixel中央点:fHtmToCenterpoint(HtmId)将前往点(x,y,z)
前往由HtmID指定的HTMtrixel的笛卡尔中央点。
利用示例:
  1. select*fromfHtmToCenterPoint(dbo.fHtmLatLon(47.646,-122.123))
复制代码
HTMtrixel角点:fHtmToCornerpoints(HtmId)将前往点(x,y,z)
前往由HtmID指定的HTMtrixel的三个笛卡尔角点。
利用示例:
  1. select*fromfHtmToCornerPoints(dbo.fHtmLatLon(47.646,-122.123))
复制代码
盘算间隔:fDistanceLatLon(lat1,lon1,lat2,lon2)将前往间隔
以海里(弧度分)为单元盘算两点之间的间隔。
利用示例:
  1. declare@latfloat,@lonfloatselect@lat=lat,@lon=lonfromPlacewherePlaceName=BaltimoreandState=MDselectPlaceName,dbo.fDistanceLatLon(@lat,@lon,lat,lon)asdistancefromPlace
复制代码
另有fDistanceXyz()fDistanceEq()函数可供地理学家利用。
上面的例程可前往一个用作空间索引的表。所前往空间索引表的数据界说为:
  1. SpatialIndexTabletable(HtmIDbigintnotnull,--HTMspatialkey(basedonlat/lon)Latfloatnotnull,--LatitudeinDecimalLonfloatnotnull,--LongitudeinDecimalxfloatnotnull,--Cartesiancoordinates,yfloatnotnull,--derivedfromlat-lonzfloatnotnull,--,Typechar(1)notnull,--place(P)orgauge(G)ObjIDbigintnotnull,--objectIDintabledistancefloatnotnull,--distanceinarcminutestoobjectprimarykey(HtmID,ObjID))
复制代码
查找临近的工具:fHtmNearbyLatLon(type,lat,lon,radius)将前往空间索引表
前往半径局限内特定范例的工具列表及它们到给定点的间隔。该列表将按工具的地位由近到远分列。
利用示例:
  1. selectdistance,Place.*fromfHtmNearbyLatLon(P,39.3,-76.6,10)IjoinPlaceonI.objID=Place.HtmIDorderbydistance
复制代码
另有fHtmGetNearbyEq()fHtmGetNearbyXYZ()函数可供地理学家利用。
查找比来的工具:fHtmNearestLatLon(type,lat,lon)将前往空间索引表
前往包括间隔该点比来的特定范例工具的列表。
利用示例:
  1. selectdistance,Place.*fromfHtmNearestLatLon(P,39.3,-76.6)IjoinPlaceonI.objID=Place.HtmID
复制代码
另有fHtmGetNearbyEq()fHtmGetNearbyXYZ()函数可供地理学家利用。
上面的例程将前往一个表,用以申明掩盖所需地区的一组trixel(HIM三角形)的HtmIdStart和HtmIdEnd。表的界说为:
  1. TrixelTabletable(HtmIdStartbigintnotnull,--minHtmIDintrixelHtmIdEndbigintnotnull--maxHtmIDintrixel)
复制代码
圆圈地区HTM掩盖:fHtmCoverCircleLatLon(lat,lon,radius)将前往trixel表
前往掩盖指定圆圈的trixel表。
利用示例:
  1. declare@answernvarchar(max)declare@latfloat,@lonfloatselect@lat=lat,@lon=lonfromPlacewherePlace.PlaceName=BaltimoreandState=MDset@answer=usingfHtmCoverCircleLatLon()itfinds:select@answer=@answer+cast(P.placeNameasvarchar(max))+,+str(dbo.fDistanceLatLon(@lat,@lon,I.lat,I.lon),4,2)+arcminutesdistant.fromSpatialIndexIjoinfHtmCoverCircleLatLon(@lat,@lon,5)OnHtmIDbetweenHtmIdStartandHtmIdEnd--coarsetestandtype=P--itisaplaceanddbo.fDistanceLatLon(@lat,@lon,lat,lon)between0.1and5--carefultestjoinPlacePonI.objID=P.HtmIDorderbydbo.fDistanceLatLon(@lat,@lon,I.lat,I.lon)ascprintThecitywithin5arcminutesofBaltimoreis:+Lansdowne-BaltimoreHighlands,4.37arcminutesaway
复制代码
另有fHtmCoverCircleEq()函数可供地理学家利用。
HTM掩盖的惯例地区指定:fHtmCoverRegion(region)将前往trixel表
前往掩盖指定地区的trixel表(本主题后面对地区举行了先容)。
  1. selectS.*from(selectObjIDfromfHtmCoverRegion(RECTLATLON37-109.5541-102.05)loopjoinSpatialIndexonHtmIDbetweenHtmIdStartandHtmIdEndandlatbetween37and41andlonbetween-109.05and-102.048andtype=S)asGjoinStationSonG.objID=S.StationNumberOPTION(FORCEORDER)
复制代码
惯例地区指定:fHtmRegionToNormalFormString(region)将前往地区字符串
前往格局为REGION{CONVEX{xyzd}*}*的字符串,个中已从每一个凸形删除过剩的半空间;如[Fekete]中所述,凸形已被简化。
  1. printdbo.fHtmToNormalForm(RECTLATLON37-109.5541-102.05)
复制代码
上面的例程将前往一个表,用以申明掩盖所需地区的一组trixel(HIM三角形)的HtmIdStart和HtmIdEnd。表的界说为:
  1. RegionTable(convexIDbigintnotnull,--IDoftheconvex,0,1,...halfSpaceIDbigintnotnull--IDofthehalfspace--withinconvex,0,1,2,xfloatnotnull--Cartesiancoordinatesofyfloatnotnull--unit-normal-vectorofzfloatnotnull--halfspaceplanedfloatnotnull--displacementofhalfspace)--alongunitvector[-1..1]
复制代码
将地区字符串转换为表:fHtmRegionToTable(region)将前往地区表
前往一个表,用以将地区作为凸形组合来讲明,个中每一个凸形均为x,y,z,d半空间的交集。如[Fekete]中所述,凸形已被简化。本文第4节先容了此函数的用法。
  1. select*fromdbo.fHtmToNormalForm(RECTLATLON37-109.5541-102.05)
复制代码
查找地区内的点:fHtmRegionObjects(region,type)将前往工具表
前往一个表,个中包括空间索引中具有指定范例且位于地区内的工具的工具ID。
  1. select*--findColoradoplaces.fromPlacesjoinwhereHtmIDinselectobjIDfromdbo.fHtmRegionObjects(RECTLATLON37-109.5541-102.05,P)
复制代码
惯例地区诊断:fHtmRegionError(region)将前往动静
假如地区界说无效,则前往“OK”;不然,前往形貌地区界说成绩的诊断信息,而且后跟地区的语法界说。
  1. printdbo.fHtmRegionError(RECTLATLON37-109.5541-102.05)
复制代码
mysql的原来开发者又开发了MariaDB,MariaDB适合用来替代mysql吗
因胸联盟 该用户已被删除
沙发
发表于 2015-1-19 10:29:42 来自手机 | 只看该作者
分区表是个亮点!从分区表也能看出微软要做大作强SQLServer的信心。资料很多,这里不详细说。但是重点了解的是:现在的SQLServer2005的表,都是默认为分区表的。因为它要支持滑动窗口的这个特性。这种特性对历史数据和实时数据的处理是很有帮助的。
兰色精灵 该用户已被删除
板凳
发表于 2015-1-24 12:55:12 来自手机 | 只看该作者
分区表效率问题肯定是大家关心的问题。在我的试验中,如果按照分区字段进行的查询(过滤)效率会高于未分区表的相同语句。但是如果按照非分区字段进行查询,效率会低于未分区表的相同语句。
精灵巫婆 该用户已被删除
地板
发表于 2015-2-1 14:58:10 | 只看该作者
两个月啃那本sqlserver2005技术内部-存储引擎,花了几个月啃四本书
莫相离 该用户已被删除
5#
发表于 2015-2-7 06:38:52 | 只看该作者
所以你总能得到相应的升级版本,来满足你的需求。
变相怪杰 该用户已被删除
6#
发表于 2015-2-20 23:41:15 | 只看该作者
发几份SQL课件,以飨阅者
不帅 该用户已被删除
7#
发表于 2015-3-6 19:18:17 | 只看该作者
SP4是一个累积性的ServicePack,包含自以前的ServicePack发布以来所有的修补程序(包括MS03-031安全公告)。
爱飞 该用户已被删除
8#
发表于 2015-3-13 06:11:24 | 只看该作者
我们学到了什么?思考问题的时候从表的角度来思考问
蒙在股里 该用户已被删除
9#
发表于 2015-3-20 15:01:08 | 只看该作者
比如日志传送、比如集群。。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 05:30

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表