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

时间:2016-02-19 09:45:09

标签: sql sql-server

道歉,这是SQL的一个基本部分,我确信这是一个之前被问过的问题,我只是找不到一个与我有关的例子让我理解它。我发现的几乎所有资源都是员工/经理关系,我认为我理解但不能适用于我的情况!

我正在使用MSSQL Server 2008.我正在创建一个包含3个表的数据库。它将用于一个简单的网络应用程序,允许人们记录他们在前面停车的车辆(因此阻塞),以便被阻挡车辆的车主知道如果他们想要移动车辆则联系谁。 / p>

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

见下文:

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.FirstNameCars.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 | 
+------------------+-----------+--------------+--------------------+

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

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

有人可以解释解决此类问题的最佳方法吗?

由于

2 个答案:

答案 0 :(得分:2)

正如@Arvo所说,你的架构看起来不错...... (例如,可能进行了一些小调整,我不确定你需要“parked_cars”表中的FK_People_Id字段,因为“People”表与“Cars”表格无关。)

如果您在使用NULL键时遇到问题,我建议您查看“OUTER JOINS”,如果您不熟悉该主题,请查看是否对您有帮助。

另外,请确保在编写包含“parked_cars”表的SELECT语句时,您可能想要调用“cars”表TWICE !!!

这是一个例子,(希望它能起作用):

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;

答案 1 :(得分:1)

基于评论以及其他类似内容,您必须稍微重新设计您的架构。

首先,不要在FK_Car_ID中使用People table,而是在FK_People_ID表格中使用Car。这解决了有多辆车的人的问题;相反的情况(汽车有多个所有者)是不太可能的。好吧,如果您需要指定所有可能的汽车用户,那么您必须创建“垃圾”#39;表(People_Car_Relation),链接到汽车和人。

其次,您根本不必在FK_people_ID表中使用Parked_Cars - 只需链接到Car即可。

第三,将主键字段设置为identity(1,1) - 这样他们就可以自行填充,而且您不必事先计算ID值。

然后记住 - 从不使用没有指定字段列表的插入语句。目前,您正在尝试插入具有特定(重复)主键值的记录,但该记录并不成功。

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

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

通过这种方式,您可以确保您的SQL代码完成了您打算执行的操作。