![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Hi all, I'm designing a database that consists of the following: There can be many locations. Each locations can have 0 or many sensors. Each sensor can have many readings. A sensor is either in "alert" state or "normal" state depending on the last reading. An alert is an entity that must be acknowledged, acted upon, etc. |
|
There must be an elegant solution to this! |
#3
| |||
| |||
|
|
Mark S. (UK) wrote: Hi all, I'm designing a database that consists of the following: There can be many locations. Each locations can have 0 or many sensors. Each sensor can have many readings. A sensor is either in "alert" state or "normal" state depending on the last reading. An alert is an entity that must be acknowledged, acted upon, etc. [snip] There must be an elegant solution to this! First off, if you're lucky most of the participants in this group will ignore your request. If you're not then one of them may take the opportunity to snarl at you, possibly accusing you of asking for a homework solution or some other plausible crime. I'm more soft-hearted so I won't do that, but I also won't prescribe a solution. There are various reasons, not least being that I know nothing about your business problem. I do want to address your desire for an "elegant" solution though. I certainly accept that there are database designs that are grotesque or tortured or poorly matched to reality, but there really isn't any way to judge the elegance of a database design. Furthermore, database designers typically have a misplaced eagerness to "simplify" their designs, which usually means minimizing the number of tables. The result of that simplification is that real-world complexity is removed or concealed instead of being highlighted and supported. The complexity doesn't go away because the designer has abstracted or concealed the details. All the database designer will have done is shift the burden of understanding and managing the detail onto the application software (and the application programmer). Your test should be two-fold: does my database design allow me to assert all the facts I need, and does my database design make it difficult to accidentally formulate incorrect queries to answer reasonable questions? If the design passes those tests yet it has a necessary proliferation of tables and foreign keys and constraints, it's a good design. (Furthermore, there is no incontestibly correct design--it will be one of many possible good designs). HTH |
#4
| |||
| |||
|
|
And appologies for posting in this forum if it was inappropriate. |
|
Sometimes someone just pointing out ways to solve something in another way can really open doors in your mind and make things suddenly fall into place. |
|
[Sensor] SensorId LocationId UpperLimitValue LowerLimitValue |
#5
| |||
| |||
|
|
On Dec 6, 1:18 pm, "Mark S. (UK)"<ma... (AT) someaccount (DOT) net> wrote: And appologies for posting in this forum if it was inappropriate. The group is mostly focused on theory - the relational model of databases, as well as related fields such as set theory and first- order logic. Specific designs are difficult to discuss here, since each vendor's idiosyncracies contradict the requirements and recommendations of the model. You could try vendor-specific forums, but as you suspect, the recommendations there are often based on convention, heuristics or product features, rather than on logic. Sometimes someone just pointing out ways to solve something in another way can really open doors in your mind and make things suddenly fall into place. I would like to suggest that your design is contaminated by naive and mereological realism. A database should not represent objects, it should represent facts about objects. Take, for example, your table: [Sensor] SensorId LocationId UpperLimitValue LowerLimitValue Based on my own assumptions to fill in the information you didn't provide (or which I may have missed), I would say this table describes at least three different facts or relations: Sensor<SensorId> is located at<LocationId Sensor<SensorId> has upper limit<UpperLimitValue Sensor<SensorId> has lower limit<LowerLimitValue Do you intend a 1-to-1 correspondence between the three facts? Are you only modeling installed sensors with both lower and upper limits? This may be a join dependency, and join dependencies, like all dependencies, are significant in a database. Study the relational normal forms and apply it to your design. Nilone |
#6
| |||
| |||
|
|
The last table [SensorAlertReading in your original] is associating readings with the alert, because it is the reading that dictate that the sensor is in alert or not. |
#7
| |||||
| |||||
|
|
Please post DDL, so that people do not have to guess what the keys, constraints, Declarative Referential Integrity, data types, etc. in your schema are. Please learn to follow ISO-11179 data element naming conventions and formatting rules. The singular table names (they are sets of more than one element, aren't they?) so use a collective or plural name and the use of universal "_id" on every table were pretty bad. |
|
\Sample data is also a good idea, along with clear specifications. It is very hard to debug code when you do not let us see it. If you want to learn how to ask a question on a Newsgroup, look at: http://www.catb.org/~esr/faqs/smart-questions.html |
|
There can be many locations. Each locations can have 0 or many sensors. Each sensor can have many readings. A sensor is either in "alert" state or "normal" state depending on the last reading. An alert is an entity that must be acknowledged, acted upon, etc. Initially I related readings to alerts like this (very cut down) : - CREATE TABLE Locations (location_id CHAR(16) NOT NULL PRIMARY KEY); --htm number? Now you start making mistakes. The location of a sensor is NOT an attribute; it is a relationship between the sensor, the location and readings with a temporal element. Would you have done that with people? |
|
CREATE TABLE Sensors (sensor_nbr CHAR(15) NOT NULL PRIMARY KEY, --gtin upper_reading_value INTEGER NOT NULL, -- hardware imposed limits? lower_reading_value INTEGER NOT NULL, CHECK (upper_reading_value>= lower_reading_value)) Why dd you think you need a "sensor_reading_id " at all? How did you have a reading without a sensor in the relationship? Don't use vague names like "value" and reserved words like TIMESTAMP for data elements. |
|
Try this. The reading events of a particular sensor are held in time and space, so model it. These co-ordinates locate a reading and a status in those dimensions. CREATE TABLE Sensor_Readings (sensor_nbr CHAR(15) NOT NULL REFERENCES Sensors (sensor_nbr ), location_id CHAR(16) NOT NULL REFERENCES Locations(location_id), PRIMARY KEY (sensor_nbr, location_id, reading_timestamp), reading_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, reading_value INTEGER NOT NULL, sensor_status CHAR(6) DEFAULT 'normal' NOT NULL CHECK(sensor_status IN ('alert', 'normal')) ); The last table [SensorAlertReading in your original] is associating readings with the alert, because it is the reading that dictate that the sensor is in alert or not. Read what you wrote; this is a computed value; it is not an entity or a relationship, so it should not be in a separate table. You might also use a computed column or a VIEW rather than a simple column. If the rule is simple, use the GENERATED; if not, go to the VIEW so you can use other tables. sensor_status CHAR(6) NOT NULL GENERATED ALWAYS AS (CASE WHEN reading_value> 42 --whatever the rule is THEN 'alert' ELSE 'normal' END) |
#8
| |||
| |||
|
|
On 07/12/2010 18:42, -CELKO- wrote: Please post DDL, so that people do not have to guess what the keys, constraints, Declarative Referential Integrity, data types, etc. in your schema are. Please learn to follow ISO-11179 data element naming conventions and formatting rules. The singular table names (they are sets of more than one element, aren't they?) so use a collective or plural name and the use of universal "_id" on every table were pretty bad. Okay, point taken. |
#9
| ||||||
| ||||||
|
|
Even without readings, I have to be able to show that "the sensor is installed at this location". |
|
The upper and lower limit is the limits to which the measured element must stay between - and if it goes outside of these limits (for a configured length of time) an alert is generated. For instance, if the air temperature goes above its set limit for too long, an "air too warm" alert will be generated. That same alert stays active until the air temperature drops below the upper limit, |
|
or until another alert takes it's place. *For instance, if the sensor fails it would become an "air sensor failure" alert. *The "air too warm" alert then enters the "inactive" state - |
|
however a user must eventually acknowledge the alert *and* apply a "corrective action" to it before it can be considered resolved. |
|
That is why I modelled an alert as an entity - it has state (though it might not be a good enough reason to model it as an entity). |
|
I used value because it can represent any analog reading (temperature, humidity, etc.) - so maybe I should of called it analog_value. |
#10
| |||
| |||
|
|
The upper and lower limit is the limits to which the measured element must stay between - and if it goes outside of these limits (for a configured length of time) an alert is generated. |
![]() |
| Thread Tools | |
| Display Modes | |
| |