SQL设计、连接类型和子类型

SQL设计、连接类型和子类型,sql,one-to-many,subtype,Sql,One To Many,Subtype,我正在制作一个交通记录前端,它允许在酒店中显示特定车辆的信息以及搜索特定车辆,但我不确定继续数据库设计的最佳方式。我想做的是能够根据车辆类型和该车辆的功能/子类型快速调出所有车辆记录。我不知道如何最好地从我的单一车辆记录中引用多个子类型/功能。下面是一个简化的示例: 我有一张供车辆使用的桌子: VehicleID, LicensePlate, TypeID, SubTypeIDs 1 , 111111 , 2 , ;2;;3; 车辆类型表: TypeID,

我正在制作一个交通记录前端,它允许在酒店中显示特定车辆的信息以及搜索特定车辆,但我不确定继续数据库设计的最佳方式。我想做的是能够根据车辆类型和该车辆的功能/子类型快速调出所有车辆记录。我不知道如何最好地从我的单一车辆记录中引用多个子类型/功能。下面是一个简化的示例:

我有一张供车辆使用的桌子:

VehicleID, LicensePlate, TypeID, SubTypeIDs
1        ,   111111    ,   2   ,   ;2;;3;
车辆类型表:

TypeID, Type
  1   ,  Car
  2   ,  Semi
和车辆子类型表:

SubTypeID,  TypeID,   SubType
1        ,   1    ,   Coupe
2        ,   2    ,   Flat Bed
2        ,   2    ,   Sleeper
Vehicles.Subtype字段是一个varchar,我目前正在删除引用VehicleSubTypes.SubjectID的子类型。。。这样做的目的是,在列出可用选项时,从前端挑出每个子类型ID,并查找要向用户显示的引用子类型字符串(即“Coupe”),更重要的是,在搜索带有卧铺和平板的半成品时,要包括像“%”这样的子类型;2;%' 及“%”;3;%' 子句仅获取包含这两个功能的车辆。我现在只想到这个解决方案,因为我已经度假一年了,我的大脑对我迟钝了:)我确信这是一个糟糕的DB设计!但就我的一生而言,我想不出一个更合适的方式,我在谷歌上的所有努力都在不断地寻找不适用的子类型示例,或者我缺少与(例如,拥有多组联系信息的人……人显然应该是一张表,联系信息显然应该是另一张表,他们通过personID链接,等等)的相似性

编辑/结论:

感谢Bort打乱了我的记忆并将我指向链接表。我现在添加了一个表,Link_VehicleToSubTypes:

linkID, VehicleID, SubTypeID
  1   ,   1      ,    2
  2   ,   2      ,    10     //10 = Cargo (Semi)
  3   ,   2      ,    15     //15 = No Sleeper
此外,我还创建了以下存储过程,以返回与我传递给它的所有参数(最多10个)匹配的车辆的VehicleID-这样,我可以在以后根据搜索我的vehicles表(包括车辆特定信息,如vehicle.Color)的结果加入此信息,从而过滤最终结果集:

ALTER PROCEDURE dbo.ReturnVehicleIDsMatchingSubTypes

    (
    @SubType1 int = NULL,
    @SubType2 int = NULL,
    @SubType3 int = NULL,
    @SubType4 int = NULL,
    @SubType5 int = NULL,
    @SubType6 int = NULL,
    @SubType7 int = NULL,
    @SubType8 int = NULL,
    @SubType9 int = NULL,
    @SubType10 int = NULL
    )

AS
    DECLARE @intNumberSubTypesToMatch int SET @intNumberSubTypesToMatch = 
    (SELECT COUNT(@SubType1) 
            + COUNT(@SubType2) 
            + COUNT(@SubType3) 
            + COUNT(@SubType4)
            + COUNT(@SubType5)
            + COUNT(@SubType6)
            + COUNT(@SubType7)
            + COUNT(@SubType8)
            + COUNT(@SubType9)
            + COUNT(@SubType10))

    SELECT  VehicleID
    FROM    Link_VehicleToSubTypes
    WHERE
            SubTypeID IN (@SubType1, @SubType2, @SubType3, @SubType4, @SubType5, @SubType6, @SubType7, @SubType8, @SubType9, @SubType10)
    GROUP BY VehicleID
    HAVING        (COUNT(*) = @intNumberSubTypesToMatch)

    RETURN

我已经测试过了,效果很好。我的存储过程实现可能有点不稳定(我以前从未计算过非空参数,我想到的就是这个方法),但它可以工作。博特-当我有足够的分数时,我会+1你!非常感谢你的帮助

我会这样做:

  • 包含车辆ID、LicensePlate和TypeID(FK)列的车辆表。车辆ID为PK
  • 包含列TypeID、SubsubId和SubType的VehicleSubTypes表。类型ID和子类型ID是PK的
  • 包含车辆ID(FK)、类型ID和子类型ID列的VehicleFeatures表。TypeID和SubjectID是FK到Vehicles子类型。您的PK可以自动生成

通过这种设计和一些SQL,您可以获得所需的数据。

因为像子类型一样在一列中存储多个值几乎总是一个坏主意(需要像“%$2;”和“%$3;”这样做
,这是一个巨大的危险信号),如果我正确理解了您的需求,这看起来像是一个多对多关系,这通常涉及一个交叉表来链接两个实体,在本例中是车辆和子类型

如果从车辆表中删除了子类型ID,并创建了链接表Vehicle\u Subtypes

VehicleID   SubTypeID
1           2
1           3
然后,您就可以编写查询来获取给定车辆的适当子类型,如

SELECT S.SubType FROM SubTypes S
    INNER JOIN Vehicle_Subtypes X ON X.SubTypeID = S.SubTypeID
WHERE X.VehicleID = @VehicleId
可能需要更多的逻辑来解释TypeID,但这似乎是正确的设计

编辑:我把它全部收回。误解了从子类型到交通工具的部分,在我的脑海中倒转过来。换一种方式更难,找到满足各种条件的记录可能很棘手。给定相同的链接表(假设您对生成的SQL有很大的控制权),您可以编写有点粗糙的查询

SELECT VehicleId FROM Vehicle_Subtypes 
WHERE SubTypeId IN (1, 2)
GROUP BY VehicleId
HAVING COUNT(*) = 2

您必须确保所选子类型的数量
COUNT(*)=
。不过,我觉得应该有更好的方法,我会继续考虑。

+1因为你肯定这是一个糟糕的设计。确实是这样的(subdivids
列:)参见本文中的车辆示例:(他在几个新闻组线程中对此进行了扩展,例如。)。这绝对是正确的。“链接表”是我的大脑在一年的不工作中似乎误放的关键概念;)我正在为此进行修改和适当的测试,我相信这是正确的设计。我现在只需要把实现整合起来,哈哈。。。嗯,我现在已经把这些都弄明白了,但因为我是新来的,所以不会让我“太快”给出答案。。。但我有一个很好的结论,三个多小时后就可以得出;)将包括我提出的SP,使之成为输入值和期望返回正确结果的简单问题。博特-我肯定会+1你也一旦它让我,你的帮助是至关重要的。