On Sat, 13 Jun 2009 23:42:21 +0100, Simon Slavin
<slav...@hearsay.demon.co.uk> wrote:

>I'm writing an application which involves lots of relations between  
>tables.  Seen from a high level, my application will have to enforce  
>lots of rules to ensure database integrity.  Before I used SQLite I  
>would have enforced all these rules in my software.  But SQLite has  
>lots of ways to do this itself, with ON CONFLICT, TRIGGERs, and stuff  
>like that.  But I don't see any real reason to use these features, and  
>I'm concerned about how well I can document what each of them is there  
>for.
>
>I'm an experienced programmer and will have no problem enforcing the  
>rules in my software.  On the other hand, SQLite does some of them  
>very neatly, with less code than I'd need in my application.  On the  
>gripping hand, if my software fails to do an operation it knows why  
>and can generate a specific error message, whereas if SQLite hits a  
>CONFLICT my error message would have to list all the possible reasons  
>and let the user decide which one was the cause.

That's a trade off you have to decide on for yourself.
User input should be validated by the application anyway, so
the most common errors will be handled by the application.

Using CONSTRAINTs and TRIGGERs protects you against
programming errors, I would .

>Do any of you have experience with doing this ?  Are there some  
>conclusive points which will make me decide immediately that I should  
>do it one way or the other ?  I accept reasoned argument, URLs,  
>anecdotes, or anything else relevant.

I tried to enforce consistency and integrity by implementing
a "value domain" system in awk. The schema source uses
domain names instead of types. They are simply substituted
by the domain definition. 

The utility primes a new database, creates dictionary tables
and registers domains, tables, columns, including the
comments from the schema definition, together with dtcreated
and dtmodified timestamps. It also keeps a log of all DDL
and DML passed through it, loads .csv files by generating
INSERT statements, trims values, and optionally analyses the
datatypes, min and max values, and min and max length of the
values. It focuses on creating (portentially large)
databases in batch. No support for referential integrity.

It's undocumented, and I don't have time to answer any
questions about it, so it's not fit for publication.

Snipped of such a schema:
--[domains]
longname  = VARCHAR(64) -- long name alphanum_64
shortname = CHAR(8)     -- identifier (userid, account, ...)
longtext  = CLOB        -- text field of arbitrary length
counter   = INTEGER     -- integer

--[help]
CREATE TABLE %OBJECT% ( -- 
        hlpfor        shortname, -- knowledge domain
        hlpname       longname,  -- name or short description
        hlptext       longtext,  -- descriptive text
        PRIMARY KEY (hlpfor,hlpname) ON CONFLICT ABORT
);
 
>By the way, the SQLite documentation is excellent but it's a little  
>short on examples (unless there are a treasure trove of them somewhere  
>I missed ?).  How would I, for example, make SQLite refuse to delete  
>an account if any transactions are recorded for it ?  Make up your own  
>schema for the two tables, as long at they're convincing.

Referential integrity can be obtained with REFERENCES
constraints (foreign key relations). SQLite parses the
syntax but doesn't enforce them yet. But the sqlite3 command
line tool has a command, .genfkey, which converts those
constraints into TRIGGERs that implement them.

http://www.sqlite.org/cvstrac/wiki?p=ForeignKeyTriggers

There's also a site that implements it:
http://www.rcs-comp.com/site/index.php/view/Utilities-SQLite_foreign_key_trigger_generator
>Simon.
-- 
  (  Kees Nuyt
  )
c[_]
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to