Модель проектирования БД для бесконечной общей и уникальной классификации элементов - PullRequest
3 голосов
/ 21 января 2012

По сути, я хотел бы создать структуру базы данных, которая позволяет классифицировать бесконечное количество предметов инвентаря бесконечным количеством способов, однако многие из этих предметов имеют определенные «черты» . Взять, к примеру, Cars и Trucks:

  • Оба могут быть только red или blue.
    • Любой цвет автомобиля / грузовика может быть 2wd или 4wd.
      • Cars может иметь manual или automatic передачу.
      • Trucks может иметь cloth или leather мест
      • и т.д ....

Чего я хотел бы избежать, так это ручного ввода всех возможных комбинаций, которые существуют. С 5 цветами и 5 транспортными средствами, это уже 25 записей и нет классификаций набора функций.

Существует ли модель данных, которая учитывает эти отношения и общие «группы признаков», или, что более важно, модель, которая допускает одну ссылку на каждую возможную комбинацию любого набора данных, который я могу себе представить? Любая помощь будет принята с благодарностью.

Обновлено [2012-01-23]

Позвольте мне быть как можно более конкретным. Моя главная цель - отслеживать использование материалов. на рабочих местах, которые мы делаем для бюджетных и исторических целей. Некоторые материалы, то есть шипы и дорожка , будут иметь те же подклассификации, с дорожка , имеющая 3-ю подклассификацию. Некоторые будут полностью различные подклассификации. Предположим следующее.

  • 5 возможно metal_widths
  • 5 возможно metal_gagues
  • 4 возможно track_types
  • 5 возможно insulation_widths
  • 3 возможно insulation_types

... отношения ( возможные комбинации ):

  • Studs> metal_widths> metal_gagues ( 25 )
  • Track> metal_widths> metal_gagues> track_types ( 100 )
  • Insulation> insulation_widths> insulation_types ( 15 )

Просто чтобы понять мою конечную цель, рабочий процесс приложения будет как то так:

  1. Создать работу.
  2. Создание бюджета на работу.
    • Установите сумму бюджета / стоимость для каждого материала, который я ожидаю использовать.
  3. Начните вводить материальные счета.
    • Укажите сумму / стоимость для каждого материала в счете.
  4. Отслеживание / проверка моих сметных и фактических расходов.

Я думаю, что цель моего бюджета против стоимости приложения довольно проста, Я просто хочу, чтобы дизайн базы данных по материалам был корректным, прежде чем Движение вперед. Я понимаю, что самым простым решением было бы создать единый введите для каждой возможной комбинации в таблицу material и ограничьте база данных на n количество возможных черт. Проблема в том, что когда я решаю добавить x width стад, я также хочу добавить x width трек, что означает У меня есть увеличены возможные комбинации на 30 , поэтому требуют 30 дополнительные записи (которых я действительно предпочел бы избежать).

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

Ответы [ 7 ]

5 голосов
/ 29 января 2012

Ты имеешь в виду что-то подобное?

enter image description here

Эта простая модель позволяет группировать признаки вместе, а затем «применять» целую группу признаков к произвольному количеству элементов (таблица ITEM_TRAIT_GROUP является типичным примером того, как отношение M: N может быть представленными в реляционной парадигме). Если ваша главная задача состоит в том, чтобы избежать повторения посредством «повторного использования» черт, эта модель может соответствовать всем требованиям.

Это, однако, не принудительно приведет:

  1. любая конкретная группа признаков для конкретного вида предмета (например, автомобили, для которых требуется цвет), или какая-либо конкретная связь между признаками (например, материал сиденья, который должен сочетаться с цветом сиденья),
  2. и не будет ограничивать значения для какой-либо конкретной черты (например, цвет должен быть «красным» или «синим», но не, например, «зеленым»).

(1) и (2) потребовали бы некоторой системы типов и даже «наследования» (в смысле ООП), что неинтересно в реляционной парадигме. Если вам это действительно нужно, вам, вероятно, лучше применять такую ​​логику на клиентском или среднем уровне.

(3) может быть разумно смоделировано реляционно, но не без усложнения модели, которая может стоить или не стоить усилий.

1 голос
/ 27 января 2012

