J'essaie de décider d'une base de données. Plus précisément, il s'agit d'une sous-partie d'une conception plus large. Fondamentalement, il existe des "Emplacements" - chaque emplacement peut avoir un nombre quelconque de capteurs associés, et il peut avoir un enregistreur (mais seulement 1).Base de données "supertable" vs plusieurs tables vs tableau générique
J'ai des lectures de capteur et j'ai des lectures d'enregistreur, chacune assez différente pour justifier des tables séparées.
Si une lecture de capteur est hors de portée, une alerte est générée. Tant que la lecture d'un capteur reste hors de portée, il reste associé à cette alerte. Vous obtenez ainsi une alerte contenant de nombreuses lectures me permettant de tracer l'alerte plus tard pour repérer les tendances, etc.
Même avec les lectures de l'enregistreur.
Voici mes 3 idées à ce jour pour stocker ces données:
Option 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]
- Problème: Beaucoup de tables répétées (est-ce que vraiment d'importance si ??)
Option 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]
- Problème: n'applique pas la règle "au moins 1 lecture par alerte".
- Problème: Permet à plus d'un type de lecture de référencer la même alerte.
Option 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]
- Problème: Rien arrêter un LoggerAlert et SensorAlert référencement même alerte (même problème que l'option 2).
- Problème: obscurcit base de données
Je pense que jusqu'à présent, je suis préférant (n'est pas table maîtresse plus d'un concept OO Une base de données est censée être purement relationnelle est-ce pas?) option 1 parce que cela semble si propre et que l'intention est claire (j'espère!), même si je répète les tables efficacement.
Le seul petit problème auquel je viens de penser est que des lectures pour différents capteurs pourraient encore être associées à une seule alarme. Je me demande ce que les gens pensent des options ci-dessus. J'ai vu l'utilisation de "super tables" souvent silencieuse, mais pour une raison quelconque, je ne me sens pas bien - cela ressemble presque à un hack, surtout quand je vois les méthodes pour essayer d'assurer l'intégrité des données. Il semble plus proche de la programmation OO que de la conception relationnelle.
Merci.
EDIT: Certains plus d'informations pour aider à répondre à certaines des questions ci-dessous:
La plupart du temps la base de données est uniquement manipulé par un serveur d'application, si cela fait une différence. Les alertes en direct et les alertes des enregistreurs sont généralement traitées de la même manière. Je traiterai donc probablement toutes les alertes la plupart du temps, plutôt que de traiter les alertes de consignation et les alertes en direct de différentes manières.
L'enregistreur a des colonnes assez spécifiques qui résident dans la table de localisation. Étant donné que l'emplacement et l'enregistreur seraient un mappage de 1 à 1, j'ai décidé de ne pas avoir de table de journalisation séparée et, jusqu'à présent, il semble que cela ait bien fonctionné et que cela reste simple. Exemples de colonnes: LoggerRFID (int), LoggerUpperLimit (float), LoggerLowerLimit (float), etc. Vous pourriez presque faire valoir qu'un enregistreur est un capteur, mais je suis allé dans cette direction et cela ne s'est pas très bien passé. Je peux presque accepter de rendre les alertes génériques, mais comme l'une des réponses dit que j'essaie d'en être très sûr, je poursuis la recherche le plus longtemps possible avant de choisir un chemin spécifique.
Si je devais travailler sur ces tables, je préférerais que vous n'ayez pas de colonnes nommées simplement "Id". Pour moi, il est plus facile que la colonne FK et la colonne PK aient le même nom. Il suffit d'étendre le nom "Id" à "SensorReadingId" dans le tableau "SensorReading" comme vous le faites dans le tableau "SensorAlert". Cela aide quand vous avez besoin de chercher beaucoup de code (vous obtenez un million de faux résultats sur "Id" mais très peu sur "SensorReadingId") ou avoir de grandes requêtes avec beaucoup de tables, chacune avec une colonne "Id". –
Point pris - c'est comme ça que je l'ai toujours fait, mais je vais certainement penser à changer de comportement car l'argument semble valable. – Mark