there is a parent table, he can add more than one children email ids(no. unknown)(primary key).
And a child can have one or 2 parent email ids(mother/father)
This will be a many to many relationship?
could you guide me on constructing this relationship in phpmyadmin.
A many to many relationship in a normal relational database, like MySQL, is normally constructed using a cross link table. That is a table that links to records in the other tables together.
For instance, when you've got tables A and B, you create a third table, C, which can look (very simplified) like this:
A B C
== == ====
A1 B1 A1B3
A2 B2 A2B1
A3 B3 A2B2
A3B2
So in this cross link table, you can see that record A2 is linked to two records in B, just as B2 is linked to two records in A. Of course, this schema is simplified. A1 is actually the keyfield of table A and A1B1 is a primary key that consists of two fields, one having a foreign key constraint to the key of table A and one having an FK to table B.
It doesn't always have to be a many to many relationship. For instance, you can say that a person has to parents, which also are persons. Since it's not very likely for people to have more that two biological parents, you can safely give a row in person a fatherid and a motherid, both of which refer to the same person table. So, like always, it depends on your exact needs.
Related
Suppose, I have a SQL database with table like A,B,C and Z. all three table A,B and C has a one-many relationship with table Z. I think of solution mentioned below but need suggestion or better solution for this problem if any.
Solution-
Create one more table named 'LinkZ' which have one-many relationship with table 'Z'
Add foreign key field to table A,B and C of table 'LinkZ'
So that way in future if more tables add to database which need relationship with table 'Z' we just need to add foreign key to newly added table of 'LinkZ' as it has already one-many relationship.
Please suggest solution if exist which satisfy my needs.
Edit -
#Gordon, "If all the tables have a "1-many" relationship with Z, then you don't need a link table at all. You need a link table when your relationships are many-to-many". I need this kind relationship which you have quoted from your answer. but if follow traditional way then i need to add AID, BID, CID in Z to achieve 1-Many with Z then 'Z' table contains many columns which represent foreign key with other table (In future might be other table also included to have same relationship, so in that case i want to avoid many columns from Z of only foreign keys only) that's why I have created dummy table 'LinkZ' which provide illusion to other table A,B and C that this all tables have 1-Many relationship with Z directly.
This is too long for a comment.
If all the tables have a "1-many" relationship with Z, then you don't need a link table at all. You need a link table when your relationships are many-to-many.
It is unclear which way the linkage is going, but you either want ZID in each of A, B, and C, or you want AID, BID, CID in Z.
Please check the tables below for a simplified version of my problem:
Table Boys
BoyId
BoyName
...
Table Girls
GirlId
GirlName
Table Toys
ToyId
ToyName
ToyOwnerBoyOrGirl ( The toy could be owned by a boy or a girl)
ToyOwnerId
I created two constraints:
1) ToyOwnerId is a foreign key of the Primary Key Boys.BoyId
2) ToyOwnerId is a foreign key of the Primary Key Girls.GirlId
My purpose is to tell the database that ToyOwnerId will always be one of these Ids
My problem:
When I tried to insert a new Toy with an id of a Boy, I got an error that there is a foreign key conflict in the Girls constraint.
Is this a bag design or I can still use the same design with a fix ?
I think you should combine the boys and girls table to one table called children. It would have sex column that would have an M or F. That will simplify things.
You should simply have both IDs in your toys table plus a check constraint to ensure that always either a boy or a girl is the owner.
Table Toys
ToyId
ToyName
ToyOwnerBoyId
ToyOwnerGirlId
CONSTRAINT chkToyOwner CHECK
(
(ToyOwnerBoyId is null and ToyOwnerGirlId is not null)
OR
(ToyOwnerBoyId is not null and ToyOwnerGirlId is null)
)
As to selecting the data, use outer joins:
select ...
from toys
left join boys on boys.boyid = toys.toyownerboyid
left join girls on girls.girlid = toys.toyownergirlid;
To find toys owned by boys:
select ...
from toys
where toyownerboyid is not null;
It looks like a bad design. Why don't have one table for all children and some mark - is it boy or girl? Also I really doubt you need ToyOwnerBoyOrGirl field - as it can be easily obtained by join from toys to owners.
Consider following scheme:
Table Children
ID
Name
Is_Boy
Table Toys
ID
Name
Owner_ID
In this case you need just foreign key from toys to owners, and other tasks you might encounter will be much more simplier to solve.
EDIT: As per OP's comment - Boys and Girls tables are totally different.
So, in this case you still can have table Children (let's use previous terminology) as a "common" table for Boys and Girls.
Something like:
Table Children
ID
Table_Name ('Boys' or 'Girls' here)
Record_ID (ID from Boys or Girls respectively)
...maybe some common fields from boys and girls tables here...
Table Boys
ID
Child_ID
...the rest of fields
Table Girls
ID
Child_ID
...the rest of fields
It's a bad design, given the fact one column set (one column, being ToyOwnerId) is referred to different tables, both as a one-column FK to a one-column PK. The obvious question would then be : how come you have different tables with a similar PK ? And I see you have answered that already, by means of replying the data columns of the respective tables are different. That is a good reason to have different tables. But, then, how to solve the FK issue ? (I understood that these "boys" and "girls" are not the real entities). What you can do, is make a BoyToy and a GirlToy table. If you have very few data columns (data = non-PK and non-FK) then that is a perfect solution. No ?
If I am relating two tables where each record in each table will not relate to more than one record in the other table, I assume that OneToOne is the right Doctrine association to use. However, if the table that s not the owning side does not have a record for every record in the owning side table, is that really one-to-one?
For example, Table A may have 100 records and Table B may have 20 records. The 20 records in Table B have a one-to-one relationship with 20 of the records in Table A, but another 80 records in Table A do not have a relationship with any records in Table B at all.
The correct answer to your question will be sticking with One-to-One relationship. It doesn't matter all records in Table A are not relating with Table B. As long as you are sure that 1 record in Table B does not refer to more than 1 row in Table A, you can stick with 1-to-1. When it comes to mapping in Doctrine, in the Table B side use the 'mappedBy' attribute. And you may not necessarily include the 'inversedBy' attribute in Table A, as not all records in Table A relates with Table B.
Hope this helps.
Cheers!
Say we have tables A, B, and C and then we want table Z to contain column TYPE which tells us which table of A, B, and C the record in Z is associated with.
Is it better to have a separate column for each table like columns A_ID, B_ID, and C_ID in order to use indexing?
Or is there some reason why using a generic column TYPE_ID might be better performance-wise?
Using a type_id and then a fk_id won't be good because selectivity on the index is 33%, which is too high to be of any use. You would always be indexing on the fk_id instead (that which links to A,B,C) - which may require tie breaking between 3 values (if the id is used by all 3 types).
Storage wise, an index never stores nulls, so the absolute number of items stored in the indexes, whether a single (fk_id) or multiple (a_id,b_id,c_id) will be similar.
If you are coming in from the exact fk_id (from either A,B,C), then using a unique index on (fk_id,type_id) in that order can quickly identify the record required.
It would seem for simplicity and brevity, two columns are better than 3 here.
This is sometimes a schema code smell.
If you are considering putting this as a single column in Z, does that mean that only one of A, B, C can be applicable to Z?
Before I decide, I'd really say I have to know more about the entity and the usage pattern. Is access coming from known A, B, or C, or is the supplemental info driven from the Z side? If it is driven from the Z side, do you want to get all the A, B and C columns and then use them selectively from the application, or just Zs with As or Zs with Bs - i.e. do you usually know the subtype? Also, do A, B, and C have enough columns to merit the separation out of Zs row if they are each 1-1 (i.e. you could have the columns in Z and just be NULL)
Just for completeness, another possibility which gives you more referential integrity (because with a single column, you can't be an FK to one of three tables) is to have tables Z_A, Z_B, Z_C:
With schemas:
Z_A:
Z_ID REFERENCES (Z.ID)
A_ID REFERENCES (A.ID)
Z_B:
Z_ID REFERENCES (Z.ID)
B_ID REFERENCES (B.ID)
Z_C:
Z_ID REFERENCES (Z.ID)
C_ID REFERENCES (C.ID)
With all IDs unique in each table, this constrains everything pretty nicely, except there is nothing declarative to stop Z lying in multiple tables without a trigger (you cannot make a unique constraint on an indexed view over a UNION ALL in SQL Server).
While it seems to multiply the number of tables, these can usually be wrapped up into views.
Is it possible, when creating a relationship in MS Access to manually set relationship type.
I'm creating a relationship between two tables, where records in table A can be related to 0 or 1 record in table B.
A:
ID PK, Counter
testID FK
Details
B:
ID PK, Counter
Details
I opened relationships tab and then dragged ID from table B to testID in table A. As a result, popup appeared with relationship setup. However, Relationship type was se to One to many, with One cardinality on the B table side.
Thanks
You model 0:1 with N:1 but make sure the field on the N/0 side of the join has the REQUIRED property set to FALSE.