Finding a good DB design for my project - sql-server

I'm really struggling to find a good DB design for my project using SQL server.
I've already implemented a few models which worked great till this point, but now that I need to add something extra I just can't find a good option and I'm stuck with it ATM.
I've supplied below 2 very simplified models (class diagrams) I've tried, but both models are not working well.
1st model: which I also prefer if it's possible to fix
I should explain first that msg and action can have the same basic id (i.e 1) but when used with tabID or groupID as a composite primary key, it becomes unique.
Here you can see that UserInput is created using only the basic ID which creates a problem to save both a Msg and Action with id 1 for example.
Is there anyway around this? maybe a way to say that ya Action and Msg are extending UserInput but they define all the keys themselves?
2nd model:
Each Critical Point is related to either a Msg or Action, but how can I define it since they have a different set of PK? I would like to keep referral integrity.
I would REALLY appreciate help on this issue.

Potential fix for 1st model
I do not understand why Action and Msg can have the same id. If you want to treat them both similarly (as UserInput) then the id of the UserInput table needs to be unique for them both. So each id of UserInput represents either an Action or a Msg.
I do not know if this is a good example, but lets if Action and Msg are similar to Car and Motorcycle, than you still want to be able to uniquely identify them so their id on the license plate should really be unique and thus should not exist in both groups.
Does the critical point needs to know by what it is used?
If not, you just need a foreign key column "CriticalPointId" in your UserInput class. Because Action and Msg are subclasses, they can both access their CritialPoint.
Potential fix for 2nd model
In this model you have unique ids in the Msg and Action table.
In that respect, it is very similar to my proposed fix for the first model, expect from that fact that no UserData table exists.
This might be the better solution if Msg and Action do not have anything in common (there are no properties in UserData in the first model except from the ID).
Supposing that the CriticalPoint does not need to know by what object it is used, you just need to specify a "CriticalPointId" foreign key column in both the Msg and the Action table.

Related

There cannot be more than one relational path between any two tables in the graph

I'm building a database in Filemaker and I have a problem linking tables. Basically, I have a table "capture" showing an event where a photo will be taken. Someone will be dealing with "capture" meaning that there will be a responsible for "capture" to be recorded properly. The photo taken in "capture" will be recorded in a second table "photos". Another person could be responsible for the photo management. So I have a "Observers" table which will be my contact table. I want to be able to link the "Observers" table with the "capture" AND the "Photos" table so that the names in "Observers" populates both tables.
But if I do the link like in the image below:
I get this error:
"There cannot be more than one relational path between any two tables in the graph."
How can I like the 2 tables, if possible? I know it makes an "ambiguous" path, but there might be a way to reutilize the information in "Observers" to inform 2 different tables that are linked together.
I want to do something like this:
EDIT:
Use another occurrence of the Observers table.
See: https://fmhelp.filemaker.com/help/18/fmp/en/index.html#page/FMP_Help/adding-tables.html
Recommended reading:
http://www.nightwingenterprises.com/Resources/approaches_to_graph_modeling_en.pdf
-- Edit
Let's bring back to basics because when trying to define a model, the concept must have been well defined before.
Am i understand it well :
One or more observer are being assigned to work on a capture (evenement, place...).
The observer(s) take one or more Photo about the capture place.
And so one or more photo of a place can have been taken.
If that's true, we have the following relation
Here we are !
So what about the Logic Model of the database.
We can say that we have the following table :
CAPTURE(id_capture)
--> With id_capture being Primary Key of CAPTURE
OBSERVER(id_observer)
--> With id_observer being PK of OBSERVER
CAPTURE_OBSERVER(id_capture, id_observer)
--> With id_capture being FK of CAPTURE, and id_observer being FK of OBSERVER
PHOTO(id_photo, id_capture, id_observer)
--> With id_photo being PK of PHOTO, id_capture foreign key of CAPTURE, id_observer foreign key of OBSERVER
I hope i'm right, if not please correct me about the purpose of every entity in this model.
I think by adding this new table that i found (CAPTURE_OBSERVER) you'll be able to solve your problem AND to improve your model conception.

Database Normalization

I have had a crack at normalizing some data for a database would appreciate if anyone body could tell me if its correctly normalized.
Here is the structure:
I have used a composite key(Incident ID and Action code) as a certain incident would not require two actions of the same type. Is there a better way of doing this? I thought about just adding an Action ID auto number but is this OK?
Thanks if anyone can help.
Personally I would use ActionID as my key - it really depends on what you'll be doing with the data and the volume.
I could see it being useful to get a list of incidents where you'd taken out a particular Action, this would be easier to get with an index on just Action Code, also having a composite key could well result in page splits on the clustered index which obviously has an overhead.

CakePHP model association based on field values?

