代码之家  ›  专栏  ›  技术社区  ›  Syntax Error ine

创建外键时,是否还需要包含链接表中的字段?

  •  1
  • Syntax Error ine  · 技术社区  · 9 年前

    抱歉,这是SQL的一个非常基本的部分,我相信这是一个以前被问过的问题,我只是找不到一个与我的例子足够相关的例子,我无法理解它。我找到的几乎所有资源都是像员工/经理关系这样的东西,我认为我能理解,但不能适用于我的情况!

    我正在使用MSSQL Server 2008。我正在创建一个包含3个表的数据库。它将用于一个简单的网络应用程序,允许人们记录他们在哪些车前双停(从而堵车),以便被堵车的车主知道如果他们想移动汽车,应该联系谁。

    • 汽车-关于人们汽车的详细信息。
    • 人-至少可以拥有一个 汽车
    • 停车场-这就是我被困的地方。

    见下文:

    CREATE TABLE dbo.Cars
    (
      Pk_Car_Id INT PRIMARY KEY,
      Manufacturer VARCHAR(55),
      Model VARCHAR(55),
      Colour VARCHAR(50),
      RegistrationNo VARCHAR(10) 
    );
    
    CREATE TABLE dbo.People
    (
      Pk_People_Id INT PRIMARY KEY,
      FirstName     VARCHAR(55),
      LastName    VARCHAR(55),
      Extension INT,
      Fk_Car_Id   INT FOREIGN KEY REFERENCES Cars(Pk_Car_Id)
    );
    
    CREATE TABLE dbo.ParkedCars 
    (
      PK_ParkedCars_Id INT PRIMARY KEY,
      FK_Car_Id INT FOREIGN KEY REFERENCES dbo.Cars(Pk_Car_Id),
      FK_People_Id INT FOREIGN KEY REFERENCES dbo.People(Pk_People_Id),
      DateParked datetime
    );
    

    我的问题是——创建 ParkedCars 桌子,我需要参考像这样的东西吗 people.FirstName Cars.RegistrationNo 作为自己的专栏?或者,我可以像上面所做的那样,只创建外键列吗?因此,当填充数据时,表格可能看起来像这样:

    +------------------+-----------+--------------+--------------------+
    | PK_ParkedCars_Id | FK_Car_Id | FK_People_Id | DateParked         | 
    +------------------+-----------+--------------+--------------------+
    | 2                | 1         | 5            | 19/2/2016 08:33:00 | 
    +------------------+-----------+--------------+--------------------+
    | 3                | 4         | 2            | 19/2/2016 08:48:33 | 
    +------------------+-----------+--------------+--------------------+
    

    然后我可以从每个表中选择相关字段并显示结果。

    我确实尝试过类似的方法,但每次我尝试插入任何数据时,都会卡住,因为在插入特定行时,其中一个键被设置为空。它不允许在任何表中插入任何进一步的数据。

    请有人解释一下处理这种事情的最佳方法吗?

    谢谢

    2 回复  |  直到 9 年前
        1
  •  2
  •   DougieHauser    9 年前

    正如@Arvo所说,你的模式看起来不错。。 (例如,如果稍作调整,我不确定您是否需要“parked_cars”表中的FK_People_Id字段,因为“People”表无论如何都与“cars”表相关)。

    如果您在使用NULL键时遇到问题,如果您还不熟悉这个主题,我建议您查看“外部连接”,看看这是否对您有帮助。

    此外,请确保在编写包含“parked_cars”表的SELECT语句时,您可能需要两次调用“cars”表!!!

    下面是一个例子(希望它能起作用):

    SELECT parked.ParkedCars_id, c1.RegistrationNo, p1.FirstName, p1.LastName,
           parked.Fk_Car_id, c2.RegistrationNo, p2.FirstName, p2.LastName
    FROM dbo.ParkedCars AS parked
    LEFT OUTER JOIN dbo.Cars c1
     ON parked.ParkedCars_Id = c1.Pk_Car_Id
    LEFT OUTER JOIN dbo.People p1
     ON c1.Pk_Car_Id = p1.Fk_Car_Id
    LEFT OUTER JOIN dbo.Cars c2
     ON parked.Fk_Car_Id = c2.Pk_Car_Id
    LEFT OUTER JOIN dbo.People p2
     ON c2.Pk_Car_Id = p2.Fk_Car_Id;
    
        2
  •  1
  •   Arvo    9 年前

    根据注释和其他看起来不需要的内容,您必须重新设计您的模式。

    首先,不要使用 FK_Car_ID 在里面 People table ,但使用 FK_People_ID 在里面 Car 桌子这为拥有多辆车的人解决了问题;相反的情况(汽车有多个车主)不太可能发生。如果你需要指定该车的所有可能用户,那么你必须创建“垃圾”表( People_Car_Relation ),连接到汽车和人。

    其次,你不必使用 FK_people_ID 在里面 Parked_Cars 表-它足以链接到 汽车 只有

    第三,将主键字段创建为 identity(1,1) -这样它们就可以填充自己,而且您不必预先计算ID值。

    然后请记住,不要在没有指定字段列表的情况下使用insert语句。当前,您正试图插入具有特定(重复)主键值的记录,但未成功。

    始终使用下一个语法进行插入:

    insert into dbo.parkedcars(fk_car_id, fk_people_id, dateparked) values(...)
    

    这样,您可以确保您的SQL代码实现了您想要的功能。