I see. Fortunately my application simplifies this since the database is created once and read many times, but is never modified after creation time. Regarding constraints, I was thinking it might be helpful to add a few where applicable (whether foreign key constraints or even simple uniqueness constraints) basically as assertions, but I was worried about the overhead it would take to enforce them when I'm creating the database. Do you know if a uniqueness constraint, for instance, does an O(N) search on each insertion? If so, it sounds prohibitive. Thanks, Jeff
Richard Klein wrote: > Jeff, > > I think that's the right way to go for your application. There are a few > things you should be aware of regarding this approach. > > A column in one table that references a column in another table is called > a "foreign key" in database lingo. > > An issue with foreign keys is that it is important to keep the referencing > table (big_table) in sync with the referenced table (secondary_table). > > For example, if you delete an entry from secondary_table, you want to update > the foreign key column in all entries in big_table that reference that entry. > > What's the proper way to update the foreign key? It depends on your appli- > cation. You might want to set the foreign key in the referencing entries to > NULL, or you might want to delete the referencing entries, or you might want > to do something else. > > In standard, full-blown SQL, you can define the synchronization behavior you > want with a "foreign key constraint". That is, you might create big_table > as follows: > > CREATE TABLE big_table ( > id INTEGER PRIMARY KEY, > col1 INTEGER, > col2 REAL, > col3 TEXT, > col4 BLOB, > col5 INTEGER, > CONSTRAINT col5_fk FOREIGN KEY(col5) > REFERENCES secondary_table(id) ON DELETE SET NULL, > ); > > This would define col5 as a foreign key referencing the id column of > secondary_ > table, and would specify that col5 should be set to NULL in all referencing > entries in big_table when an entry in secondary_table is deleted. > > Unfortunately, SQLite does not implement foreign key constraints. More > precisely, > they don't cause syntax errors, but they aren't enforced. Therefore, you will > have to implement the desired synchronization behavior yourself. Fortunately, > this is easy to do with the use of TRIGGERs, which *are* implemented in > SQLite. > > Here are some links that might be useful: > > Foreign keys: http://en.wikipedia.org/wiki/Foreign_key > SQLite triggers: http://www.sqlite.org/lang_createtrigger.html > > Hope this helps, > - Richard > > >> Thanks! I'll give that a try. >> Jeff >> >> Richard Klein wrote: >> >>>> Whether or not the the secondary columns are needed is a function of one >>>> of the primary columns. That function involves values from another >>>> table, though, so the general case would require a join. That other >>>> table is small, however, so I generally cache it outside the database. >>>> Some pseudocode for my expected use would be something like: >>>> >>>> prepare("SELECT primary_columns FROM big_table WHERE some_criterion") >>>> while(step()) { >>>> >>>> if( F(primary_column_values) ) { >>>> Fetch secondary values >>>> } >>>> >>>> do something with primary and maybe secondary values; >>>> >>>> } >>>> >>>> Where F would be implemented outside the database. >>>> Thanks, >>>> Jeff >>>> >>>> >>> I assume that the primary SELECT shown above can be made suitably fast >>> by creating the appropriate indices on big_table. >>> >>> If the secondary columns are kept in a separate, secondary_table, and >>> a fifth primary column is added that contains the ROWID of the approp- >>> riate entry in the secondary_table (or NULL if the secondary_table is >>> not needed), then the "Fetch secondary values" operation should be very >>> fast as well. >>> >>> It seems to me that this approach would be faster than a join, and >>> would consume less space than an 8-column table containing mostly >>> NULLs in the secondary columns. >>> >>> Of course, this approach would cost you some extra space, in the form >>> of the 5th primary column containing the secondary ROWID. >>> >>> - Richard Klein >>> >>> _______________________________________________ >>> sqlite-users mailing list >>> sqlite-users@sqlite.org >>> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users >>> >>> >> _______________________________________________ >> sqlite-users mailing list >> sqlite-users@sqlite.org >> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users >> > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users