I want to have a database with two tables, like so:
Parent
-------
Pk
UgliestChildPk
StrongestChildPk
Child
------
Pk
ParentPk
I'm working with SQLite, although that probably doesn't pertain much.
In my model, a Parent always has at least one Child, in which case the ugliest one and the strongest one would be the Parent's only Child.
I need to be able to retrieve all of a Parent's Children (via the Child.ParentPk foreign key). I also need to be able to efficiently retrieve a Parent's ugliest and strongest child.
I need to be able to add and remove children, as well as change which ones are the ugliest and strongest.
I gather it throws a flag that the Parent and Child tables both refer to each other. Is there a better way to accomplish these sorts of relationships?
I could add an IsUgliest and IsStrongest column to the Child table, but I want to efficiently ensure that there is one and only one ugliest and strongest child for each Parent (although they could be the same).
I also don't want to have to add indexes to the IsUgliest and IsStrongest columns in order to retrive them quickly. The schema I've described prevents that since the Pk columns are implicitly indexed anyway.
Is there a better way?
Any suggestions?
I prefer option 2 below as it would be the easiest to maintain and craft logic for.
Option 1
One way to accomplish this would be to specify the [strongest] not null unique in the table creation. You would then decide how you wanted to list the strongest, e.g. 1 being the strongest.
Although this would allow you to do what you are asking, you would need some logic to rearrange the values in the table so that you could add or remove other children. This would allow you to easily reassign the ugliest child based on the ascending/descending order you set on your ugly/strength score
Option 2
A second way to do this would be to still use the IsStrongest and IsUgliest columns, but set their type to Boolean, and then perform a check to make sure there is only one person set to true when attempting to add a new ugliest or strongest child.
Option 3
Use the table structure you provided to quickly keep track of the strongest and ugliest child right in the parent table. You would probably need an alternate way of tracking the strength and beauty of a child so that you can easily determine who is the parent's ugliest/strongest child
Additionally
If you have the possibility of having more than one parent, you should use a linked table that looks like this
Parent_Child
------------
PCPK
Parent_FK
Child_FK
Related
Imagine I have a Parent.hasMany(Child) relationship, if I have an API to query a Parent but also need to surface how many children this parent has, I have 2 immediate options:
Run a query on COUNT(child.id) (I feel this must be very hard to scale as we add more and more children in for a given Parent
Maybe have a n_count attribute defined on the Parent and do a SQL transaction to modify the count on the parent every time a Child is created/deleted
Which is the better option here, or is there a third and best way?
Storing n_count in the parent is generally considered undesirable because it is redundant information (information which can be obtained more reliably by counting the child records). Having said that, if the updates to the parent and child rows (n_count) is controlled to guarantee correct updates (by database triggers, for example), then this can be called a type of 'controlled de-normalisation', and used for performance improvement (only improves read-queries, updates/inserts will be slower, of course).
What is best practise when a parent & child table both FK to the same table?
Parent > Child(ren)
CommonAttributes: Sex, Age, Height, Weight
Is it better to directly reference the common table:
CommonAttributes > Parent(s) > Child(ren)
&
CommonAttributes > Child(ren)
Or use a reference table:
RefTable: CommonAttributes_Id, Parent_Id(null), Child_Id(null)
I think the first method works OK (with regards to EF) but it is a bit of a circular reference. Is it better to use a reference table to define the constraints?
There are several approaches to this and the one you need depends on your business needs.
First, can a child record have more than one parent? For instance you might be modelling an organizational structure where an employee can have two supervisors. If this is true, then you have a one to many relationship and need a separate table for this model to work.
If you are guaranteed to have only one parent per child (but each parent might have a parent (building a hierarchy), then you can model this is one table. The table structure would include the Primary key, say UserID and then a nullable column for the parent such as ParentUserID. Then you can create the foreign key to the field in the same table.
ALTER TABLE dbo.Mytable ADD CONSTRAINT FK_Mytable _UserPArent FOREIGN KEY (ParentUserD) REFERENCESdbo.Mytable (UserID)
If you want to build a hierarchy in a query, you then use a recursive CTE to get it. See example here:
https://msdn.microsoft.com/en-us/library/ms186243.aspx
Another time you might want to build a separate table for the child parent relationship is if only a small portion of teh records in the main table would have parent child relationships. For instance suppose you had a people table that stored, sales reps and customers. Only sales reps would have a parent child relationship. So you would want a separate SalesRepHierarchy table to store it which woudl make querying more straightforward.
While in general you woudl want to create hierarchies in a recursive CTE, there are special cases when it might be faster to pre calculate the hierarchies. This is true if the hierarchy is frequently queried, the CTE performance is slow and you have control over how the hierarchy is built (preferably through an import of data only) and if it changes fairly rarely (you would not want to be rebuilding the hierarchy every minute, but a once a day import can be accommodated. This can greatly speed up and simply querying for the whole hierarchy, but is not recommended if the parent child relationships are created and changed constantly through the application.
If in a databse we have a parent table and two children tables. Is it better to use joins to get the children or add a flag to distinguish them ?
For example, the parent table is Person[Person_Name, Person_ID]. The first child table is Employee[Person_ID, Employee_ID, Department] and the other child is Customer[Person_ID, Location, Rank].
So, is it a good thing to add flag [isEmployee] or [isCustomer] to the parent table (Person) and save the effort of Joining the tables on "person_Id" ?
Another case would be with one child, for example, the parent table would be Member[Member_Name, Member_ID] and a child table GoldenMember[Member_ID, Phone_Number, EMail].
Now in this case, if I want to show the info of a specific Member, I need to do a join between tables to see whether it's a Golden Memmber or not, but if the flag "isGolden" was in the table (Member) it would save us a join?
So, which is better and why ??
Thanks in advance :)
There is no "better" unless you provide criteria for measurement of "goodness".
SQL's support for entity subtyping is inadequate. You can hack your way around any of the shortcomings that there are, but each hack will do no more than introduce new problems of its own.
Additional "Type" columns on the top level introduce the problem of database updating becoming more complex. Defective update procedures will corrupt the database's integrity.
Leaving out the additional "Type" columns at the top level will make the problem of formulating read queries more complex (more joins, notably). Many people would add here "and degrade performance", but it's unlikely that you will suffer noticeably from this.
Choose which difficulty is the easiest to live with in your particular use case.
I have been questioning a certain scenario if it could benefit from using a one to one relationship in my ERD. I have a table called library with a FK called typeID from a table called element type. Essentially the element types have a sibling relationship with element as the parent and each item in the library is one of those types. The library is mainly used to create a hierarchy amongst the elements and other properties of how they exist in the library. If I add a column for every property of each type of element most columns would be virtually empty because not every element type has every property of the others. Also there are some other tables that are using the library items id where I want to put a constraint on what types of elements can be a foreign key for that table because not every element type can have that relationship. I was wondering if it is a good idea to use 1 to 1 where there is that same constraint on what type of element from the library can exist in the table, then add the unique properties. For example tableXYZ can only have items where typeID from library = 1 and all the 1 types are always in it. It seems like a good way to simulate object inheritance/generalization. Also all the tables connecting to library needing a specific type of element for the FK relationship could connect to the extended 1 to 1 table which already has that constraint so they don't have to. Also some of the elements are extensions of each other, could you have 1 to 1 then extend 1 to 1 again? Is this a legit idea? Will it even work? Is there anything I am not seeing here?
fyi the DB is postgreSQL
You might want to look into two techniques: class-table-inheritance and shared-primary-key
By applying these two techniques to your case, you may end up with a simpler, yet more powerful design than the one you propose. In some cases, you can dispense with the TypeID entirely, because a join between the generalized table and the appropriate specialized table will yield precisely the objects you are looking for. In addition, because the join is on two primary keys, the join will be relatively fast.
i am trying to design a table which contains sections and each section contains tasks and each task contains sub tasks and so on. I would like to do it under one table. Please let me know the best single table approach which is scalable. I am pretty new to database design. Also please suggest if single table is not the best approach then what could be the best approach to do this. I am using db2.
Put quite simply, I would say use 1 table for tasks.
In addition to all its various other attributes, each task should have a primary identifier, and another column to optionally contain the identifier of its parent task.
If you are using DB2 for z/OS, then you will use a recursive query with a common table expression. Otherwise you you can use a hierarchical recursive query in DB2 for i, or possibly in DB2 for LUW (Linux, Unix, Windows).
Other designs requiring more tables, each specializing in a certain part of the task:subtask relationship, may needlessly introduce issues or limitations.
There are a few ways to do this.
One idea is to use two tables: Sections and Tasks
There could be a one to many relationship between the two. The Task table could be designed as a tree with a TaskId and a ParentTaksId which means you can have Tasks that go n-levels deep (sub tasks of sub tasks og sub tasks etc). Every Task except for the root task will have a parent.
I guess you can also solve this by using a single table where you just add a section column to the Task table I described above.
If you are going to put everything into one table although convenient will be inefficient in the long run. This would mean you will be storing unnecessary repeated groups of data in your database which would not be processor and memory friendly at all. It would in fact violate the Normalization rules and to be more specific the 1st Normal Form which says that there should be no repeating groups that could be found in your table. And it would actually also violate the 3rd Normal Form which means there will be no (transitional) dependency of a non-primary key to another non-primary key.
To give you an illustration, I will put your design into one table. Although I will be guessing on the possible fields but just bear with it because this is for the sake of discussion. Look at the graphics below:
If you look the graphics above (although this is rather small you could download the image and see it closer for yourself), the SectionName, Taskname, TaskInitiator, TaskStartDate and TaskEndDate are unnecessary repeated which as I mentioned earlier a violation of the 1st Normal Form.
Secondly, Taskname, TaskInitiator, TaskStartDate and TaskEndDate are functionally dependent on TaskID which is not a primary key instead of SectionID which in this case should be the primary key (if on a separate table). This is violation of 3rd Normal Form which says that there should be no Transitional Dependence or non-primary key should be dependent on
another non-primary key.
Although there are instances that you have to de-normalized but I believe this one should be normalized. In my own estimation there should be three tables involved in your design, namely, Sections,Tasks and SubTasks that would like the one below.
Section is related to Tasks, that is, a section could have many Tasks.
And Task is related to Sub-Tasks, that is, a Task could have many Sub-tasks.
If I understand correctly the original poster does not know, how many levels of hierarchy will be needed (hence "and so on"). His problem is to create a design that can hold a structure of any depth.
Imho that is a complex issue that does not have a single answer. When implementing such a design you need to count such factors as:
Will the structure be fairly constant? (How many writes?)
How often will this structure be read?
What operations will need to be possible? (Get all children objects of a given object? Get the parent object? Get the direct children?)
If the structure will be constant You could use the nested set model (http://en.wikipedia.org/wiki/Nested_set_model)
In this way the table has a 'left' and 'right' column. The parent object has its left and right column encompasing the values of any of its children object.
In that way you can list all the children of an object using a query like this:
SELECT child.id
FROM table AS parent
JOIN table AS child
ON child.left BETWEEN parent.left AND parent.right
AND child.right BETWEEN parent.left AND parent.right
WHERE
parent.id = #searchId
This design can be VERY fast to read, but is also EXTREMELY costly when the structure changes (for example when adding a child to any object You will have to update any object with a 'right' value that is higher than the inserted one).
If you need to be able to make changes to structure in real time you should probably use a design with two tables - one holding the objects, the second the structure (something like parentId, childId, differenceInHierarchyLevels).