I've got three tables (there's actually several more, but I only need the three for this problem). Applications, Appattrs and Appcats. In CakePHP parlance (as best as I can since I'm still learning the framenwork) Applications hasMany Appattrs and Appattrs belongsTo Applications. Easy.
The problem comes when I want to associate Appattrs and Appcat - the association is predicated on a field value and a corresponding foreign key in Appattrs. For instance:
If appattrs.type = 'appcatid' then appattrs.value would point to a record in the Appcat table.
The appattrs table holds static data appattrs.type='dateadded' and value='201201011300' as well as foreign key references. I'd rather not get into a discussion as to why data is stored this way, I just want to figure out how to create associations that will let me pull an application record, the associated attr records and then an attr record with its associated row from the appropriate table. Dynamically.
It seems to me that I should be able to create a model based on a query and then associate that model - I just can't seem to figure out how to do that.
--
If I need to post schema for the three tables, I can. I can also post my current model code, but honestly, right now it's just association variables so I don't think it'll get anyone anywhere.
Thow I do not understand the logic behind this design, I thing what you are looking for
is Creating and Destroying associations on the fly.
On this section of CakePHP Docs, it describes how you can associate models from within the corresponding controller.
So, for example, when you want to save specific data to Appattr model you can do some data checking and create your association using bind() method.
A very abstract approach to the above would be something like this
public function yourmethod() {
...
if ($this->request->data['Appattr']['type'] == 'sometype') {
$this->Appattr->bindModel(
array(/*Your association*/ => array(/* Your attributes...*/)
);
/* Rest of the logic follows */
}
}
This way you get your job done, but it's very possible to end up having very complicated
data in your database and thus having very complicated code.
I hope this helps

cakePHP HABTM, am I getting it all wrong?

I understood that every new row, causes the deletion of the rows that were there before?
What is the idea behind it? I don't believe that it is ..
So, what am i getting wrong?
Edit A
I have a form that adds a store to the Stores table. the store have a column named owner_id which is associated to the Users table through a belongsTo relationship.
There is also a table named stores_users that supposed to store the mangers for each store, using the HABTM relationship.
For this table there is a form with an email field, that connects the user to the store by saving the record directly to the stores_users table.
So, there is no full HABTM save anywhere, if I understand the term correctly.
So, my questions are:
Should I expect problems using it this way?
Can you advice me about how to it, if my method is not the proper way?
How can I use the stored data, using $this->User->find(...) to get all the stores that the user can manage?
yes, thats the default behavior of HABTM in cakephp
although this is not on "every row", but "every HABTM save".
this is working IF you always provide all HABTM values.
and with baked views according to the specifications for such HABTM this is all working out of the box.
if you change the default behavior (old ones get not deleted) you will need to make sure that there are no duplicates. there are behaviors out there, I think, which try to accomplish that.
but I would recommend for you to build your forms the way that the default behavior of cake can do its job.
Example:
IS: 1,3,6 (in DB for this key)
NEW: 2,3,6 (coming from form)
(cake deletes 1,3,6 and adds 2,3,6)
=> overall result (forgetting about different primary keys): "1" deleted, "2" added
so it might not be the most resource sparing way but its sure the easiest and fastest.

How to store old version of ID String in Database Design?

I am building a small database for a lab. We have some rules to make a ID String for every Item, so i do not want to store it in my database. The problem is that some times changes in data, for example the person response for that item changed, causes the chang of ID String. But i can not correct it for printed docs. How can i store the old version of that ID String.
I may simply do't change it but that will break the rules. Any suggestions?
To expand on Damir's point
A "Smart Key" is what you say when
We have some rules to make a ID String for every Item
You're taking the name of the item, maybe a category code and adding
person response for that item
So if I were responsible for Beakers that item ID might be
GLASSWARE-BEAKER-SPAGE
That 'code' becomes a 'Smart key' when you use it in your database as a Primary Key.
This is an anti-pattern. Like most anti-patterns it's seductive. People like the idea of just looking at the key and knowing what kind of thing it is, what it is called and who do I ask to get more. All that information on a report or shelf-label with just a few characters. But it's an anti-pattern for the reason you mentioned - it has meaning and meaning can be changed.
As Damir suggests, you can store this value in another column that we'd call an ALTERNATE KEY or CANDIDATE KEY... it's unique, it could be a PK but it's not. You'll want a unique constraint on the column but not a Primary Key constraint.
It is important to distinguish between a primary key which is supposed to uniquely identify a row in a table and some kind of a smart key that products in catalogs usually have.
For a primary key use auto-incrementing integer -- very few exceptions to this one.
Add columns for things that you are trying to represent in that smart key, like: Person, Project, Response etc.
Add a separate column for that key and treat it like any other field in the table -- this should keep people who are used to this kind of thinking happy.
Smart key is a misnomer here, from a db-design point, that key is rather dumb.
for example the person response for that item changed, causes the chang of ID String
Looks like the workflow in your lab is broken. IDs should never change. Try to bring this to attention of your superiors.

Resources