On Tue, Feb 22, 2005 at 09:38:53PM -0700, John LeSueur wrote: > >In my model, a 'song' record consists of a unique artist/album/title > >A 'tag' is a name/value pair associated with a 'song': > > Song: song_id artist album title > > Tag: song_id name value > >Searching for the tags associated with a given song would be pretty > >easy, but complicating matters I need for tags to 'cascade'. > > > >This is so that a tag can be set for an entire album, and then > >overridden if necessary on a song by song basis. For example, if I am > >checking the value of the tag 'rating' for Artist/Album/Title, but no > >such tag is found, I want to fall back on the tag for > >Artist/Album/NULL; failing that I search for Artist/NULL/NULL. ... > select > coalesce(songtag.name, albumtag.name, artisttag.name) as name, > -- you might need to use a case statement instead if the value of a > tag can be null > -- in that case this would return a value that did not match the tag > coalesce(songtag.value, albumtag.value, artisttag.value) as value > from > song > left outer join > tag songtag > on song.id = tag.object_id > left outer join > tag artisttag > on song.artist_id = tag.object_id > left outer join > tag albumtag > on song.album_id = tag.object_id > where > song.id = ? > and tag.name = ?
Thanks for the response (and to you too, Dan)! I hadn't known about coalesce as a builtin, so that should be useful. I was also thinking that there should be some way to speed up the join a bit by short-circuiting if the first join finds a tag. Something like: SELECT coalesce(song_tag.name, album_tag.name, artist_tag.name) as name, coalesce(song_tag.value, album_tag.value, artist_tag.value) as value, FROM song LEFT OUTER JOIN tag AS song_tag ON song.song_id = song_tag.id LEFT OUTER JOIN tag as album_tag ON song_tag.id ISNULL AND <--- song.artist_id = album_tag.id LEFT OUTER JOIN tag as artist_tag ON album_tag.id ISNULL AND <--- song.artist_id = artist_tag.id WHERE song.id = ? AND tag.name = ? (guessing at query, haven't actually tried it yet) If this is internally optimized the way it could be (if I understand correctly), it could just fill in NULLs for the 'album_tag' and 'artist_tag' columns without having to do a look up. Do you know if this is how it works, or if there is some way to make it do that? > This could be surprisingly fast if you do it like itunes does and > load the entire song database into memory(which sqlite supports), > and using a file(itunes uses xml) only to load initially, and store > permanent changes. There's probably something even simpler you can > do, but I can't think of it at this moment. I'm going to be accessing this database from a couple different places: as a plugin to a music player (and hence long-lived) and from a small client program accessible via a hot key (short-lived). So I think that having the XML file as a primary store might not work well for me (at least from the short-lived client). But maybe I'm not really understanding the advantages of the in-memory database. Is it in some way inherently faster on lookups than just setting SQLite to use a really large cache? Thanks! Nathan Kurz [EMAIL PROTECTED]