Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL Server中创建具有非唯一列的外键_Sql_Sql Server 2008 - Fatal编程技术网

在SQL Server中创建具有非唯一列的外键

在SQL Server中创建具有非唯一列的外键,sql,sql-server-2008,Sql,Sql Server 2008,我正在处理一个同时包含汽车和车主的表(表CO)。我正在创建另一个表,其中包含用户可以通过GUI分配给的所有者属性(tableOwnerAttributes)。我的问题在于所有者不是唯一的,因为我使用的是SQL Server,所以无法在其上创建外键。表中有一个id,但它将汽车和车主作为一个整体进行标识 我绕过这个问题的想法是创建一个包含不同所有者的新表(表Owners),然后向表CO添加一个触发器,该触发器将使用任何更改更新所有者。然后,我可以使用表OwnerAttributes为我的OwnerA

我正在处理一个同时包含汽车和车主的表(表
CO
)。我正在创建另一个表,其中包含用户可以通过GUI分配给的所有者属性(table
OwnerAttributes
)。我的问题在于所有者不是唯一的,因为我使用的是SQL Server,所以无法在其上创建外键。表中有一个id,但它将汽车和车主作为一个整体进行标识

我绕过这个问题的想法是创建一个包含不同所有者的新表(表
Owners
),然后向表
CO
添加一个触发器,该触发器将使用任何更改更新
所有者。然后,我可以使用表
OwnerAttributes
为我的
OwnerAttributes
表解决我的问题

我想回答的问题是,是否有更好的方法


我使用的是一个预先存在的数据库,它被一个旧的应用程序大量使用。将该应用程序连接起来,以便为车主和汽车使用表
CO
。还有其他几个表使用了
CO
表。我希望我可以将表分为
所有者
汽车
,但公司不希望我把所有的时间都花在这上面,因为我还需要向应用程序添加更多的功能。

你应该创建所有者表、汽车表、所有者卡表(如果一个人可以拥有几辆汽车的话)。所有者表包含描述所有者(所有者属性)的字段。

您应该创建所有者表、汽车表、所有者卡表(如果用户可以拥有几辆汽车)。所有者表包含描述所有者(所有者属性)的字段。

您对所有者表的看法是正确的!您的问题是因为您的模式没有规范化。事实上,您在一张表(您的表CO)中存储了两件东西(汽车和车主)

您应该创建一个所有者表,这是正确的,但是您应该完全从CO表中删除所有者信息,并将其替换为所有者表的外键

所以你想要这样的东西:

CREATE TABLE Owner (
  ownerID int not null primary key indentity(1,0),
  FirstName varchar(255),
  LastName varchar(255),
  /* other fields here */
)
GO
CREATE TABLE Car
  carID int not null primary key identity(1,0),
  ownerID int not null references Owner(ownerID),
  /* other fields go here */
GO

/* a convenience, read only view to replace your old CAR OWNER table */
CREATE VIEW Car_Owner AS
  SELECT c.*, o.FirstName, o.LastName FROM Car c INNER JOIN Owner o ON c.ownerID = o.ownerID
现在,您已经在SQL中正确地规范化了所有内容。一个视图将车主作为一件事返回到一个伪表中

但真正的答案是,规范化您的模式。让SQL做它最擅长的事情(将事情与其他事情联系起来)。将这两件事放在一张桌子上只会导致更多的问题,比如你在下游遇到的问题


希望这个答案看起来很有帮助,而不是居高临下,这正是我想要的!我通过艰苦的努力了解到,这种方法(规范化所有内容,让数据库做一些额外的工作来检索/显示/插入它)是最后唯一有效的方法。

您对Owners表的想法是正确的!您的问题是因为您的模式没有规范化。事实上,您在一张表(您的表CO)中存储了两件东西(汽车和车主)

您应该创建一个所有者表,这是正确的,但是您应该完全从CO表中删除所有者信息,并将其替换为所有者表的外键

所以你想要这样的东西:

CREATE TABLE Owner (
  ownerID int not null primary key indentity(1,0),
  FirstName varchar(255),
  LastName varchar(255),
  /* other fields here */
)
GO
CREATE TABLE Car
  carID int not null primary key identity(1,0),
  ownerID int not null references Owner(ownerID),
  /* other fields go here */
GO

/* a convenience, read only view to replace your old CAR OWNER table */
CREATE VIEW Car_Owner AS
  SELECT c.*, o.FirstName, o.LastName FROM Car c INNER JOIN Owner o ON c.ownerID = o.ownerID
现在,您已经在SQL中正确地规范化了所有内容。一个视图将车主作为一件事返回到一个伪表中

但真正的答案是,规范化您的模式。让SQL做它最擅长的事情(将事情与其他事情联系起来)。将这两件事放在一张桌子上只会导致更多的问题,比如你在下游遇到的问题


希望这个答案看起来很有帮助,而不是居高临下,这正是我想要的!我了解到,这种方法(规范化一切,让数据库做一些额外的工作来检索/显示/插入它)是最后唯一可行的方法。

听起来像是在使用实体属性值模式设计[OwnerAttribute]表。也许你可以在这里了解一下这种方法的优缺点:我也写了一篇关于它的博客文章。不确定它是否与op相关,但对于搜索EAV的任何人来说,它可能值得一看(特别是随后的讨论):听起来您正在使用实体属性值模式设计[OwnerAttribute]表。也许你可以在这里了解一下这种方法的优缺点:我也写了一篇关于它的博客文章。不确定它是否与op相关,但对于搜索EAV的任何人来说,它可能值得一看(特别是随后的讨论):如果一辆车只能由一个人拥有(似乎是当前状态),您不需要OwnerCar表,只需将fk_owner添加到Car表我使用的是一个现有数据库,它被一个旧的应用程序大量使用。该应用程序被连接起来,以便为车主和汽车使用表格CO。我希望我可以将表拆分为车主和汽车,但公司不希望我把所有的时间都花在这方面。您可以创建上面的结构,然后使用CO表的旧名称创建一个视图。旧代码仍然有效(但现在正在引用视图),并且可以继续正确地更改。如果一辆车只能由一个人拥有(似乎是当前状态),则不需要OwnerCar表,只需将fk_owner添加到Car表中即可。我正在使用一个旧应用程序大量使用的现有数据库。该应用程序被连接起来,以便为车主和汽车使用表格CO。我希望我可以将表拆分为车主和汽车,但公司不希望我把所有的时间都花在这方面。您可以创建上面的结构,然后使用CO表的旧名称创建一个视图。旧的代码仍然有效(但现在正在引用视图),继续下去,你可以适当地改变事情。在与该公司的首席开发人员讨论后,决定采用这种方式,但由于时间限制,我不会实施这种方式。修复和测试应用程序所需的时间太长,而gai太少