База данных "supertable" против большего количества таблиц против общей таблицы - PullRequest
4 голосов
/ 29 ноября 2010

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

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

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

То же самое с показаниями регистратора.

Вот мои 3 идеи для хранения этих данных:

Вариант 1:

Location [Table]
- Id [PK]
- Name
- HasLogger

LiveSensor [Table]
- LocationId [FK]
- Id [PK]

LiveSensorReading [Table]
- Id [PK]
- SensorId [FK]
- Value

LiveSensorAlert [Table]
- Id [PK]
- SensorReadingId [FK] (may not be needed - enforces need to always have at least 1 reading)

LiveSensorAlertCorrectiveAction [Table]
- LiveSensorAlertId [FK]
- CorrectiveActionId [FK]
- ByUserId [FK]

LiveSensorAlertAcknowledgement [Table]
- LiveSensorAlertId [FK]
- ByUserID [FK]

LiveSensorAlertReading [Table]
- SensorAlertId [FK]
- SensorReadingId [FK]

LoggerReading [Table]
- LocationId [FK]
- Value

LoggerAlert [Table]
- Id [PK]
- LoggerReadingId [FK] (may not be needed - enforces need to always have at least 1 reading)

LoggerAlertReading [Table]
- LoggerAlertId [FK]
- LoggerReadingId [FK]

LoggerAlertCorrectiveAction [Table]
- LoggerAlertId [FK]
- CorrectiveActionId [FK]
- ByUserId [FK]

LoggerAlertAcknowledgement [Table]
 - LoggerAlertId [FK]
 - ByUserID [FK]
  • Проблема: множество повторяющихся таблиц (правда ли это имеет значение ??)

Вариант 2:

Location [Table]
- Id
- Name
- HasLogger

Sensor [Table]
- Id [PK]
- LocationId [FK]

SensorReading [Table]
- Id [PK]
- SensorId [FK]
- Value

LoggerReading
- LocationId [FK]
- Value

Alert [Table]
- Id [PK]

AlertCorrectiveAction [Table]
- AlertId [FK]
- CorrectiveActionId [FK]
- ByUserId [FK]

AlertAcknowledgement [Table]
- AlertId [FK]
- ByUserId [FK]

SensorAlertReading
- AlertId [FK]
- SensorReadingId [FK]

LoggerAlertReading
 - AlertId [FK]
 - LoggerReadingId [FK]
  • Проблема: не применяется "по крайней мере 1 «чтение по предупреждению» правило.
  • Проблема: допускает более одного типа чтение для ссылки на то же предупреждение.

Вариант 3:

Location [Table]
- Id
- Name
- HasLogger

Sensor [Table]
- Id [PK]
- LocationId [FK]

SensorReading [Table]
- Id [PK]
- SensorId [FK]
- Value

LoggerReading
- LocationId [FK]
- Value

Alert [Table] "super table"
- Id [PK]

LoggerAlert [Table]
- AlertId [PK, FK]
- LoggerReadingId [FK]

SensorAlert [Table]
- AlertId [PK, FK]
- SensorReadingId [FK]

AlertCorrectiveAction [Table]
- AlertId [FK]
- CorrectiveActionId [FK]
- ByUserId [FK]

AlertAcknowledgement [Table]
- AlertId [FK]
- ByUserId [FK]

SensorAlertReading [Table]
- SensorAlertId [FK]
- SensorReadingId [FK]

LoggerAlertReading [Table]
 - LoggerAlertId [FK]
 - LoggerReadingId [FK]
  • Проблема: ничто не мешает LoggerAlert и SensorAlert ссылка на то же самое оповещение (та же проблема как вариант 2).
  • Проблема: запутывает базу данных (не супер стол больше концепции ОО? База данных должна быть чисто не так ли?)

Я думаю, что до сих пор я предпочитаю вариант 1, потому что он кажется таким чистым и цель ясна (я надеюсь!), Хотя я эффективно повторяю таблицы.

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

Мне интересно, что люди думают о вышеупомянутых вариантах. Я видел использование «супер таблиц», рекомендуемых тихо, часто, но по какой-то причине это просто нехорошо - это почти похоже на хак, особенно когда я вижу методы для обеспечения целостности данных. Кажется, это больше похоже на ОО-программирование, чем на реляционный дизайн.

