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你也一旦它让我,你的帮助是至关重要的。