2012-06-25 9 views
5

Vorrei essere sicuro di aver fatto tutto nel modo giusto.sqlite inserire un nuovo valore in vista

C'è un file di log 3Gb che voglio analizzare. Per eseguire tutte le query in ": memory:" per potenziare le prestazioni, Sostituisco le 10 colonne di testo in numeri interi per ciascuna riga di log.

create table if not exists app (
    id Integer primary key autoincrement, 
    value text unique 
); 

create table if not exists secret (
    id integer primary key autoincrement, 
    value text unique 
); 

and 10 more tables 

create table if not exists raw_log 
(
    id Integer primary key autoincrement, 
    app_id INTEGER, 
    secret_id INTEGER, 
    and 10 more _id columns 
); 

e creare una vista per la query e un trigger per l'inserimento.

create view if not exists log as 
    Select 
     raw_log.id, 
     app.value as app, 

     secret.value as secret, 
     and 10 more ... 

     from raw_log, app, secret, ..... x 10 
     where raw_log.app_id = app_id.id and raw_log.secret = secret.id and ... x 10 


CREATE TRIGGER insert_log 
    INSTEAD OF INSERT ON log 
    FOR EACH ROW BEGIN 
INSERT OR IGNORE INTO app(value) VALUES(NEW.app); 
INSERT OR IGNORE INTO secret(value) values(NEW.secret); 
... x 10 

INSERT INTO raw_log(app_id,secret_id, .... x 10) 
select app.id, secret.id, x 10 
from app, secret, x 10 
where app.value = NEW.app 
and secret.value = NEW.secret 
and ... x 10 
END;   

domande:

L'inserto via trigger non sembra funziona. Il numero di entità nella tabella di log è molto inferiore a quello che dovrebbe essere, mentre il numero di entità in segreto e l'app sembrano correttamente.

Penso che sia perché una nuova app e un segreto appaiono nel registro. Possono essere inseriti nella tabella senza problemi. Tuttavia, poiché queste modifiche non sono state ancora eseguite, la seguente query non può fare riferimento a questi valori correttamente.

In caso affermativo, come posso risolvere queste query?

INSERT INTO raw_log(app_id,secret_id, .... x 10) 
     select app.id, secret.id, x 10 
      from app, secret, x 10 
      where app.value = NEW.app 
       and secret.value = NEW.secret 
       and ... x 10 
+1

forse alcune delle colonne dove null e così, quando si fa un conteggio, non ha ottenuto contati? l'hai risolto? Sono interessato alla tua soluzione. – cybork

+0

hai testato la mia soluzione? –

risposta

1

Per ottenere inserito id uso last_insert_rowid(), ma se non sono sicuro si ottiene id sul conflitto, quindi è necessario utilizzare IFNULL per ottenere id per l'inserimento in raw_log.
È MAST salvare il valore di last_insert_rowid() prima di inserimento successivo, è per questo che è necessario utilizzare le variabili ...

CREATE TEMP TABLE IF NOT EXISTS _Variables (Name TEXT PRIMARY KEY, Value TEXT); 
... 
INSERT OR IGNORE INTO app(value) VALUES(NEW.app); 
INSERT OR REPLACE INTO _Variables(Key, Value) VALUES('app_id', ifnull((SELECT app.id from app where app.value = NEW.app), last_insert_rowid()); 
... 
INSERT INTO raw_log(app_id, secret_id, ... x 10) 
values((SELECT Value FROM _Variables WHERE Key = 'app_id') 
, (SELECT Value FROM _Variables WHERE Key = 'secret_id'), ... x 10); 
END; 
Problemi correlati