2017-06-16 1 views
0

J'ai créé une base de données SQLite dans une application VB.NET. Il stocke les données de séries chronologiques pour plusieurs varName enregistrements sur 2 tables:SQLITE INSERT relationnel avec clé étrangère inconnue

  1. Tableau varNames:

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

    Il ressemble à ceci:

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

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

    Il ressemble à ceci:

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

Première table contient varName avec ID. La seconde contient les valeurs de chaque varName en tant que série temporelle (par timestamp). Une clé étrangère relie les tables. Insérer dans varNames ressemble à ceci:

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

insérer des valeurs pour un varName spécifique à la deuxième table comme ceci:

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

Je ne sais pas pour le varValues enregistrement correspondant de la IDvarName au moment de l'insertion. Voilà pourquoi je l'utilise:

(SELECT id FROM varNames WHERE varName = @name) 

semble lent par rapport à l'adressage par ID directement. Comment puis-je améliorer les performances INSERT dans la deuxième table?

+0

Cela dépend de la façon dont vous faites les choses ... Cela ne devrait pas être lent si vous avez peu de données. Vous pouvez stocker la valeur de l'identifiant dans votre code .net si c'est possible ou obtenir le [dernier identifiant de ligne inséré] (https://stackoverflow.com/questions/2127138/how-to-retrieve-the-last-autoincremented- id-from-a-sqlite-table). –

+0

Une question que je voudrais poser est pourquoi vous avez deux tables en premier lieu? À quoi sert la première table (avec seulement l'identifiant et le nom de la variable)? Dans la deuxième table, qu'est-ce qui vous empêche de stocker simplement le nom de la variable au lieu de l'identifiant? –

+0

@ChrisDunaway: Bonne question que je me posais aussi quand je viens de relire ce fil. La raison pour laquelle je fais cela est la performance et la taille du fichier DB. Avec 600 variables à 50k points de données, je reçois 30m lignes. Quand je n'utilise qu'une seule table et que je mets encore et encore les noms de chaque variable au lieu d'une simple clé étrangère, ma taille de fichier augmente énormément (dans mon cas, 3 fois la taille). De plus cela prend beaucoup plus de temps que l'apporach avec les deux tables ... – JoP

Répondre

0

& hellip; améliorer la performance INSERT dans la deuxième table?

Utilisation a transaction (de préférence moissonneuse-batteuse multiple 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.