SQL-дизайн, объединение типов и подтипов - PullRequest
2 голосов
/ 17 февраля 2012

Я делаю внешний интерфейс регистрации трафика, который позволяет отображать информацию о конкретном транспортном средстве, а также искать конкретное транспортное средство, но я не уверен, что лучший способ продолжить разработку моей базы данных , То, что я хочу сделать, это иметь возможность быстро получить все записи транспортного средства, основанные на типе транспортного средства и особенностях / подтипах этого транспортного средства. Я не знаю, как лучше всего ссылаться из моей записи об одном автомобиле на несколько подтипов / функций. Вот упрощенный пример:

У меня есть таблица для транспортных средств:

VehicleID, LicensePlate, TypeID, SubTypeIDs
1        ,   111111    ,   2   ,   ;2;;3;

Таблица для Типов транспортных средств:

TypeID, Type
  1   ,  Car
  2   ,  Semi

И таблица для VehicleSubTypes:

SubTypeID,  TypeID,   SubType
1        ,   1    ,   Coupe
2        ,   2    ,   Flat Bed
2        ,   2    ,   Sleeper

Поле Vehicles.Subtype - это varchar, в котором я в настоящее время просто делюнирую на Подтипы, которые ссылаются на VehicleSubTypes.SubTypeID ... Идея состоит в том, чтобы из внешнего интерфейса выбирать каждый SubTypeID при перечислении доступных опций и найдите строку SubType, на которую ссылаются (т. е. «Coupe»), для отображения пользователю, или, что более важно, при поиске Semi со спальным местом и плоской кроватью, чтобы включить SubTypes LIKE '%; 2;%' AND '% ; 3;% 'пункт, чтобы получить только транспортные средства, которые включают обе функции. Я только думаю об этом решении, хотя прямо сейчас, потому что я был в отпуске в течение года, и мой мозг останавливается на мне :) Я уверен, что это ужасный дизайн БД! Но что касается меня, я не могу придумать более правильного способа, и все мои усилия по поиску в Google продолжают приводить примеры подтипов, которые просто не применяются, или я упускаю сходство с (т. Е. Люди с несколькими наборами контактов информация .. люди, очевидно, должны быть одной таблицей, контактная информация, очевидно, должна быть другой, они связываются по personID и т. д. и т. д.)

EDIT / Вывод:

Спасибо Борту за то, что он потряс мою память и указал мне на таблицу ссылок. Я сейчас добавил таблицу, Link_VehicleToSubTypes:

linkID, VehicleID, SubTypeID
  1   ,   1      ,    2
  2   ,   2      ,    10     //10 = Cargo (Semi)
  3   ,   2      ,    15     //15 = No Sleeper

Кроме того, я создал следующую хранимую процедуру для возврата идентификаторов транспортных средств для транспортных средств, которые соответствуют всем параметрам (до 10), которые я ему передал, - таким образом я позже смогу объединить эту информацию с результатами поиска по моим транспортным средствам. таблица, которая включает в себя информацию о транспортном средстве, такую ​​как 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, когда у меня будет достаточно очков для этого! Ваша помощь очень ценится!

Ответы [ 2 ]

2 голосов
/ 17 февраля 2012

Поскольку хранить несколько значений в одном столбце, как вы, с помощью SubTypes - это почти всегда плохая идея (необходимо сделать LIKE '%;2;%' AND LIKE '%;3;%' - это огромный красный флаг), если я правильно понял ваши требования, это выглядит какмного взаимосвязей, которые обычно включают в себя перекрестную таблицу для связи двух сущностей, в данном случае Транспортные средства и подтипы.

Если вы удалили SubTypeIDs из таблицы транспортных средств и создали таблицу ссылок Vehicle_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(*) = количество выбранных подтипов,Таким образом, автомобиль имеет их все.Тем не менее, кажется, что должен быть лучший путь, я буду думать об этом.

0 голосов
/ 17 февраля 2012

Я бы сделал что-то вроде этого:

  • A Таблица транспортных средств с колонками ID автомобиля, LicencePlate и TypeID (FK).Идентификатор транспортного средства - PK.
  • Таблица VehicleSubTypes со столбцами TypeID, SubTypeID и SubType.TypeID и SubTypeID являются таблицами PK
  • A VehicleFeatures со столбцами Vehicle ID (FK), TypeID и SubTypeID.TypeID и SubTypeID являются FK для VehicleSubTypes.Ваш PK может быть сгенерирован автоматически.

С этим дизайном и некоторым SQL вы можете получить нужные данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...