MySQL Foreign Key to different table depending on column - mysql

I'm not sure the proper terminology for this type of relationship or even if it's good or bad. Hopefully I can clear up the lousy title.
I have a table that has the following fields:
id(pk), type, data(fk)
I want to be able to change the table that data points to depending on what "type" is. Depending on the type, there might be different types of data I need to pull. I'm basically trying to create a variable relationship.

You cannot do this in MySQL. You want conditional relationships.
You have basically three choices.
You can ignore putting these relationships in the database.
You can use before insert and before update triggers to enforce the constraints.
You can add a separate column for each type of id and add the constraints to those columns.

Related

Best database table design for a table with dependent column values

I would like know the best way of designing a table structure for dependent column values.
If i have a scenario like this this
if the status of the field is alive nothing to do
if the status is died some other column values are stored somehow.
What is the best way to handle this situation
whether to create table containing all columns ie 'Died in the hospital','Cause of death','Date of Death' and 'Please narrate the event' and let it be null when status is alive
or
to use seperate table for storing all the other attributes using Entity-attribute-value (EVA) concepts
in the above scenario signs and symptoms may be single, multiple or others with specification. how to store this .
what is the best way for performance and querying
either to provide 15 columns in single table and store null if no value or to store foreign key of symptoms in another table (in this strategy how to store other symptom description column).
In general, if you know what the columns are, you should include those in the table. So, a table with columns such as: died_in_hospital, cause_of_death, and so on seems like a reasonable solution.
Entity-attribute-value models are useful under two circumstances:
The attributes are not known and new ones are added over time.
The number of attributes is so large and sparsely populated that most columns would be NULL.
In your case, you know the attributes, so you should put them into a table as columns.
Entity-attribute-value models is the best method, it will be helpful in data filtering/searching. Keeping the columns in the base table itself is against Normalization rules.

Database table setup: Multiple tables that serve the same purpose?

I need to setup a MySQL database for a bugtracker, that's paired with a changelog.
Therefore I essentially have three tables: product, version, problem, problem_solution. The reason I splitted problems and their solutions is that I want to be able to provide my users with a set of possible solutions.
Now I want to add attachments to each of these tables and manage them via the database as well. There should be pictures, PDFs, ... for each product, version and possibly for each problem and solution.
Would I rather
Create 4 attachment-tables (product_attachments, version_attachments, ...), or
Create one attachment-table and create a column stating what it is for?
If latter, how should I do it? I want to reference to the specific ID of the product, version, problem or solution using a foreign key. Should I then just create 4 columns, each of them with a foreign key and decide whether it's an attachment for a product, a version, ... depending on which of these columns is not NULL? Wouldn't this make my queries unnecessarily complex?
I say create one table, have its primary key available, and create another table of EAV type for multi-to-multi relation between attachments and other entities, with "value" corresponding to attachment ID, "entity" to foreign ID and "attribute" to a value out of a fixed set of product, version, problem, solution in any form you like (1,2,3,4?). This way the attachments will be stored in a table of id, blob structure, maybe with corresponding count column storing the amount of links in the relation table, so that an orphaned attachment could be detected and removed with ease.

Database Design - Custom attributes table - Table that "relate" entities

