Not long ago I had a mission to normalize a Routes Waypoint table .
The current RoutePoints table should be split into 2 tables:Route table and a Waypoints table.
The following is used to create the table demo sample for the post
IF EXISTS ( SELECT *FROM sys.tablesWHERE name = 'RoutesPoints' )DROP TABLE RoutesPoints;CREATE TABLE RoutesPoints( RouteName VARCHAR(255),WayPointName VARCHAR(255),WayPointlocation GEOGRAPHY ,WayPointType VARCHAR(6),);INSERT INTO RoutesPoints( RouteName, WayPointName,WayPointlocation, WayPointType )VALUES( 'Route1', 'WayPoint1', geography::STGeomFromText('POINT(32.34900 36.65150)', 4326) , 'Start' ),( 'Route2', 'WayPoint2', geography::STGeomFromText('POINT(32.34900 36.65260)', 4326) , 'Start' ),( 'Route1', 'WayPoint3', geography::STGeomFromText('POINT(32.34900 36.65600)', 4326) , 'Middle' ),( 'Route3', 'WayPoint4', geography::STGeomFromText('POINT(32.34900 36.65666)', 4326) , 'End' ),( 'Route3', 'WayPoint5', geography::STGeomFromText('POINT(32.34800 36.65160)', 4326) , 'Middle' ),( 'Route2', 'WayPoint6', geography::STGeomFromText('POINT(32.34980 36.65290)', 4326) , 'Start' ),( 'Route1', 'WayPoint7', geography::STGeomFromText('POINT(32.34908 36.61100)', 4326) , 'Start' ),( 'Route2', 'WayPoint8', geography::STGeomFromText('POINT(32.34950 36.65150)', 4326) , 'Middle' ),( 'Route1', 'WayPoint9', geography::STGeomFromText('POINT(32.34900 36.65540)', 4326) , 'Start' ),( 'Route2', 'WayPoint10', geography::STGeomFromText('POINT(32.34900 36.65550)', 4326) , 'Start' ),( 'Route1', 'WayPoint11', geography::STGeomFromText('POINT(32.34900 36.65230)', 4326) , 'End' ),( 'Route2', 'WayPoint12', geography::STGeomFromText('POINT(32.34940 36.65150)', 4326) , 'Middle' ),( 'Route1', 'WayPoint13', geography::STGeomFromText('POINT(32.34600 36.65270)', 4326) , 'Start' ),( 'Route4', 'WayPoint16', geography::STGeomFromText('POINT(32.34500 36.65340)', 4326) , 'Start' ),( 'Route1', 'WayPoint14', geography::STGeomFromText('POINT(32.34500 36.65160)', 4326) , 'Middle' ),( 'Route2', 'WayPoint17', geography::STGeomFromText('POINT(32.34400 36.65150)', 4326) , 'Middle' ),( 'Route3', 'WayPoint18', geography::STGeomFromText('POINT(32.34200 36.65140)', 4326) , 'Start' ),( 'Route3', 'WayPoint19', geography::STGeomFromText('POINT(32.34200 36.65150)', 4326) , 'Start' ),( 'Route1', 'WayPoint20', geography::STGeomFromText('POINT(32.34100 36.65140)', 4326) , 'Middle' ),( 'Route2', 'WayPoint21', geography::STGeomFromText('POINT(32.34100 36.65150)', 4326) , 'End' ),( 'Route1', 'WayPoint22', geography::STGeomFromText('POINT(32.34910 36.65160)', 4326) , 'Middle' ),( 'Route2', 'WayPoint23', geography::STGeomFromText('POINT(32.34430 36.65100)', 4326) , 'Start' ),( 'Route2', 'WayPoint24', geography::STGeomFromText('POINT(32.34440 36.65180)', 4326) , 'Start' ),( 'Route2', 'WayPoint25', geography::STGeomFromText('POINT(32.34530 36.65140)', 4326) , 'Middle' ),( 'Route1', 'WayPoint26', geography::STGeomFromText('POINT(32.34340 36.65800)', 4326) , 'Start' ),( 'Route3', 'WayPoint27', geography::STGeomFromText('POINT(32.34670 36.65700)', 4326) , 'Start' ),( 'Route2', 'WayPoint28', geography::STGeomFromText('POINT(32.34540 36.65600)', 4326) , 'End' ),( 'Route3', 'WayPoint29', geography::STGeomFromText('POINT(32.34650 36.65500)', 4326) , 'Middle' ),( 'Route1', 'WayPoint30', geography::STGeomFromText('POINT(32.34345 36.65140)', 4326) , 'Start' ),( 'Route4', 'WayPoint31', geography::STGeomFromText('POINT(32.34584 36.65130)', 4326) , 'Start' ),( 'Route5', 'WayPoint31', geography::STGeomFromText('POINT(32.34888 36.65200)', 4326) , 'Middle' ),( 'Route4', 'WayPoint32', geography::STGeomFromText('POINT(32.34900 36.65100)', 4326) , 'Middle' )
The rolls for the normalization process :
Every route should contains one start waypoint , one end way point and 0..n middle waypoints. if no start or end drop the points drop the route data if more then one end or start points exists to the same route take the first occurrence.
The T-SQL for the normalized tables
IF EXISTS ( SELECT *FROM sys.tablesWHERE name = 'RoutePoints' )DROP TABLE RoutePoints;CREATE TABLE RoutePoints( RouteID int,WayPointName VARCHAR(255),WayPointlocation GEOGRAPHY ,WayPointType VARCHAR(6),);IF EXISTS ( SELECT *FROM sys.tablesWHERE name = 'Routes' )DROP TABLE Routes;CREATE TABLE Routes( RouteID int ,[Name] VARCHAR(255),CONSTRAINT PK_Routes_RoutesID PRIMARY KEY CLUSTERED (RouteID));goALTER TABLE RoutePointsADD CONSTRAINT RouteKey FOREIGN KEY (RouteID)REFERENCES Routes (RouteID)ON DELETE CASCADEGO
The resolution for this problem is based on this article.
אין תגובות:
הוסף רשומת תגובה