Я не уверен, что понимаю, что вы имеете в виду под "поэтому требуется 30 дополнительных записей". Вам не нужно вводить все комбинации явно, если они на самом деле не несут информацию. Например, если у вас есть прайс-лист поставщика со всеми ценами, то у вас будет 30 дополнительных строк с новой ценой в каждой. Но это не то, что вы хотите. Похоже, вам нужна запись по бюджетной и последующей стоимости счета для всех предметов, составляющих работу.

Давайте попробуем решить проблему простым способом:

METAL_WIDTH
id | unit | amount | displaytext
 1 |  mm  |   10   |  2/5 in
 2 |  mm  |   15   |  3/5 in
 3 |  mm  |   20   |  4/5 in
 4 |  mm  |   25   |  1 in
 5 |  mm  |   30   |  1 1/5 in

METAL_GAUGE...
TRACK_TYPE...
INSULATION_WIDTH...
INSULATION_TYPE...

я пропустил детали четырех других таблиц, их структура аналогична METAL_WIDTH

JOB
id | name
 1 | test job


BUDGET_ITEM
id | job_id | type | metal_width_id | metal_gauge_id | track_type_id | insulation_width_id | insulation_type_id | price_in_dollar
1  |    1   | STUD |       1        |      1         |    null       |      null           |     null           |    50

INVOICE_ITEM
id | job_id | type | metal_width_id | metal_gauge_id | track_type_id | insulation_width_id | insulation_type_id | price_in_dollar
1  |    1   | STUD |       1        |      1         |    null       |      null           |     null           |    49.95

Здесь я сделал отдельные таблицы INVOICE_ITEM и BUDGET_ITEM, потому что я чувствую, что вы, вероятно, захотите использовать INVOICE_ITEM не только для контроля бюджета. Но вы можете выбросить все элементы в одну большую таблицу JOB_ITEMS. Возможно и обратное: вы можете создать таблицу STUD_PRICE, TRACK_PRICE и INSULATION_PRICE. Больше таблиц означает, что запросы становятся длиннее, но теперь вы можете хранить информацию о том, что STUD могут иметь только свойства METAL_GAUGE и METAL_WIDTH:

STUD_PRICE
id | job_id | purpose | metal_width_id | metal_gauge_id | price
 1 |    1   | BUDGET  |       1        |       1        |  50
 2 |    1   | INVOICE |       1        |       1        |  49.95

И теперь вы, вероятно, заметите, что у вас есть избыточность: один и тот же стержень вводится дважды, что станет проблемой, если вы захотите сравнить бюджет и счет-фактуру и иметь более одного стержня в работе:

STUD_PRICE
id | job_id | purpose | metal_width_id | metal_gauge_id | price
 1 |    1   | BUDGET  |       1        |       1        |  50
 2 |    1   | INVOICE |       1        |       1        |  49.95
 3 |    1   | BUDGET  |       1        |       2        |  75
 4 |    1   | INVOICE |       1        |       2        |  89.95

К какому счету сейчас принадлежит БЮДЖЕТ? Вы один опечатка от интересной проблемы. Так что вы, вероятно, лучше с:

STUD_ITEM
id | job_id | metal_width_id | metal_gauge_id | budget_price | invoice_price
 1 |    1   |       1        |       1        |  50          |   49.95
 2 |    1   |       1        |       2        |  75          |   null

где null означает «еще не выставлен счет», и как только вы окажетесь там, вы можете взять таблицы BUGET_ITEM и INVOICE_ITEM сверху и объединить их в JOB_ITEM

JOB_ITEM
id | job_id | type | metal_width_id | metal_gauge_id | track_type_id | insulation_width_id | insulation_type_id | budget_price | invoice_price
1  |    1   | STUD |       1        |      1         |    null       |      null           |     null           |    50        | 49.95

