Sqlite Limit > Datenstruktur bzw. Vorgehensweise sinnvoll?

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
inco
User
Beiträge: 16
Registriert: Sonntag 30. Dezember 2018, 16:32

Servus Zusammen,

ich stoße aktuell an verschiedene Limits beim erstellen einer Sqlite-Tabelle.

Hintergrund:
Sqlite-Datenbank mit Metadaten und Zeigern zu diversen .mat bzw. .csv files vorhanden.
Inhalt der .mat files (fix, je ein Float32 array mit 16k Elementen)
Inhalt der .csv files (variabel, etwa 30 Spalten x 3250 Zeilen, hauptsächlich Integer)
Um die Performance beim lesen/auswerten vieler Daten zu steigern hatte ich mir überlegt die genannten Files direkt in Sqlite-Datenbank abzulegen. Leider ist es in einer sqlite_Datenbank scheinbar nur möglich ca. 2000 Spalten anzulegen und dann bleibt immer noch ein Fehler ala SQL-Kommando zu lange...

Deswegen frage ich mich gerade ob mein Vorhaben überhaupt sinnvoll ist...
Wie würdet ihr solche Daten ablegen?

VG
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Warum musst du die ueberhaupt irgendwo ablegen? Du hast doch die Dateien. Die in eine Datenbank zu stopfen hat nur Vorteile, wenn du auf Teile der Daten zugreifen willst, und sich das sinnvoll ueber SQL darstellen laesst.
Benutzeravatar
__blackjack__
User
Beiträge: 13065
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@inco: Wo kommen denn 2000 Spalten her? Und wolltest Du die Dateien in die DB stecken oder den Inhalt in Tabellen?

Eventuell macht HDF mehr Sinn als SQLite?

@__deets__: Wenn in der Datenbank die Metadaten zu den Dateien liegen, kann es schon vorteilhaft sein auch die Dateien da rein zu stecken um das alles beieinander zu haben. Also wirklich einfach die jeweilige Datei statt ein ”Zeiger” auf die Datei, nicht eine Tabelle mit dem Dateiinhalt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

du Meinst in Form eines BLOBS? Klar, kann man auch machen. Aber mir fehlen da noch viel Informationen.
inco
User
Beiträge: 16
Registriert: Sonntag 30. Dezember 2018, 16:32

Warum musst du die ueberhaupt irgendwo ablegen? Du hast doch die Dateien. Die in eine Datenbank zu stopfen hat nur Vorteile, wenn du auf Teile der Daten zugreifen willst, und sich das sinnvoll ueber SQL darstellen laesst.
Nicht zwingend. Ich kann ein paar tausend von den .mat Daten auch so schon in Sekunden in pandas laden.
Ich dachte nur, dass das über eine Datenbank vielleicht noch schneller geht. Wollte einfach mal ein Gefühl für die unterschiedlichen Wege bekommen.
@inco: Wo kommen denn 2000 Spalten her? Und wolltest Du die Dateien in die DB stecken oder den Inhalt in Tabellen?
Durch probieren... ich hab einfach so lange die Spaltenanzahl reduziert, bis keine Fehlermeldung diesbezüglich mehr kam.
Die Arrays eingebettet geht wohl nur bei einer Postgres Datenbank. Hab mit sqlite beim auslesen nur noch binären Salat zurückbekommen.
Deswegen wollte ich nun den Inhalt in Tabellen legen.

Eventuell macht HDF mehr Sinn als SQLite?
Hab mal alle .csv Dateien in eine HDF Tabelle geschrieben und das dann per bulk in ein Mi-Dataframe gepackt.
Hat einigermaßen gut funktioniert... Fand das nur etwas umständlich und hab dann die Aktionen (filtern etc.) doch weitestgehend mit pandas durchgeführt.
du Meinst in Form eines BLOBS?
Interessant, über den Begriff bin ich noch nicht gestolpert.

Aber mir fehlen da noch viel Informationen.
Womit kann ich Licht ins Dunkel bringen?

VG
Benutzeravatar
sparrow
User
Beiträge: 4183
Registriert: Freitag 17. April 2009, 10:28

Für eine relationale Datenbank ist das Design der "Tabellen" ausschlaggebend.
Das ist nicht zwangsläufig ein Design, wie man es von visuellen Tabellen kennt. Und eine Tabelle mit >2.000 Spalten klingt erst einmal so, als wäre das Design falsch.
inco
User
Beiträge: 16
Registriert: Sonntag 30. Dezember 2018, 16:32

Für eine relationale Datenbank ist das Design der "Tabellen" ausschlaggebend.
Bei den Meta-Daten war das einfacher..
Vor allem da ich noch nicht genau weiß welche Analysen später mit den Daten durchgeführt werden sollen.
Der Grundaufbau sollte also recht flexibel bleiben...

Betrachte ich die FFT-Spektren könnte man die SQL-Tabellen von geringer zu hoher Auflösung strukturieren.
Beispielsweise:
Parent_Table: Terzspektren (Amplituden Mittelwert über definierte Frequenzbänder)
Jedes Frequenzband erhält dann einige Tabellen --> für die höchste Frequenzauflösung müsste man dann mehrere Tabellen kombinieren.
Wenn man über alle Daten nur bestimmte Frequenzbereiche analysieren möchte hätte das sicherlich Vorteile.
Bei Auswertungen des vollständigen Spektrums vermutlich dann eher weniger...

Edit: Aber vielleicht ist es doch sinnvoller einfach alle Daten in einem großen DataFrame zu organisieren und dann einfach verschiedene Container Ladezeiten zu vergleichen. Ich bau mal ein konkretes Beispiel zum spielen...

