multi value attribute in primary key rdbms - mysql

I am creating a new database design in which i got stuck in a problem. I am having a table with attribute(A,B,C,D,E) here (A,B,C,D) is composite key which uniquely define E . My problem is attribute D is multi valued Which is a part of primary key.Currently i am thinking using comma separated values for D but it also has some limitations as while searching for E the values in D should be in same order as they were inserted.As-
Let D is i,j,k So My Table T is A,B,C,D(i,j,k)->E
Now if i want the result then i should fire query in same order as (A,B,C,D(i,j,k)).
So i am wondering is there any other better way to do this thing.

Don't use comma separated values as one of the fields in a composite primary key. When you do this, you are really creating a table that is not in First Normal Form, even though it may appear to be 1NF to the DBMS.
First Normal Form was devised way back when the relational model was brand new. It's purpose was to guarantee keyed access to all data. Don't define your keys in a way that defeats the purpose of having keys.
Here's what to do: First decompose the rows of your table into separate rows for each individual value in D, so that D doesn't have to be a multivalue any more. This will conform to 1NF, but will probably be in violation of 2NF, since non key values may be determined by just A, B, and C. You will probably want to decompose into two tables so as to conform to 2NF. And you may want to normalize even more than that.

Related

Can MySQL allow reference targets to be missing?

I have two tables in a MySQL 5.7.x DB. Table A, whose data I maintain, and table B, which I can only read. I would like to define a relationship (somewhat like a foreign key) from a column in table A to refer to values in a column in table B. The exception is that the referenced column in table B does not always contain the value to which the column in table A refers.
I don't mind that B's column doesn't have the value. As long as the relationship is defined for advisory purposes, it's OK. However, if I try to use a foreign key relationship for this purpose, it requires the value from A to be in B, too.
How can I define the relationship without the requirement? That is, can I let it be optional?
I'm looking for this to be specifically in the direction of A referring to a value in B, but B doesn't contain that value, and that's OK. Not as one person suggested, the column in A is null, not pointing to any value in B.
I've searched for an answer to this online, but I can't find the solution. Maybe I'm not phrasing the search terms well or I'm using the wrong terminology.
I think this may be possible with MySQL 8's NOT ENFORCED option, but that's only possible with CHECK type of constraints.
Foreign keys in MySQL can be enforced or not at session level (something really unorthodox and IMHO a design mistake):
SET FOREIGN_KEY_CHECKS = 0;
-- Do stuff
SET FOREIGN_KEY_CHECKS = 1;
But it's all-or-nothing. Advisory foreign keys is not really a concept in relational databases design. At first sight, I can't see what problem it would solve.

normalization and normal forms: database

Basically sorry for asking such question.But I got it wrong when I wrote these definitions in my exam about 1,2,and 3rd normal form (Conditions):
1 NF :
Data in each column should be atomic.No, multiple values separated by commas
Table should not contain repeating column groups
Identify each record using primary key.
2 NF :
must be in 1 NF
must not contain redundant data, if yes, move it to separate table
create table using foreign keys
3 NF :
Must be in 2NF
Dose not contain column that are not fully depended upon primary key
Have I written something wrong?My teacher does not agree.
Source this Video.
1NF
A row of data cannot contain repeating group of data i.e each column must have a unique value. Each row of data must have a unique identifier.
2NF
A table to be normalized to Second Normal Form should meet all the needs of First Normal Form and there must not be any partial dependency of any column on primary key. It means that for a table that has concatenated primary key, each column in the table that is not part of the primary key must depend upon the entire concatenated key for its existence. If any column depends only on one part of the concatenated key, then the table fails Second normal form
3NF
Third Normal form applies that every non-prime attribute of table must be dependent on primary key. The transitive functional dependency should be removed from the table. The table must be in Second Normal form.
More references:
http://www.studytonight.com/dbms/database-normalization.php
http://holowczak.com/database-normalization
I believe the answer is wrong. You are not using terms that are associated with normalization when you should. An example of this can be found in your answer for 2NF
must not contain reduntant data, if yet, move it to seperate table
create table using foreign keys
When is data redundant? Which data do you move to a seperate table? Is creating a table always a step you take to get a table in 2NF?
If you would have said:
All attributes which are not part of the primary identifier should be completely dependent on the entire primary identifier.
You are still saying the exact same thing, no redundant data is allowed, but the way you say it shows that you know what normalization is all about.
According to your answers in exam:
1 NF :
a.Data in each column should be atomic.No, multiple values separated by commas
(TRUE because 1NF does not support Composite and Multivalued attributes and more importantly, this property is handeled during ER Model to relational model conversion by default.) Only this property is enough for 1NF.
b.Table should not contain repeating column groups.
(Not required)
c.Identify each record using primary key.
(Not required)
2 NF :
a.must be in 1 NF
(TRUE)
b.must not contain redundant data, if yes, move it to separate table.
(TRUE but here we only focus on Partial dependency. Removal of Partial Dependency is enough for 2NF.And after its removal if some redundant data is still exist,Its OK for 2NF.)
c.create table using foreign keys
(FALSE, Break the table into 2-parts in such a way where common attribute between them behaves as a Candidate Key for any of decomposed table )
Example: R(A,B,C,D) , lets suppose we want to break this table for 2NF, so decomposition is done in such a way like, (AB) and (BCD) where common attribute(HERE: 'B') behaves as a Candidate key for any of (AB) or (BCD) ).
3 NF :
a.Must be in 2NF
(Not neccessarily true, even it is not in 2NF you can go with 3NF.When it will be in 3NF ,it automatically satisfy 2NF Properties)
b.Dose not contain column that are not fully depended upon primary key
(Way of writing is wrong, You should write "In 3NF, Transitive Dependency(Non prime attribute derives prime attribute) is not allowed")
*Remember: Always keep this thing in mind that, following 1NF to 2NF, 2NF to 3NF, 3NF to BCNF is not a rule ,its a convention. Means you can directly go for BCNF(0% redundancy).
Hope this helps. For more detail, you can also refer : Detailed explanation of Normal forms