Ваше приложение позволит вам создать новую работу, установить ее атрибуты, а затем добавить элементы в свой бюджет. Вы можете сказать «Новый предмет ...» и выбрать между STUD, TRACK и INSULATION. Выбрав STUD, вы получите меню с разрешенными METAL_WIDTH, другое с разрешенными METAL_GAUGE. Вы выбираете их, устанавливаете бюджетную цену и сохраняете товар. Повторите по мере необходимости. Как только вы доберетесь до стадии выставления счета, вы выбираете сохраненный товар и устанавливаете цену счета. Сравнение бюджета / счета-фактуры выполняется путем просмотра всех позиций в задании, добавления всех бюджетных цен для прогнозируемого общего бюджета и добавления всех счетов-фактур к фактической общей сумме счета-фактуры, с бонусными баллами за то, что они также отображают бюджетную стоимость только для тех позиций, для которых invoice_price не является нулевым.

Чтобы создать текст для счета-фактуры, вам просто нужно объединить содержимое столбцов отображаемого текста, тем самым сохраняя необходимость в строке для каждого из «Стад - 2/5 в - 10га» до «Стад - 1 1/5» в - 18га ". Если вы сейчас добавите METAL_WIDTH, все, что вам нужно сделать, это добавить одну строку в таблицу METAL_WIDTH, и все будет хорошо.

0 голосов
/ 31 января 2012

Я подхожу к этому, моделируя элементы (и кавычки) как объекты с типом, и определяя черты, используя пары ключ-значение. Показывая таблицы в следующем примере и игнорируя такие вещи, как первичные ключи:

Сначала создайте таблицу всех допустимых пар ключ-значение:

VALID_KEY_VALUES
| key             | value   |
=============================
| metal_width     | mwidth1 |
| metal_width     | mwidth2 |
...
| insulation_type | itype3  |

Это соответствует вашему требованию, если вам нужно добавить новый metal_width, то это одна вставка в эту таблицу. (В настоящее время в вашем примере 22 строки).

Теперь есть таблица допустимых ключей для каждого типа:

VALID_TYPE_KEYS
| type       | key              |
=================================
| stud       | metal_width      |
| stud       | metal_gauge      |
| track      | metal_width      |
| track      | metal_gauge      |
| track      | track_type       |
| insulation | insulation_width |
| insulation | insulation_type  |

Теперь предмет (или цитата) определяется двумя таблицами, во-первых, предметами по ID:

ITEMS
| ID | type | .... whatever columns you need ...
================================================
| 1  | stud | ..................................

А теперь «черты» этого предмета:

ITEM_TRAITS
| itemID | type | key         | value   |
=========================================
| 1      | stud | metal_width | mwidth1 |
| 1      | stud | metal_gauge | mgauge2 |

(Это немного денормализовано, потому что каждая строка содержит itemID и type из таблицы ITEMS, но мы можем жить с этим на данный момент). Другими словами, пункт 1 представляет собой шпильку с metal_width=mwidth1, metal_gauge=mgauge2.

Вы можете соединить все это вместе, используя внешние столбцы из нескольких столбцов из таблицы ITEM_TRAITS.

(itemID, type) is a foreign key into the ITEMS table
(type, key) is a foreign key to the VALID_TYPE_KEYS table
(key, value) is a foreign key to the VALID_KEY_VALUES table

Это похоже на хорошее начало того, что вам нужно. Если вам нужно добавить новый тип, новую черту или новое значение черты, это делается с минимальным количеством вставок. Ваши цитаты могут быть сделаны аналогично, с таблицами QUOTES и QUOTE_TRAITS. Вы можете сопоставлять элементы с кавычками по объединениям, подсчитывая, сколько признаков совпадают между элементом и цитатой (и сравнивая это с общим количеством признаков для данного типа).

Вам может потребоваться выполнить некоторую работу с клиентом, перебирая все ключи для данного типа, чтобы убедиться, что все необходимые данные введены, и это предполагает, что каждая из ваших «комбинаций» действительна. (Если у вас do есть ситуация, когда некоторые комбинации являются действительными, а некоторые нет, то вы не сможете избежать перечисления их всех). Это также предполагает, что логики «детализации» также нет, что указание одной черты не ограничивает значения более поздних, но вы даже можете расширить эту идею и в этом случае (при условии, что ваши требования не * 1034) * тоже безумно).

0 голосов
/ 31 января 2012

СУБД является требованием? Не могли бы вы вместо этого использовать graphDB как Neo4j ?

0 голосов
/ 27 января 2012

Когда я работал в Onan, и им приходилось отслеживать допустимые конфигурации генераторных установок, они использовали две таблицы: «должны использовать» и «не разрешены».

