On second thought, checking the entire table for uniqueness would seem to require O(N log N), regardless of whether it is done one INSERT at a time, or all at once after the table is created!
- Richard Richard Klein wrote: > Quoting from the description of CREATE TABLE in the SQL Syntax section of > the SQLite documentation: > > "The UNIQUE constraint causes an index to be created on the specified columns. > This index must contain unique keys." > > The creation of an index would seem to imply an O(log N) search on each > insertion, so you should be okay. > > My advice would be to try it and see. If table creation takes too long, > you can always remove the UNIQUE constraint, and then write a routine to > check the table for uniqueness after it's created. > > - Richard > > > Jeff Gibson wrote: >> 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 > _______________________________________________ > 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