Polymorphic database design : does this approach have a name?

I have a base enitiy (items) that will host a vast range of item types (>200) with totaly different properties. I want a clean portable and fast solution and have come up with an idea that maby has a name I'm unaware of.
Here it goes:
items-entity holds base class fields + additional fields for subclass fields but with dummie-names, ItemID,ItemNo,ItemTypeID,int1,int2,dec1,dec2,dec3,str1,str2
referenced itemtype-record holds name of type and child enity (1:n):
itemtypefields [itemtypeid,name,type,realfield]
example in [53,MaxPressure,dec,dec3]
It's limitations:
hard to estimate field requirements in baseclass
harder to add domains/checkconstraints based on child type
need application layer to translate tagged sql to real query
Only possible to query one type at a time since shared attributes may be defined to different "real-fields".
3rd bullet explained:
select ItemNo,_MaxPressure_ from items where ItemTypeID=10 and _MaxPressure_>42
should translate to:
select ItemNo,dec3 as MaxPressure from items where ItemType=10 and dec3>42
(can't do that with sp's or udf's right - or whould it be possible?)
But benefits of:
Performance
Ease of CRUD-operations
Easier to sort/filter at application level.
Now - does it have a name?
This antipattern is called One True Lookup Table.
In a relational database, each column needs to be defined as one logical type. I don't mean one SQL data type like INT or VARCHAR, I mean everything in that column from start to finish must be from the same set of values, and you should be able to tell one value apart from another value.
You can't put shoe size and average temperature and threads per inch into the same column of a given table, and still call it a relation.
Basically, your database would not be a database at all -- it would be a spreadsheet.
Read almost any book by C. J. Date, such as SQL and Relational Theory for a proper explanation of relations and types.
Re your comment:
Read the Q again before lecuturing about elementary books and mocking about semi structured data.
Okay, I have re-read your post.
The classic use of One True Lookup Table isn't exactly what you're doing, but what you're doing shares the same problems with OTLT.
Suppose you have "MaxPressure" stored in column dec3 for ItemType 10. Suppose there are a fixed set of valid choices for the value of MaxPressure, and you want to put those in another lookup table, so that no one can enter an invalid MaxPressure value.
Now: declare a foreign key constraint on dec3 referencing your MaxPressures lookup table. You can't -- the problem is that the foreign key constraint applies to the dec3 column in all rows, not just those rows where ItemType is 10.
The reason is that you're storing more than one set of values in a single column. The same problem arises for any other kind of constraint -- unique constraints, check constraints, even NOT NULL. And you can't declare a DEFAULT value for the column either, because you probably have a different correct default for each ItemType (and some ItemTypes have no default for that attribute).
The reason that I referred to the C. J. Date book is that he gives a crisp definition for a type: it's a named finite set, over which the equality operation is defined. That is, you can tell if the value "42" on one row is the same as the value "42" on another row. In a relational column, that must be true because they must come from the same original set of values. In your table, dec3 could have the value "42" when it's MaxPressure, but "42" for another ItemType when it's threads per inch. Therefore they aren't the same value "42". If you had a unique constraint, these two 42's would not be considered duplicates. If you had a foreign key, each of the different 42's would reference a different lookup table, etc.
What you're doing is not a valid relational database design.
Don't bristle at my referring you to a resource on relational database design unless you understand that.

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.

How to handle an "OR" relationship in an ERD (table) design?

I'm designing a small database for a personal project, and one of the tables, call it table C, needs to have a foreign key to one of two tables, call them A and B, differing by entry. What's the best way to implement this?
Ideas so far:
Create the table with two nullable foreign key fields connecting to the two tables.
Possibly with a trigger to reject inserts and updates that would result 0 or 2 of them being null.
Two separate tables with identical data
This breaks the rule about duplicating data.
What's a more elegant way of solving this problem?
You're describing a design called Polymorphic Associations. This often gets people into trouble.
What I usually recommend:
A --> D <-- B
^
|
C
In this design, you create a common parent table D that both A and B reference. This is analogous to a common supertype in OO design. Now your child table C can reference the super-table and from there you can get to the respective sub-table.
Through constraints and compound keys you can make sure a given row in D can be referenced only by A or B but not both.
If you're sure that C will only ever be referring to one of two tables (and not one of N), then your first choice is a sensible approach (and is one I've used before). But if you think the number of foreign key columns is going to keep increasing, this suggests there's some similarity or overlap that could be incorporated, and you might want to reconsider.