Итак, учитывая ваш пример:

cars and trucks,
    Both can be red or blue only.
    Either color car/truck can be 2wd or 4wd.
        Cars can have manual or automatic transmission.
        Trucks can have cloth or leather seats

в таблице «необходимо использовать», будут такие правила, как

object | attribute | mustUse1 | orMustUse2

car | color | red | blue
truck | color | red | blue
car | wd | 2wd | 4wd
truck | wd | 2wd | 4wd
car | transmission | manual | automatic
truck | seats | cloth | leather

В вашем случае, если у вас естьмного дубликатов, вы, вероятно, могли бы хранить отношения более высокого уровня, например cars и trucks - это autos, а затем в таблице «необходимо использовать» просто есть

auto | color | red | blue
auto | wd | 2wd | 4wd
car | transmission | manual | automatic
truck | seats | cloth | leather

Кроме того, я не уверен, почему возможные комбинации вешают вас.Дано

    5 possible metal_widths
    5 possible metal_gagues
    4 possible track_types
    5 possible insulation_widths
    3 possible insulation_types

...the relationships (possible combinations):

    Studs > metal_widths > metal_gagues (25)
    Track > metal_widths > metal_gagues > track_types (100)
    Insulation > insulation_widths > insulation_types (15)

Иметь таблицу для metal_widths с 5 строками, metal_gauges с 5 строками, studs с metal_widthID и metal_gaugeID, track с (studID?) И track_typeID, иinsulation с изоляцией_widthID и изоляцией_типа ID.

Если вы не чувствуете, что ваш опыт адекватен модели, а затем применяете данные, вы можете попросить кого-то еще сделать это.

0 голосов
/ 24 января 2012

Я не уверен, что вы подразумеваете под "едиными контрольными точками для каждой возможности".

Вы могли бы просто ввести свои данные в широкий столбец varchar (), как

  • Шпилька, 8 мм, 8 га
  • Шпилька, 10 мм, 8 га
  • Шпилька, 12 мм, 6 га
  • дорожка, 8 мм, 8 га, тип 1
  • дорожка, 10 мм, 8 га, тип 2

Для этого не требуется вводить что-либо заранее, и он обеспечивает максимальную гибкость, хотя эта гибкость достигается ценой целостности данных. (Или увеличение административных издержек из-за постоянного просмотра записей на наличие ошибок.) Это также может усложнять отчеты. Например, отчет только о 8 калибровочных шпильках является более сложным.

Готовые системы бухгалтерского учета, которые уже запрограммированы для работы с бюджетами, сметами и счетами, обычно требуют, чтобы вы хранили запасы именно таким образом.

Предполагая, что вы уже приняли осознанное и осознанное решение не использовать для этого свою учетную систему, что вы просто не будете хранить значения таким образом, а вместо этого захотите большей целостности данных, которая сопровождается ограничениями внешнего ключа , может иметь смысл генерировать наборы автоматически.

-- This table will be used as a foreign key reference for tracks. 
-- Adjust the CHECK() constraints for your actual values. If you're using MySQL,
-- replace the CHECK() constraints with foreign key references to separate tables.
--
create table studs (
  metal_width_mm integer not null check (metal_width_mm between 5 and 10),
  metal_gauge integer not null check (metal_gauge between 8 and 16),
  primary key (metal_width, metal_gauge)
);

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

insert into studs
with gauge as (
  select 8 as metal_gauge
  union all
  select 10
  union all
  select 12
  union all
  select 14
  union all
  select 16
),
width as (
  select 5 as metal_width_mm
  union all
  select 6
  union all
  select 7
  union all
  select 8
  union all
  select 9
  union all
  select 10
)
select * 
from width, gauge

Если вам часто приходится добавлять значения, нетрудно написать хранимую процедуру SQL для вставки только новых комбинаций.

Если вам не нужна большая гибкость или целостность данных, подумайте над уточнением своего вопроса.

0 голосов
/ 21 января 2012

Марка автомобильного класса. Автомобиль может быть либо грузовиком, либо автомобилем. Возможно, вам стоит взглянуть на наследование и абстракцию - две основы объектно-ориентированного проектирования.

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