q_e_d — 2011-07-20T13:36:40-04:00 — #1
I'm trying to create an inherited keyword structure in MySQL, and I'm not sure the best way to proceed. Essentially, I need one table attaching keywords to groups, ie:
create table keywords (
where the same keyword can apply to multiple groups and groups can have multiple keywords, as a many-to-many relationship.
Additionally, I need some structure for the groups that allows each group to inherit all of the keywords of its parent group. So far, I'm working with a table like:
create table groups(
int(6) groupID autoincrement,
PRIMARY KEY (groupID)
The intent is that if a keyword is changed in a parent group then all of its children, grandchildren, etc. inherit that change.
I've tried joining the groups table to itself recursively, but I don't know how to do that in SQL without hard-coding the number of joins.
Any ideas how to set up that sort of inheritance structure?
r937 — 2011-07-20T16:22:31-04:00 — #2
that's the unfortunate side effect of using the adjacency data model (the one which uses a "parent id")
but most applications can realistically set an upper limit on the number of levels, and then code that number of joins using LEFT OUTER JOIN for the retrieval query
if you really can't write a query for the maximum number of levels, you'll have to either change your data structure to the nested set model (the one with "lft" and "rgt" columns), or else call the database recursively (which can be horribly inefficient)
q_e_d — 2011-07-20T18:04:32-04:00 — #3
I don't know what you mean by the nested set model. How does that work?
r937 — 2011-07-20T18:34:30-04:00 — #4
how hard did you try to search for this?
there's even a sitepoint article which explains it
q_e_d — 2011-07-21T00:01:06-04:00 — #5
Thanks, r937. I didn't realize that this was an established method.
Stepping out of the structure for the big picture, what I'm trying to do is set up a way for a user to select the species for a picture they are uploading to a natural history site. When they pick a species the image gets all of the inherited tags like:
Group: Crotalus atrox
Keywords: Crotalus atrox, western diamond-backed rattlesnake, western diamondback rattlesnake, Víbora-cascabel de diamantes
Parent Group: Crotalus
Keywords: Crotalus, rattlesnakes
Parent Group: Crotalinae
Parent Group: Viperidae
Keywords: Viperidae, pit vipers, vipers
Parent Group: Serpentes
Keywords: Serpentes, serpente, serpents, snakes
Parent Group: Squamata
Parent Group: Reptilia
Keywords: Reptilia, répteis, reptiles, Reptiles
Parent Group: Vertebrata
Keywords: Vertebrata, vertebrado, vertebrates, vertébrés
Parent Group: Chordata
Keywords: Chordata, chordates, cordado
Keywords: Animalia, animal, animals
so the picture gets whatever keywords are assigned to it as well as all of the following keywords:
Crotalus, rattlesnakes, Crotalinae, Viperidae, pit vipers, vipers, Serpentes, serpente, serpents, snakes, Squamata, Reptilia, répteis, reptiles, Reptiles, Vertebrata, vertebrado, vertebrates, Chordata, chordates, cordado, Animalia, animal, animals
and if any of the parents have changes in keywords this is reflected in all of the children.
The problem I see with the nested set model is that there would be hundreds of thousands of groups, each with multiple keywords. Do you have any suggestions on how MySQL could efficiently deal with that sort of set up?
r937 — 2011-07-21T05:38:56-04:00 — #6
hundreds of thousands is no big deal, i would only start worrying if it were hundreds of millions
q_e_d — 2011-07-21T15:40:31-04:00 — #7
I just found the article you referred to and I'm converting my table.
Thank you for your help!