2017-06-16 18 views
0

Ich habe eine SQLite-Datenbank in einer VB.NET-Anwendung erstellt. Es speichert Zeitreihendaten für mehrere varName Aufzeichnungen über 2 Tabellen:SQLite relational INSERT mit unbekanntem Fremdschlüssel

  1. Tabelle varNames:

    CREATE TABLE IF NOT EXISTS varNames(
        id  INTEGER PRIMARY KEY, 
        varName TEXT UNIQUE 
    ); 
    

    Es sieht wie folgt aus:

    ID | varName 
    --------------- 
    1 | var1 
    2 | var2 
    ... | ... 
    
  2. Tabelle varValues:

    CREATE TABLE IF NOT EXISTS varValues(
        timestamp INTEGER, 
        varValue FLOAT, 
        id  INTEGER, 
        FOREIGN KEY(id) REFERENCES varNames(id) ON DELETE CASCADE 
    ); 
    

    Es sieht wie folgt aus:

    timestamp | varValue | id 
    ------------------------------ 
    1   | 1.0345 | 1 
    4   | 3.5643 | 1 
    1   | 7.7866 | 2 
    3   | 4.5668 | 2 
    ...  | ....  | ... 
    

erste Tabelle enthält varName mit ID. Die Sekunde enthält die Werte von jedem varName als Zeitreihe (per timestamp). Ein Fremdschlüssel verbindet die Tabellen. Legen Sie in varNames sieht wie folgt aus:

INSERT OR REPLACE INTO varNames (
    varName 
) VALUES (
    @name 
); 

I-Werte für einen bestimmten varName in die zweite Tabelle wie folgt ein:

INSERT OR REPLACE INTO varValues (
    timestamp, 
    varValue, 
    id 
) VALUES (
    @timestamp, 
    @value, 
    (SELECT id FROM varNames WHERE varName = @name) 
); 

Ich weiß nicht, die varName ‚s ID für den entsprechenden varValues Rekord zum Zeitpunkt der Einfügung. Aus diesem Grund verwende ich:

(SELECT id FROM varNames WHERE varName = @name) 

Scheint langsam im Vergleich von ID direkt zu adressieren. Wie kann ich INSERT Leistung in die zweite Tabelle verbessern?

+0

Hängt davon ab, wie Sie Dinge tun ... Es sollte nicht langsam sein, wenn Sie wenig Daten haben. Sie könnten den Wert der ID in Ihrem .net-Code speichern, wenn das möglich ist, oder Sie erhalten die [letzte eingefügte Zeilen-ID] (https://stackoverflow.com/questions/2127138/how-to-retrieve-the-last-autoincremented- ID-von-a-SQLite-Tabelle). –

+0

Eine Frage, die ich fragen würde ist, warum Sie zwei Tabellen an erster Stelle haben? Welchen Zweck erfüllt die erste Tabelle (mit nur ID und Variablenname)? In der zweiten Tabelle, was verhindert, dass Sie nur den Variablennamen anstelle der ID speichern? –

+0

@ChrisDunaway: Gute Frage Ich habe mich auch gefragt, als ich diesen Thread gerade noch einmal gelesen habe. Der Grund dafür ist die Performance und die Größe der DB-Datei. Mit 600 Variablen bei 50k Datenpunkten bekomme ich 30m Zeilen. Wenn ich nur eine Tabelle verwende und die Namen jeder Variablen anstelle eines einfachen Fremdschlüssels immer und immer wieder neu setze, wächst meine Dateigröße enorm (in meinem Fall 3x die Größe). Zusätzlich dauert dies viel länger als die Einstellung mit den zwei Tabellen ... – JoP

Antwort

0

& hellip; die INSERT-Leistung in der zweiten Tabelle verbessern?

Verwendung a transaction (vorzugsweise kombinieren mehrere INSERT):

BEGIN TRANSACTION; 

INSERT OR REPLACE INTO varValues (
    timestamp, 
    varValue, 
    id 
) VALUES (
    @timestamp, 
    @value, 
    (SELECT id FROM varNames WHERE varName = @name) 
); 

INSERT OR REPLACE INTO varValues (
    timestamp, 
    varValue, 
    id 
) VALUES (
    @timestamp, 
    @value, 
    (SELECT id FROM varNames WHERE varName = @name) 
); 

etc. ... 

END TRANSACTION; 

Related.