Таблицы обычно разбиваются на логически отличные " вещи ", поэтому у вас нет одинаковых " вещей " дважды. Например, вы не хотели бы:
[SensorReadings]
Id : PK
UpperLimit : FLOAT
UpperLimitAlertDelay : INT
LowerLimit : FLOAT
LowerLimitAlertDelay : INT
IsAnalog : BOOL
AnalogValue : FLOAT
IsOn : BOOL
Поскольку вы смешиваете датчик и его показания в один ряд. Датчик - это вещь , отличная от показаний:
[Sensors] [SensorReadings]
Id Id
UpperLimit SensorID
UpperLimitAlertDelay Reading
LowerLimit
LowerLimitAlertDelay
IsAnalog
Manufacturer
SerialNumber
LastInspectionDate
...
Единственное, чего бы я не хотел, так это разделить «датчики» на две таблицы. Датчик - это датчик, это то, чем он является. Как клиент - это клиент, или песня - это песня. У вас будет столик с песнями, а не столик с классическими песнями и еще один столик для всего остального. Если вы разделите датчики на две таблицы, вы можете предположить, что у вас будет два датчика с одинаковым ID
. Датчики являются уникальными объектами, они должны находиться в одной таблице и иметь уникальный идентификатор. Тот факт, что датчик является аналоговым или цифровым, является свойством датчика.
Ваш вопрос уникален - ваши датчики могут иметь Показания в различных логических форматах; некоторые являются аналоговыми значениями с плавающей запятой, другие являются цифровыми логическими значениями. Вы боретесь с тем, как сохранить « показания » датчика, когда не все показания датчика соответствуют одному и тому же типу данных логического столбца (т.е. float vs bool). Все сводится к практичности и тому, что лучше для системы.
Вы можете сохранить все показания в столбце с плавающей запятой:
[SensorReadings]
Id SensorID Reading
== ======== =======
1 3728 120.2
2 3728 120.3
3 89 1
4 89 0
5 3728 120.2
6 89 0
Но теперь вы должны знать, как интерпретировать значение с плавающей запятой 0
, 1
как логическое on
, off
. Это сложно сделать? лично я так не думаю. Правда, он не в полной мере использует типы данных, доступные в ядре базы данных, но мне все равно. Вы собираетесь присоединиться к SensorReadings
с Sensors
, поэтому у вас будет столбец IsAnalog
, чтобы помочь вам интерпретировать. Другими словами:
SELECT Id, SensorID, Reading, Sensors.IsAnalog
FROM SensorReadings sr
INNER JOIN Sensors s ON sr.SensorID = s.SensorID
Довольно просто разобрать набор результатов:
Id SensorID Reading IsAnalog
== ======== ======= ========
1 3728 120.2 false
2 3728 120.3 false
3 89 1 true
4 89 0 true
5 3728 120.2 false
6 89 0 true
Вы можете даже создать вспомогательное представление (или просто запрос), которое декодирует чтение как AnalogReading
и DigitalReading
:
CREATE VIEW SimpleSensorReadings AS
SELECT Id, SensorID, Reading AS RawReading,
CASE Sensors.IsAnalog
WHEN 0 THEN Reading
ELSE NULL
END AS AnalogReading,
CASE Sensors.IsAnalog
WHEN 1 THEN CAST(Reading AS BOOL)
ELSE NULL
END AS DigitalReading,
Sensors.IsAnalog
FROM SensorReadings sr
INNER JOIN Sensors s ON sr.SensorID = s.SensorID
Это даст вам:
[SimpleSensorReadings]
Id SensorID RawReading AnalogReading DigitalReading IsAnalog
== ======== ========== ============= ============== ========
1 3728 120.2 120.2 true
2 3728 120.3 120.3 true
3 89 1 true false
4 89 0 false false
5 3728 120.2 120.2 true
6 89 0 false false
Это зависит от того, кто имеет дело с результатами. Я легко могу представить код, сначала проверяющий столбец «IsAnalog», а затем считывающий AnalogReading
или DigitalReading
в зависимости от ситуации.
Вы могли бы сделать то, что вы изначально предложили; разделите их на несколько таблиц. Но теперь возникает проблема: как вы получаете доступ к данным? Мне кажется, если бы у меня была эта система показаний датчиков, в какой-то момент мне придется что-то с ними делать - показывать их пользователю. Теперь мне нужно прыгать через обручи, чтобы воссоединиться с данными:
SELECT ID, AnalogSensorID AS SensorID,
Value AS RawReading, Value AS AnalogReading,
true AS IsAnalog
FROM AnalogSensorReadings
UNION ALL
SELECT ID, SwitchSensorID AS SensorID,
CAST(IsOn AS float) AS RawReading, null AS AnalogReading, IsOn AS DigitalReading,
false AS IsAnalog
давая вам
Id SensorID RawReading AnalogReading DigitalReading IsAnalog
== ======== ========== ============= ============== ========
1 3728 120.2 120.2 true
2 3728 120.3 120.3 true
1 89 1 true false
2 89 0 false false
3 3728 120.2 120.2 true
3 89 0 false false
Кроме того, "Id" также трудно декодировать, потому что два разных показания могут иметь один и тот же "ID". Чтение - это чтение, и оно должно быть уникальным.
Компромисс, который вы, вероятно, ищете, это то, что вы изначально имели.
[SensorReadings]
Id SensorID AnalogReading DigitalReading
== ======== ============= ==============
1 3728 120.2
2 3728 120.3
3 89 true
4 89 false
5 3728 120.2
6 89 false
Да, это оставляет вам множество (null)
значений, но затраты на объединение таблиц - это практическая проблема, которая должна учитывать ваше проектное решение.
Я думаю, что это как реестр в Windows. A key
содержит value
. Вам не очень важно, , как хранится это значение, если вы можете его прочитать, так как тип является логически. Для этого в базе данных я бы использовал несколько столбцов типа данных и считывал их по мере необходимости.