Спасибо.

EDIT: Некоторая дополнительная информация, чтобы помочь ответить на некоторые из вопросов ниже:

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

Живые оповещения и оповещения регистратора обычно обрабатываются одинаково, поэтому я, вероятно, буду иметь дело со всеми оповещениями большую часть времени, а не с оповещениями регистратора и оповещениями в реальном времени.

В логгере есть довольно специфические столбцы, которые находятся в таблице местоположений. Так как местоположение и регистратор были бы отображением 1: 1, я решил не иметь отдельную таблицу регистратора, и до сих пор она, кажется, работала нормально и оставалась простой. Пример столбцов: LoggerRFID (int), LoggerUpperLimit (float), LoggerLowerLimit (float) и т. Д. Можно почти утверждать, что регистратор является датчиком, но я пошел по этому пути, и он не получился слишком хорошо.

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

Ответы [ 3 ]

1 голос
/ 29 ноября 2010

Некоторые мысли (идеи и мнения, а не ответы) по этому поводу:

Модель «supertable» (тип / подтип) неотразима, но ее сложно реализовать и поддержать.Несколько трюков:

ALERT
  AlertId    PK 1/2
  AlertType  PK 2/2  Check constraint (1 or 2, or better L or S)

... то есть составной первичный ключ, где "тип" всегда должен быть L) или S) ensor.

LOGALERT
  LogAlertId  PK 1/2  FK 1/2
  AlertType   PK 2/2  FK 2/2

(and again for SENSORALERT)

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

Недостатком является то, что он сложный, запутывает тех, кто еще (пока) не знаком с ним, и потребует дополнительной поддержки и усилий,Вопрос в том, стоит ли это того?

  • Как часто вы должны иметь дело с всеми оповещениями, а не только с журналом или только с датчиком?Если в большинстве случаев вам приходится иметь дело только с одним или другим, это, вероятно, не стоит.
  • Сколько деталей, относящихся к журналу или датчику, вам приходится иметь дело?Помимо реальных событий, связанных с отдельным предупреждением, насколько одинаковыми для обоих типов являются многочисленные атрибуты (подробности в столбцах), которые вы будете отслеживать?Если пользователи, подтверждения и корректирующие действия (в достаточной степени) идентичны, вы можете сделать их атрибутами (столбцами) ALERT, но если нет, то вам придется присвоить им атрибуты соответствующего подтипа, и вы потеряете консолидирующее преимущество супертипа.
  • И вы должны сделать это правильно сейчас, во время разработки.Исследуйте, задавайте вопросы, смотрите в хрустальные шары (то есть размышляйте о том, что может произойти в будущем, чтобы опровергнуть все текущие предположения), потому что, если вы ошибаетесь, вам и вашим преемникам, возможно, придется жить с этим вечно.
1 голос
/ 09 декабря 2010

Я думаю, что на этот вопрос был дан ответ в вашем другом вопросе с полной моделью данных;в противном случае (если есть что-то выдающееся), пожалуйста, опубликуйте Редактировать этот вопрос.

Если вас интересует Супертип-подтип Реляционная структура, в общем смысле, , этот вопрос может вас заинтересовать.

Могу ли я предложить вам закрыть этот вопрос.

1 голос
/ 29 ноября 2010

Вы можете добавить столбец ObjectType к вашим зеркальным таблицам в первом варианте и предоставить значения либо Sensor, либо Logger.Тогда ваш дизайн базы данных будет выглядеть примерно так:

Location [Table]
- Id
- Name
- HasLogger

ObjectType [Table]
- Id [PK]
- Name -- either Sensor or Logger
- Description

Object [Table]
- Id [PK]
- LocationId [FK]
- ObjectTypeId [FK]

Reading [Table]
- Id [PK]
- ObjectId [FK]
- Value

ObjectReading
- ObjectId [FK]
- ReadingId [FK]

Alert [Table]
- Id [PK]
- ReadingId [FK]

AlertCorrectiveAction [Table]
- AlertId [FK]
- CorrectiveActionId [FK]
- ByUserId [FK]

AlertAcknowledgement [Table]
- AlertId [FK]
- ByUserId [FK]

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

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

Я также согласен с оценкой КМ выше, что идентификатор первичного ключа каждой таблицы должен бытьназвал что-то длиннее, чем "Id".

...