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]