Modellazione di un database per un'app domotica del riscaldatore

3

Immagina una webapp domotica, per comandare un riscaldatore.

Potresti configurare N piani, per un piano intendo una tabella simile:

+----+---------+--------------------+
| id | name    | target_temperature |
+----+---------+--------------------+
| 1  | confort | 19                 |
+----+---------+--------------------+
| 2  | hot     | 22                 |
+----+---------+--------------------+
| 3  | night   | 17                 |
+----+---------+--------------------+


PSEUDOCODE
(if plan is confort && temperature<19 then heater on)

Immagina di configurare uno scenario simile:

MONDAY:

from 00:00 to 07:00 >> plan is night
from 07:00 to 08:00 >> plan is hot
from 16:00 to 18:00 >> plan is hot
from 18:00 to 22:00 >> plan is confort
from 22:00 to 23:59 >> plan is night

[...]

SATURDAY:

from 00:00 to 23:59 >> plan is confort

Nota che il lunedì dalle 08:00 alle 18:00 non c'è un piano. Il software verrà impostato su OFF the heater.

Come progetteresti il database dei giorni? Un tavolo singolare con 7 colonne (dal lunedì alla domenica) e ogni riga N righe? Non mi piace, perché il sabato è completamente diverso da lunedì.

Una tabella singolare con 24 (o 48) righe e 7 colonne? WHERE le righe vanno dalle 00:00 alle 23:59

+-----+-------+-------+---------+-----+---------+-------+
| id  | hour  | M     | T       | […] | S       | S     |
+-----+-------+-------+---------+-----+---------+-------+
| 1   | 00:00 | night | hot     |     | night   | night |
+-----+-------+-------+---------+-----+---------+-------+
| 2   | 00:30 | night | night   |     | confort | null  |
+-----+-------+-------+---------+-----+---------+-------+
| 3   | 01:00 | night | night   |     | confort | null  |
+-----+-------+-------+---------+-----+---------+-------+
| 4   | 01:30 | hot   | confort |     | confort | null  |
+-----+-------+-------+---------+-----+---------+-------+
| 5   | 02:00 | hot   | hot     |     | confort | null  |
+-----+-------+-------+---------+-----+---------+-------+
| 6   | 02:30 | null  | null    |     | confort | hot   |
+-----+-------+-------+---------+-----+---------+-------+
| […] |       |       |         |     |         |       |
+-----+-------+-------+---------+-----+---------+-------+
| 50  | 23:30 | hot   | hot     |     | null    | null  |
+-----+-------+-------+---------+-----+---------+-------+
| 51  | 23:59 | night | night   |     | night   | null  |
+-----+-------+-------+---------+-----+---------+-------+

E dove il NULL significa "Ehi! Metti il riscaldatore su OFF!" ...

Quindi, la query per ottenere il PIANO APPLICABILE CORRENTE potrebbe essere un semplice

SELECT * FROM TEST WHERE hour = 

(

SELECT MAX(hour) FROM TEST WHERE hour < CURTIME()

)

Ma in questo caso il difficile potrebbe essere selezionare il giorno giusto! Come selezionare solo la colonna "Lunedì"?

Grazie:)

    
posta sineverba 05.08.2016 - 17:18
fonte

1 risposta

2

Il tuo problema deriva dal fatto che la tua tabella TEST non è in NF1

Un modello più normalizzato sarà qualcosa del genere:

LatabellachechiamiTESTchiamoSCHEDULE_DETAIL,idatinonsonosimiliaquesto:

La query dovrebbe essere la seguente:

select
    p.plan_id,
    p.name,
    p.temp
from
    schedule s join
    schedule_detail sd on (sd.sch_id=sd.sch_id) join
    plan p on (sd.plan_id=p.plan_id) join
    day_of_week d on (sd.dow_id=d.dow_id)
where
    s.sch_id=1 and --we are using schedule 1 this time of year
    d.dow_id=1 and --monday, we can substitute the literal with a
                       --function that returns day of week (0-6)
    curtime() >= sd.start_hour and curtime() <= sd.end_hour;

Nota:

  • Alcune restrizioni non possono essere modellate, quindi dovrai scrivere una procedura di sanità per verificare che nessuna riga di SCHEDULE_DETAIL per lo stesso schedule_id abbia sovrapposizioni temporali. Nel tuo esempio le prime due righe per lunedì hanno un tempo di sovrapposizione (una termina alle 07:00 e la successiva inizia alle 07:00, ho corretto l'ora che si sovrappone ai dati di esempio che fornisco)

  • È necessario aggiungere un vincolo di controllo in modo che start_hour < end_hour

  • Puoi avere orari diversi e cambiarli durante l'anno come desideri.

  • Puoi creare una vista da quella query (meno le condizioni where) in modo da interrogare quella vista invece di fare i joind in ogni momento.

  • Quando la query non restituisce righe, disattiva il riscaldatore.

risposta data 05.08.2016 - 19:32
fonte

Leggi altre domande sui tag