Viele Grüße
Zuletzt geändert von inco am Freitag 4. Januar 2019, 12:18, insgesamt 1-mal geändert.
Benutzeravatar
sparrow
User
Beiträge: 4183
Registriert: Freitag 17. April 2009, 10:28

So rein aus Neugier:
Könntest du mal eine Handvoll supervereinfachte Zeilen zeigen.
Also nicht mit 2.000 Spalten, sondern gerade so, dass man sich darunter etwas vorstellen kann.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Nur zum Speichern und Rechnen mit vielen Daten sind SQL-Datenbanken langsam. Wenn es Dir denn um Geschwindigkeit geht (und das sollte es erst, wenn Du Probleme damit hast), dann sind DataFrames die als Binärdaten in eine Datei geschrieben werden, das schnellste, was geht. Bevor Du hier also etwas so kompliziertest machst, mach es ersteinmal so einfach wie möglich, und warte, bis es Probleme gibt.
inco
User
Beiträge: 16
Registriert: Sonntag 30. Dezember 2018, 16:32

Servus Zusammen,

hier ein realitätsnahes Beispiel:

Code: Alles auswählen

import pandas as pd
import numpy as np
import datetime
import lorem

arr_len = 5000
base = datetime.datetime(2000, 1, 1)

#Master Tabelle
df = pd.DataFrame({'id': np.arange(arr_len),
                   'date' : np.array([base + datetime.timedelta(hours=i) for i in range(arr_len)]),
                   #Hier muss Metadata aus anderen Tabellen nachgeschlagen werden
                   'index_1': np.random.randint(1,10,size=arr_len),
                   'index_2': np.random.randint(1,35,size=arr_len),
                   'index_3': np.random.randint(1,4, size=arr_len),
                   'index_4' : np.random.randint(1,4, size=arr_len),
                   'index_5': np.random.randint(1,4, size=arr_len),
                   'index_6': np.random.randint(1,3,size=arr_len),
                   'index_7': np.random.randint(1,5,size=arr_len),
                   'index_8': np.random.randint(1,4, size=arr_len),                   
                   'index_9': np.random.randint(1,4, size=arr_len),                   
                   'index_10': np.random.randint(1,4, size=arr_len),

                   #Hier sind weitere Meta-Tabellen über eine ID verlinkt
                   #Die Links enthalten Zeiger zu den .mat - Files
                   'link_1': np.random.randint(1,8000, size=arr_len),
                   'link_2': np.random.randint(1,8000, size=arr_len),
                   'link_3': np.random.randint(1,8000, size=arr_len),
                   'link_4': np.random.randint(1,8000, size=arr_len),
                   
                   #Direkte Datensätze
                   'some_str_1' : [lorem.sentence() for i in range(arr_len)],
                   'some_str_2' : [lorem.sentence() for i in range(arr_len)],
                   'some_float_1' : np.random.uniform(0,100,arr_len),
                   'some_int': np.random.randint(1,100, size = arr_len),
                   
                   #Hier ist ein Pfad welcher auf eine .csv - Tabelle zeigt
                   'zeiger_1': [lorem.sentence() for i in range(arr_len)],

                   })

#sample .csv Tabelle
arr_len = 420   #dieser Wert schwankt in Wirklichkeit etwas
df = pd.DataFrame({'id': np.arange(arr_len),
                   'date' : np.array([base + datetime.timedelta(hours=i) for i in range(arr_len)]),
                   #Hier muss Metadata aus anderen Tabellen nachgeschlagen werden
                   'index_1': np.random.randint(1,2,size=arr_len),
                   'index_2': np.random.randint(1,3,size=arr_len),
                   'index_3': np.random.randint(1,4, size=arr_len),
                   'index_4' : np.random.randint(1,4, size=arr_len),
                   
                   #Direkte Datensätze
                   'some_float_1' : np.random.uniform(0,100,arr_len),
                   'some_float_2' : np.random.uniform(0,30,arr_len),
                   'some_float_3' : np.random.uniform(0,30,arr_len),
                   'some_float_4' : np.random.uniform(0,30,arr_len),
                   
                   'some_int_1': np.random.randint(1,100, size = arr_len),
                   'some_int_2': np.random.randint(1,200, size = arr_len),
                   'some_int_3': np.random.randint(1,300, size = arr_len),
                   'some_int_4': np.random.randint(1,100, size = arr_len),
                   'some_int_5': np.random.randint(1,100, size = arr_len),
                   'some_int_6': np.random.randint(0,100, size = arr_len),    
                   'some_int_7': np.random.randint(1,100, size = arr_len),
                   'some_int_8': np.random.randint(0,100, size = arr_len), 
                   'some_int_9': np.random.randint(1,100, size = arr_len),
                   'some_int_10': np.random.randint(0,100, size = arr_len), 
                   })

#sample .mat
def mat():
    pass

arr_len = 16383
mat.x = np.arange(arr_len)
mat.y = np.random.uniform(0,10,arr_len)
Nur zum Speichern und Rechnen mit vielen Daten sind SQL-Datenbanken langsam. Wenn es Dir denn um Geschwindigkeit geht (und das sollte es erst, wenn Du Probleme damit hast), dann sind DataFrames die als Binärdaten in eine Datei geschrieben werden, das schnellste, was geht. Bevor Du hier also etwas so kompliziertest machst, mach es ersteinmal so einfach wie möglich, und warte, bis es Probleme gibt.
Ich arbeite immer nur mit einem Snapshot aller Daten.
Das heißt du würdest ein großes Dataframe mit eingebetteten Arrays und .csv-Tabellen erstellen und dieses beispielsweise mit pickle speichern?

Wie würdest du die Indizierung nutzen?
Übersetzen und mit Strings im Dataframe zu arbeiten erscheint mir wenig sinnvoll...
Ein hybrides Modell aus sql Index Tabellen und dem Daten-DataFrame?

VG
Antworten