Among all the tables in my database, I have two which currently have a Many-to-Many
join. However, the actual data population being captured nearly always has a One-to-Many
association.
Considering that I want database look-ups (doctrine queries) to be as unencumbered as possible, should I instead:
- Create two associations between the tables (where the second is only populated in these exceptional cases)?
- Change the datatype for the association (eg to a
text
/tinyblob
) to record a mini array of the 2 (or technically even 3) associated records?
This is what I currently have (although TableB-> JoinTable is usually just one-to-one):
TableA.id --< a_id.JoinTable.b_id >-- TableB.id
So, I am looking to see if I can capture the 'exceptions'. Is the below the correct way to go about it?
TableA.id TableB.id
+----< TableB.A_id1
+----- TableB.A_id2
+----- TableB.A_id3
You seem to be interested in:
If you want queries to be unencumbered, just define Foo. You can query it for Rare.
Any other design suffers from update complexity in keeping the database consistent.
You have some fuzzy concern about Rare being much smaller than Foo. But what is your requirement re only n in a million Foo records being many:many by which you would choose some other design?
The next level of complexity is to have Foo and Rare. Updates have to keep the above equation true.
It seems extremely unlikely that there is a benefit in reducing the 2-or-3-in-a-million redundancy of Foo + Rare by only having Boring + Rare and reconstructing Foo from them. But it may be of benefit to define a unique index (b) for Boring which will maintain that a b in it has only one a. When you need Foo:
But your updates must maintain that
Please don't do that. If you do the people maintaining your database will curse your name unto the thousandth generation. No joke.
Your best bet here is to rig a one-to-many association. Let's say your table
a
has an integer primary keya_id
.Then, put that
a_id
as a foreign key column in your second tableb
.You can retrieve your information as follows. This will always give you one row in your result set for each row in
a
.If you don't mind the extra row for your one-in-a-million case it's even easier.
The
LEFT JOIN
operation allows for the case where youra
row has no correspondingb
row.Put an index on
b.a_id
.