规范化数据库列

3
这里的目标是能够查询一个数据库并提供一个“Journey”,基于这个“Journey”,数据库将返回所有运行通过此旅程的“Stop Codes”。
例如,我需要能够说:“选择运行通过34号旅程的所有停止代码”。然后这应该只返回STOP CODE:SZDASDASDE(在生产中将返回更多代码)。
上面您可以看到数据库中第一个表的图像。
您还可以看到第二个表,其中每个“STOP CODE”都有许多作为父级的“JOURNEYS”。据我所知,将多个旅程放入单个字段中不符合标准数据库设计,因此如果有人可以帮助我解决这个问题,我将非常感谢。
这些图像是在Microsoft的Excel中拍摄的,只是为了计划如何实现它,生产将使用MySQL数据库。

规范化,规范化,规范化 - Strawberry
1
因此,“normalize”在标题中 ;) - jskidd3
3个回答

5
你需要处理停靠点代码和行程之间的多对多关系,为了解决这个问题,你需要分解这种关系。
为了做到这一点,你需要一个中介表,让我们称之为 JourneyStopCode,它会长得像这样:
JourneyStopCode:
JourneyStopCodeID (primarykey)
JourneyID
StopCodeID

如果你的停止代码表中没有JourneyID字段。

要检索旅程的停止代码,您需要执行以下操作:

SELECT * FROM StopCode
INNER JOIN JourneyStopCode ON StopCode.StopCodeID = JourneyStopCode.StopCodeID
INNER JOIN Journey On Journey.JourneyID = JourneyStopCode.JourneyID
WHERE JourneyID = @yourJourneyID

编辑:可视化展示:

---------------        ---------------------         ----------------
|  Journey    |        | JourneyStopCode   |         |  StopCode    |
---------------        ---------------------         ----------------
| JourneyID   |<---    | JourneyStopCodeID |     --->|  StopCodeID  |
| Description |   |----| JourneyID         |     |   |  Latitude    |
---------------        | StopCodeID        |------   |  Longitude   |
                       ---------------------         ----------------

然后你的数据将会是这样的:

旅程

----------------------------------------
| JourneyID | Description              | 
----------------------------------------
| 34        | Southampton - Portsmouth |
----------------------------------------

停止代码
----------------------------------------
| StopID | Latitude | Longitude        | 
----------------------------------------
| SSDAFS | 12345    | 67890            |
----------------------------------------


JourneyStopCode

------------------------------------------
| JourneyStopID | JourneyID | StopCodeID | 
------------------------------------------
| 1             | 34        | SSDAFS     |
------------------------------------------

谢谢你的回答。你是在建议我只需要一个表吗?如果你能为我可视化你的答案,我会很感激的。我对数据库设计还不太熟悉,正在努力理解你的答案(这可能是正确的)。 - jskidd3
1
@JoelKidd 没问题!它基本上只是一个虚拟列,你可以将其用作主键,因为你无法使用其他字段作为主键(但你可以将它们都用作组合键,但我们不要走得太远 :))。如果您不想在表中使用主键,则可以将其删除,但最好的做法是始终有一个主键。 - Mathew Thompson
1
@mattytommo - Malcolm Birtle 会感到骄傲。 - Darren
1
@mattytommo - 谢谢。哈哈,是的,不好意思!Annette希望你使用左反半连接。 - Darren
1
@DarrenDavies 哈哈,我给 Reggie 打了电话讨论这个问题,他说我需要一个元素表。 - Mathew Thompson
显示剩余7条评论

3
旅程到停止代码是多对多的关系,您可能需要一个连接表。
Table 1 :
SID   |   Stop Code   |  Long    |   lat 
0     | ASDFSAFA      | 1        | 2
1     | sdDSGSDGS     | 4        | 0 
....

Table 2 : 
Journey   | Description 
0         | Blah blah blah


Table 3 : 
Journey  | SID 
0        |  1
2        |  1
1        |  4


SELECT A.Longitude, A.Latitude FROM TABLE1 WHERE A.SID IN (
    SELECT SID FROM TABLE3 WHERE JOURNEY = 0
);

除非停止代码更改,否则它们可以作为主键使用。 - Strawberry
你能否展示一个SQL查询,该查询将返回所有经过旅程为0的站点的纬度和经度值? - jskidd3
当然,使用子查询非常简单。我已经将其添加到我的答案中了。 - gbtimmon

0

试试这个:

    TABLE 1
    -------
    JOURNEY (PK) DESCRIPTION

    TABLE 2
    -------
    SEQUENCENO (PK) STOP_CODE LATITUDE LONGITUDE

    TABLE 3
    -------
    JOURNEY SEQUENCENNO 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接