Архитектура базы данных sqlite - ссылка на несколько строк

У меня есть стол materials который содержит (я использую web2py):

materials_db.define_table('materials',
    Field('name','string'),
    Field('reference','string'),
    Field('manufacturer','string'),
    Field('date_added','date'),
    Field('density','double'), # Density - kg/m³
    Field('emissivity','double'),
    Field('specific_heat','double'), # Specific Heat - kJ/kg.K
    Field('thermal_conductivity','double') # Thermal conductivity - W/m.K
    )

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

+------------+-------+
|  Material  | Layer |
+------------+-------+
| Concrete   |     1 |
| Airgap     |     2 |
| Insulation |     3 |
| Plaster    |     4 |
+------------+-------+

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

Я действительно понятия не имею, как это сделать. Значение для layer внутри конструкции должен быть уникальным, но, очевидно, не должен быть уникальным между конструкциями, то есть каждая конструкция может иметь слой со значением 1.

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

3 ответа

Решение

Я не знаком с web2py, но чисто с точки зрения базы данных ваша модель должна выглядеть примерно так:

введите описание изображения здесь

  • Каждая конструкция имеет одну строку в таблице CONSTRUCTION.
  • Каждый материал по одной строке в таблице МАТЕРИАЛ.
  • Каждая строка в вашей спецификации 1 является одной строкой в ​​таблице CONSTRUCTION_MATERIAL и идентифицируется с помощью составного ключа {CONSTRUCTION_ID, LAYER}.

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


1 Билл или материалы.

2 Хотя и немного "необычно": MATERIAL_ID не является частью ключа, позволяющего использовать один и тот же материал в разных слоях одной и той же конструкции. Напротив, если один и тот же материал может появляться только один раз за конструкцию, просто создайте другой составной ключ: {CONSTRUCTION_ID, MATERIAL_ID}.

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

Каждое утверждение дает таблицу. Таблица содержит строки, которые делают ее утверждение верным.

materials(material_id,name,...) // material [material_id] has name [name] and ...
constructions(construction_id,purpose,...) // construction [construction_id] is good for [purpose] and ...
construction_layers(construction_id,material_id,layer) // construction [construction_id] layer [layer] is [material_id]

Ограничьте базу данных состояниями, которые могут возникнуть.

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

Ключи (наборы столбцов PK и UNIQUE) говорят, что значение базовой таблицы ограничено. ФК выражают, что буксирные столы взаимно ограничены.

materials(material_id,name,...) // material [material_id] has name [name] and ...
    pk (material_id)
constructions(construction_id,purpose,...) // construction [construction_id] is good for [purpose] and ...
    pk (construction_id)
construction_layers(construction_id,material_id,layer) // construction [construction] layer [layer] is [material_id]
    pk (construction_id,layer)
    fk (construction_id) references constructions (construction_id)
    fk (material_id) references materials (material_id)

Было бы хорошо, если бы СУБД была бы для каждой строки construction_layers

CHECK(layer >= 1)

но это может или не может быть возможно без триггеров с конкретной СУБД.

Мы также хотели бы проверить, что слои каждой конструкции являются смежными (возможно, не все время). Это вам придется делать триггерами под текущие СУБД.

Ограничьте то, что вы говорите в утверждении определенным образом.

Единственные свойства, которые вы должны иметь в базовой таблице, кроме ее ключевых столбцов, - это свойства целого ключа. (Это дает таблицу в 5NF.) (Расчетный столбец в любое время в порядке.)

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

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

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

create table MatConst(
  MatID int not null, -- Foreign key to Material table
  ConstID int not null, -- Foreign key to Construction table
  Qty number not null,  -- The number, volume or weight of Mat in Const.
  primary key( MatID, ConstID )
);

Два внешних ключа становятся первичными ключами для таблицы взаимосвязей, поэтому для каждой конструируемой вещи может быть только одна запись для бетона, одна для штукатурки и так далее. Поле Кол-во учитывает количество как 57 (фунтов бетона) или 150 (квадратных футов штукатурки). Вы можете, конечно, добавить другие столбцы, которые описывают отношения по мере необходимости.

Другие вопросы по тегам