I'm designing a database (for use in mysql) that permits new user-defined attributes to an entity called nodes.
To accomplish this I have created 2 other tables. One customvars table that holds all custom attributes and a *nodes_customvars* that define the relationship between nodes and customvars creating a 1..n and n..1 relationship.
Here is he link to the drawed model: Sketched database model
So far so good... But I'm not able to properly handle INSERTs and UPDATEs using separate IDs for each table.
For example, if I have a custom attribute called color in the *nodes_customvars* table inserted for a specific node, if I try to "INSERT ... ON DUPLICATE KEY UPDATE" either it will always insert or always update.
I've thinked on remove the "ID" field from the *nodes_customvars* tables and make it a composite key using nodes id and customvars id, but I'm not sure if this is the best solution...
I've read this article, and the comments, as well: http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspx
What is the best solution to this?
EDIT:
Complementing: I don't know the *nodes_customvars* id, only nodes id and customvars id. Analysing the *nodes_customvars* table:
1- If I make nodes id and/or customvars id UNIQUE in this table, using "INSERT ... ON DUPLICATE KEY UPDATE" will always UPDATE. Since that multiple nodes can share the same customvar, this is wrong;
2- If I don't make any UNIQUE key, "INSERT ... ON DUPLICATE KEY UPDATE" will always INSERT, since that no UNIQUE key is already found in the statement...
You have two options for solving your specific problem of the "INSERT...ON DUPLICATE KEY" either always inserting or updating as you describe.
Change the primary to be a composite key using nodeId and customvarId (as suggested by SyntaxGoonoo and in your question as a possible option).
Add a composite unique index using nodeId and customvarId.
CREATE UNIQUE INDEX IX_NODES_CUSTOMVARS ON NODES_CUSTOMVARS(nodeId, customvarId);
Both of the options would allow for the "INSERT...ON DUPLICATE KEY" functionality to work as you require (INSERT if a unique combination of nodeId and customvarId doesn't exist; update if it does).
As for the question about whether to have a composite primary key or a separate primary key column with an additional unique index, there are many things to consider in the design. There's the 1NF considerations and the physical characteristics of the database platform you're on and the preference of the ORM you happen to be using (if any). Given how InnoDB secondary indexes work (see last paragraph at: http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html), I would suggest that you keep the design as you currently have it and add in the additional unique index.
HTH,
-Dipin
You current entity design breaks 1NF. This means that your schema can erroneously store duplicate data.
nodes_customvars describes the many-to-many relationship between nodes and customvars. This type of table is sometimes referred to as an auxiliary table, because its contents are purely derived from base tables (in this case nodes and customvars).
The PK for an auxiliary table describing a many-to-many relationship should be a composite key in order to prevent duplication. Basically 1NF.
Any PK on a table is inherently UNIQUE. regardless of whether it is a single, or composite key. So in some ways your question doesn't make sense, because you are talking about turning the UNIQUE constraint on/off on id for nodes and customvars . Which you can't do if your id is actually a PK.
So what are you actually trying to achieve here???

Microsoft Access 2007, about column value

I'm pretty new to MS Access 2007, and I wanted to ask about something, that I couldn't find.
Is it possible that in a specific column, say for example: type, to make the only possible values "typea", "typeb"?
Just like the yes/no available option, just that it will contain my own specific values.
Yes you can create a lookup table with the id and description (typea/typeb) values in and then reference this table. You can add a check constraint on the column to ensure the type entered matches the constraint specified. (typea or typeb).
There is a way that involves only the basics. Create a reference table for the valid values of Type. It might have two columns, Id and Description. The primary key is Id.
Put two rows in with Id values of "typea" and "typeb". Put whatever you want for the description. You might use this later.
Use the relationship tool to make the column in your existing table reference the Id column in the types table. This will create a references constraint in the database.
Another response suggested adding a check constraint. That will probably run faster, but may involve more learning on your part.
And, if you ever add a third and fourth type, having a table like the one I've given will make it super easy to modify.

MYSQL: Creating a list of integers (IDs) which can use foreign key constraints for each integer element?

I was wondering if there is a way to create a foreign key for a list of integers that responds on single integer elements of the list.
For example, I have an "exercises" table. On that table, I would like to maintain two related columns:
"exercisesID"
"relatedExerciseIDs"
However, "relatedExerciseIDs" is a VARCHAR containing comma-delimited "exerciseID"s. On a deletion of an exercise from the table, any exercises with the deleted "exerciseID" in their "relatedExerciseIDs" list should remove it.
Is this possible? How can I do this?
Thanks for your opinions! I would also be interested in using a column type other than a VARCHAR if shown possible =)
All column values should be atomic.
You should not have a list of anything you want to query inside a single value.
The way to relate exercises to other exercises is with a second table. It will have two columns, each holding an exercise ID, where both columns are a foreign reference the exercises table.
The only way to do that is either via a stored procedure or in your language of choice. When you delete the record, you would then have to do a LIKE query to find any record with the value in your delimited field. It's really not the best way to do things, and would be slow as hell since you can't index that field the way you need to.
Your absolute best bet would be to create another table to define the relationships between exercises, using just two exercise id fields (exercise_id, related_exercise_id).
You should read up on Database Normalization.