2012-02-17 83 views
1

我正在处理包含汽车和所有者的表(表CO)。我正在创建另一个表来包含用户可以通过GUI分配的所有者属性(表OwnerAttributes)。我的问题在于,所有者不是唯一的,因为我使用的是SQL Server,我无法在其上创建外键。表格中有一个ID,但它将车辆和车主识别为一个整体。在SQL Server中创建具有非唯一列的外键

我必须解决这个问题的想法是创建一个包含不同的业主,然后添加一个触发器表CO将更新Owners任何变化的新表(表Owners)。然后我可以使用表Owners作为我的OwnerAttributes表,并解决我的问题。

我想回答的问题是,如果有更好的方法来做到这一点?

我正在使用一个预先存在的数据库,这是旧的应用程序大量使用。该应用程序被连接使用表CO为业主和汽车。还有其他几个表使用CO表。我希望我可以将表格拆分为OwnersCars,但该公司不希望我花费我所有的时间来完成这项工作,因为我需要添加更多功能以添加到应用程序中。

+1

听起来像您正在使用实体属性值模式设计[OwnerAttribute]表。也许有这里阅读关于这种方法的优点/缺点:http://stackoverflow.com/questions/870808/entity-attribute-value-database-vs-strict-relational-model-ecommerce-question – Kane 2012-02-17 23:07:49

+1

我写了一篇博客张贴关于它。不确定它是否与操作相关,但对于搜索EAV的人来说,值得一看(特别是随后的讨论):http://sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/what- is-so-bad-about-eav-anyway.aspx – 2012-02-17 23:23:20

回答

2

您对Owners表格的看法是正确的!你的问题是因为你的模式没有被标准化。这是你在一张桌子(你的桌子CO)里存储两件东西(汽车和所有者)的事实。

你是对的,你应该创建一个所有者表,但是你应该完全从CO表中除去所有者信息,并用一个外键替换为Owners表。

所以,你想是这样的:

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适当正常化。视图已将car_owner作为伪表中的一件东西提供给您。

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

希望这个答案似乎有帮助,而不是居高临下,这就是我要去的!我已经学会了这种方法(标准化所有事情,让数据库做一些额外的工作来检索/显示/插入它)是唯一一个最终解决问题的难题。

+0

经过与公司的首席开发人员的一些讨论后,决定这是要走的路,但由于时间的限制,我不会实施这个。修复和测试应用程序所花费的时间太长,以致获得的收益太少。 – Joshua5822 2012-02-21 20:40:40

2

您应该创建车主表,车表,车主车辆表(如果人员可以有几辆车)。所有者表格包含描述所有者的字段(所有者属性)

+1

如果Car只能由一个人拥有(看起来就是它的当前状态),则不需要OwnerCar表,只需将fk_owner添加到Car表 – 2012-02-17 23:13:51

+0

我正在使用一个现有的数据库,这是旧的应用程序大量使用。该应用程序被连接到使用表CO的业主和汽车。我希望我能把桌子分成车主和汽车,但公司不希望我花这么多时间。 – Joshua5822 2012-02-17 23:19:25

+0

您将创建上面的结构,然后使用CO表的旧名称创建一个视图。旧的代码仍然有效(但现在正在引用该视图),并且可以继续正确地调整事物。 – HLGEM 2012-02-17 23:45:19