sqlite - gibts gründe, das nicht zu nutzen?
frankx
- datenbank
Ahoi,
angenommen eine Datenbank mit 2.000 - 5.000 Einträgen, nicht allzuviele, beschreibende Personendaten, ggf. noch Zuordnungen untereinander, die Einträge werden nur von _einem_ Admin verwaltet. Macht es da Sinn, sqlite (mit PHP) zu nutzen? Die Daten sind alle auch anderswo veröffentlicht, als öffentliche Personen sozusagen.
Dank und Gruß,
echo $begrüßung;
Macht es da Sinn, sqlite (mit PHP) zu nutzen?
Ich zitiere mal bewusst gekürzt nur diese Frage. Grundsätzlich sage ich ja. Bis zu einer gestimmten (Projekt-)Größe, die ich dir aber nicht nennen kann, weil mir da die Erfahrung fehlt. SQLite läuft als Bibliothek und damit als Bestandteil des Programms und ein Funktionsaufruf ist schneller ausgeführt als eine Interprozesskommunikation zwischen Client und DBMS. Allerdings muss beim Schreiben die gesamte Datei gesperrt werden, so dass der Schreiberling erst warten muss, bis alle Leser fertig sind und neue Leser ihrerseits müssen warten bis der Schreiber fertig ist. Paralleles Lesen ist jedoch problemlos möglich. Wenn also viel geschrieben werden muss, ist das sicher nicht sehr performant. Der eingeschränkte Funktionsumfang ist auch ein zu beachtender Punkt. Aber man kann eigene Funktionalität anflanschen, soweit ich weiß.
Meine Entscheidung würde ich abhängig machen vom Vorhandensein "ausgewachsener" DBMS oder wenn besondere Gründe für SQLite sprechen (Portabilität der Anwendung und geringe Datenmenge sowie funktionale Ansprüche).
echo "$verabschiedung $name";
Ahoi dedlfix,
ein Vorteil, beim Lesen, fiel mir ein: die Daten können gut lokal erstellt, bearbeitet werden, und dann per ftp ausgetauscht werden, oder?
Portabilität spielt im Grunde nicht so eine Rolle. Schlussendlich ist es ja aber offenbar nicht wirklich ein "Problem", das u.U. dann einem MySQL Server irgendwann zu füttern, denn ein "Dump" dürfte ja SQL ausspucken, oder?
Dank und Gruß,
echo $begrüßung;
btw: dazu fällt dir nix ein, oder?
Nö, denn ich hab ja die Behauptung nicht aufgestellt, und bin auch nicht im Thema drin, um da was sagen zu können.
echo "$verabschiedung $name";
Ahoi,
Nö, denn ich hab ja die Behauptung nicht aufgestellt, und bin auch nicht im Thema drin, um da was sagen zu können.
Naja, du wärst noch am Drinnsten von allen hier gewesen, würd ich mal sagen (;-).
Dank und Gruß,
Ahoi,
echo $begrüßung;
»» btw: dazu fällt dir nix ein, oder?
Nö, denn ich hab ja die Behauptung nicht aufgestellt, und bin auch nicht im Thema drin, um da was sagen zu können.
Kritikpunkt war ja, dass vielleicht "die falschen Sachen abstrahiert werden".
Aus meiner Sicht abstrahieren die Klassen aber ganix. Sie bilden ein einheitliches Interface (Zend_Db_Adapter_Abstract) für ein PDO, unabhängig vom dahinterstehenden RDBMS.
Vergleich:
//PHP Data Object
$pdo = new PDO("sqlite:test.db");
//Zend_Db_Adapter_Pdo_Sqlite
$dba = Zend_Db::factory("PDO_Sqlite",array("dbname"=>"test.db"));
// SQL-Ausruck
$all = "SELECT * FROM test_table";
// Array als Rückgabe:
$pdo->query($all)->fetchAll();
// oder
$dba->fetchAll($all);
Db_Adapter bringt u.a. auch noch eine passende insert-Methode mit, man kann einen Profiler zum Debugging aktivieren, und mit weiteren Klassen interagieren, wie Zend_Db_Statement (basieren auf PDOStatement) und einem Zend_Db_Select-Objekt: $dba->query($dba->select()->from("table_name"))->fetchAll())
.
Der Adapter versteht natürlich dann eben auch die Zend_Config-Objekte und kann wiederum von Zend_Db_Table benutzt werden, was pro Tabelle mit einer eigenen Klasse beerbt werden muss, und weitere Funktionalitäten mit sich bringt.
Mal pointiert in den Raum gestellt: abstrahiert wird da aus meiner Sicht garnix, oder verstehe ich "Abstraktion" falsch? Das ist doch einer eine Frage der "Convinience". Ein Interface ist doch keine Abstraktion im Sinne eines ORM, oder? Ich dacht eher eine einheitliche Schnittstelle, um im o.g. Falle a) unabhängig vom dahinterliegenden Datenbanksystem codieren zu können und b) von anderen Klassen des Frameworks genutzt zu werden.
Dank und Gruß,
echo $begrüßung;
Aus meiner Sicht abstrahieren die Klassen aber ganix. Sie bilden ein einheitliches Interface (Zend_Db_Adapter_Abstract) für ein PDO, unabhängig vom dahinterstehenden RDBMS.
Genau das ist die Abstraktion an der Stelle, die Bildung einer einheitlichen Oberfläche unabhängig von der dahinterstehenden konkreten Implementation. Außerdem ist ja nicht nur PDO vertreten, sondern auch diverse native Implementationen (mysqli neben PDO_mysql beispielsweise). Verwechsle bitte nicht diese Abstraktion des DB-Zugriffs und dessen Oberfläche/Schnittstelle mit den Begriffen Interface und abstrakte Klassen/Methoden aus der OOP. Stell dir einfach vor, der DB-Layer wäre nicht in OOP realisiert und dann tauchten die OOP-Schlüsselwörter abstract und interface nicht auf. Es bleibt aber, dass der DB-Layer eine Abstraktion unterschiedlicher DBMS ist und eine Schnittstelle hat, über die das Hauptprogramm mit ihm kommuniziert.
Zend_Db_Statement (basieren auf PDOStatement)
(Vom Funktionsumfang gesehen mag das vielleicht so sein, nicht aber von der Vererbung/Klassenhierarchie.)
Zend_Db_Select-Objekt
Beides sind Abstraktionen. Zend_Db_Statement ist die Abstraktion eines Prepared Statements und Zend_Db_Select die eines SQL-SELECT-Statements.
Mal pointiert in den Raum gestellt: abstrahiert wird da aus meiner Sicht garnix, oder verstehe ich "Abstraktion" falsch?
Ja, du verstehst das anscheinend falsch.
Das ist doch einer eine Frage der "Convinience".
So eine Abstraktion ist "convenient" (angenehm, komfortabel, bequem, ...), weil man eine einheitliche Oberfläche/Schnittstelle hat und nicht mehrere. Und Convenience ist das Ziel der Abstraktion (das man sich mit zusätzlicher Komplexität erkauft, auch wenn es nach außen hin einfacher aussieht als ein Zugriff über konkrete DBMS-individuelle Komponenten).
Ein Interface ist doch keine Abstraktion im Sinne eines ORM, oder?
Welches Interface meinst du? Das aus der OOP ist hier fehl am Platz. Und ein ORM hat natürlich zwei Schnittstellen, eine zum DBMS hin und eine zum Hauptprogramm hin. (Und die Implementation in OOP verwendet möglicherweise Interfaces, aber das ist eine andere Geschichte.)
Ist ein ORM eine Abstraktion? Meiner Meinung nach nicht unbedingt. In erster Linie sehe ich es als eine Konvertierschicht zwischen zwei Philosophien, mit Daten umzugehen. Eine Abstraktion wird es dann, wenn es unterschiedliche Arten des Zugriffs vereinheitlicht. "Unter" dem ORM ist es ja schon einheitlich. Entweder durch den DB-(Abstraktions-)Layer oder weil der ORM nur auf einem einzigen DBMS aufsetzt. Es mag sicher auch Implementationen geben, wo ORM und DB-Layer eins sind und dann noch diverse DBMS bedient werden können. Dann konvertiert und abstrahiert dieses Konglomerat in Personalunion (und hat eine Schnittstelle über die die Programmlogik zugreift).
Ich dacht eher eine einheitliche Schnittstelle, um im o.g. Falle a) unabhängig vom dahinterliegenden Datenbanksystem codieren zu können und b) von anderen Klassen des Frameworks genutzt zu werden.
Abstraktion eben.
echo "$verabschiedung $name";
Ahoi,
»» Mal pointiert in den Raum gestellt: abstrahiert wird da aus meiner Sicht garnix, oder verstehe ich "Abstraktion" falsch?
Ja, du verstehst das anscheinend falsch.
»» Kritikpunkt war ja, dass vielleicht "die falschen Sachen abstrahiert werden".
Ich frage mich dann eben, was soll denn da "falsch abstrahiert" worden sein, wenn die Zurverfügungstellung von Interfaces aus Conveniencegründen Abstraktion bedeutet, was ja durchaus gefühlt einleuchtend erscheint - warum ORM kein Abstraktion sein soll, fand ich jetz eher kontra-intuitiv.
Die Funktionalität basiert ja insofern auf PDO, also dass die Klasse als zentrale Eigenschaft ein PDO initialisiert (nicht erbt, eine Klassenvariable ist ein PDO). Der Ansatz ist doch schlicht eine Vereinheitlichung des Zugriffs, unabhängig vom Datenbanksystem. Und die Methoden sind denen der PDO-Klasse angepasst.
Dank und Gruß,
echo $begrüßung;
Ich frage mich dann eben, was soll denn da "falsch abstrahiert" worden sein,
Den Punkt klammere ich aus, weil ich ihn nicht in die Diskussion gebracht habe und die Argumente nicht kenne.
wenn die Zurverfügungstellung von Interfaces aus Conveniencegründen Abstraktion bedeutet, was ja durchaus gefühlt einleuchtend erscheint - warum ORM kein Abstraktion sein soll, fand ich jetz eher kontra-intuitiv.
Eine Abstraktion setzt auf viele verschiedene Systeme einen Deckel derart, dass nach oben hin alles gleich aussieht. Ein ORM ist ein Konverter von einer Tabelle(nstruktur) in ein(e) Objekt(struktur). Jede Tabelle bekommt ihre eigene Klasse, denn jede Tabelle unterscheidet sich von einer anderen durch ihre individuellen Felder, die sich in jeweils individuellen Eigenschaften der Klasse widerspiegeln müssen. Mit einem ORM wird nichts vereinheitlicht. Die Individualität bleibt bestehen, sieht nur anders aus.
echo "$verabschiedung $name";
Ahoi,
echo $begrüßung;
»» Ich frage mich dann eben, was soll denn da "falsch abstrahiert" worden sein,
Den Punkt klammere ich aus, weil ich ihn nicht in die Diskussion gebracht habe und die Argumente nicht kenne.
Immerhin scheint es ja nix offensichtliches zu sein und die Abstraktion ist angepasst an die Gepflogenheiten von PHP (PDO) bzw. des Zend-Frameworks. Ich dachte ja, ich würde irgendwas "krudes" finden, das gelang mir aber nicht.
»» wenn die Zurverfügungstellung von Interfaces aus Conveniencegründen Abstraktion bedeutet, was ja durchaus gefühlt einleuchtend erscheint - warum ORM kein Abstraktion sein soll, fand ich jetz eher kontra-intuitiv.
Eine Abstraktion setzt auf viele verschiedene Systeme einen Deckel derart, dass nach oben hin alles gleich aussieht. Ein ORM ist ein Konverter von einer Tabelle(nstruktur) in ein(e) Objekt(struktur). Jede Tabelle bekommt ihre eigene Klasse, denn jede Tabelle unterscheidet sich von einer anderen durch ihre individuellen Felder, die sich in jeweils individuellen Eigenschaften der Klasse widerspiegeln müssen. Mit einem ORM wird nichts vereinheitlicht. Die Individualität bleibt bestehen, sieht nur anders aus.
Und eben dass soll die Zend_Db_Adapter-Klasse ja auch garnicht sein. Lang gesucht, keine "falschen Abstraktionen" gefunden, ab zu den Akten.
Dank und Gruß,
echo $begrüßung;
ein Vorteil, beim Lesen, fiel mir ein: die Daten können gut lokal erstellt, bearbeitet werden, und dann per ftp ausgetauscht werden, oder?
Ja, denn es ist ja nur eine Datei (oder mehrere), die in Reichweite der Anwendung liegen (müssen).
Portabilität spielt im Grunde nicht so eine Rolle. Schlussendlich ist es ja aber offenbar nicht wirklich ein "Problem", das u.U. dann einem MySQL Server irgendwann zu füttern, denn ein "Dump" dürfte ja SQL ausspucken, oder?
Ja, so ein Dump erzeugt SQL, wobei man da beim Ausgeben und Einlesen auf die Angabe der richtige Kodierung achten muss. Die SQLite-Datenbank-Dateien hingegen muss man einfach nur kopieren.
echo "$verabschiedung $name";
Ahoi,
Ja, so ein Dump erzeugt SQL, wobei man da beim Ausgeben und Einlesen auf die Angabe der richtige Kodierung achten muss. Die SQLite-Datenbank-Dateien hingegen muss man einfach nur kopieren.
Kodierung? utf8 vs. iso-8859-1?
Dank und Gruß,
echo $begrüßung;
» Ja, so ein Dump erzeugt SQL, wobei man da beim Ausgeben und Einlesen auf die Angabe der richtige Kodierung achten muss.
Kodierung? utf8 vs. iso-8859-1?
Genau diese.
echo "$verabschiedung $name";
Ahoi,
angenommen eine Datenbank mit 2.000 - 5.000 Einträgen, nicht allzuviele, beschreibende Personendaten, ggf. noch Zuordnungen untereinander, die Einträge werden nur von _einem_ Admin verwaltet. Macht es da Sinn, sqlite (mit PHP) zu nutzen? Die Daten sind alle auch anderswo veröffentlicht, als öffentliche Personen sozusagen.
Alternative zu sqlite wäre ja zB. einfach ein serialisiertes Array. Wie schaut es denn bei 3.000 Datensätzen mit je ein paar Zeilen Text pro Datensatz aufgeteilt in verschiedene Variablen mit der "Performance" aus. Liest sqlite um Datensatz-X zu extrahieren, oder einige zu Filtern immer die komplette DB in den Arbeitsspeicher ein oder durchläuft ("parst") es das Stückweise?
Macht es sozusagen einen "performancetechnisch" einen Unterschied, ob ich
SELEFT FROM meinedaten WHERE plz LIKE '1%'
oder
foreach ($meinedaten as $datum) {
if($datum[plz]<2000) {
$filtered[] = $datum;
}
}
Oder gilt: über Performanceprobleme macht man sich Gedanken, wenn man sie hat (Sven) und o.g. ist schlicht Geschmackssache?
Dank und Gruß,
echo $begrüßung;
Alternative zu sqlite wäre ja zB. einfach ein serialisiertes Array. [...] Liest sqlite um Datensatz-X zu extrahieren, oder einige zu Filtern immer die komplette DB in den Arbeitsspeicher ein oder durchläuft ("parst") es das Stückweise?
Ganz sicher greift SQLite datenbanküblicherweise mit diversen Abkürzungen, beispielsweise einem Index, auf die Daten zu. PHPs Serialisierung kann das nicht. Es ist wie bei einer Textdatei, bei der man nicht wahllos auf eine beliebige Zeile zugreifen kann, weil deren Position sich nicht berechnen lässt sondern sich nur aus den vorhergehenden Zeilen ergibt.
Inwieweit das bei deinem geringen Datenbestand ins Gewicht fällt, müsstest du einfach mal ausprobieren.
echo "$verabschiedung $name";
Ahoi,
Ganz sicher greift SQLite datenbanküblicherweise mit diversen Abkürzungen, beispielsweise einem Index,
Ja, so hatte ich das auch verstanden. Wenn ich einen primary_key, oder index unique definiere, würde es mit
SELECT FROM mydata WHERE ID = 123 wohl direkt den Datensatz picken.
Wobei es bei
SELECT FROM mydata WHERE NAME = "Herr Müller" schon anders aussieht, oder?
Dank und Gruß,
yo,
Wobei es bei
SELECT FROM mydata WHERE NAME = "Herr Müller" schon anders aussieht, oder?
wer hindert dich den, auch über die spalte name einen index anzulegen, wenn er den gebraucht wird ?
Ilja
Ahoi,
»» SELECT FROM mydata WHERE NAME = "Herr Müller" schon anders aussieht, oder?
wer hindert dich den, auch über die spalte name einen index anzulegen, wenn er den gebraucht wird ?
Bisher meine Unkenntnis, jetzt nicht mehr (;-).
Dank und Gruß,
Moin!
Alternative zu sqlite wäre ja zB. einfach ein serialisiertes Array. Wie schaut es denn bei 3.000 Datensätzen mit je ein paar Zeilen Text pro Datensatz aufgeteilt in verschiedene Variablen mit der "Performance" aus. Liest sqlite um Datensatz-X zu extrahieren, oder einige zu Filtern immer die komplette DB in den Arbeitsspeicher ein oder durchläuft ("parst") es das Stückweise?
Du musst vor allem bedenken, dass du mit der Serialisierungsvariante immer den gesamten Datenbestand im Speicher rumschleppst. Das kann sinnvoll sein, das kann aber auch hinderlich sein.
Oder gilt: über Performanceprobleme macht man sich Gedanken, wenn man sie hat (Sven) und o.g. ist schlicht Geschmackssache?
Ja, Performanceprobleme sind dann relevant, wenn man sie erlebt, und die Art der Datenspeicherung ist immer auch eine Geschmacksfrage. Allerdings kann man sich bei manchen Projekten nie sicher sein, dass die Datenmenge nicht doch mal anwächst - warum auch immer - so dass es grundsätzlich keine schlechte Idee ist, die Speicherung lieber einem Subsystem zu übergeben, was darauf ausgerichtet ist, Daten zu speichern und schnell wiederzufinden.
- Sven Rautenberg
Ahoi Sven,
den gesamten Datenbestand im Speicher rumschleppst. Das kann sinnvoll sein,
Was wäre denn ein Paradebeispiel für Sinnvollsein in dem Zusammenhang?
Ja, Performanceprobleme sind dann relevant, wenn man sie erlebt, und die Art der Datenspeicherung ist immer auch eine Geschmacksfrage. Allerdings kann man sich bei manchen Projekten nie sicher sein, dass die Datenmenge nicht doch mal anwächst - warum auch immer - so dass es grundsätzlich keine schlechte Idee ist, die Speicherung lieber einem Subsystem zu übergeben, was darauf ausgerichtet ist, Daten zu speichern und schnell wiederzufinden.
Eben drum. SQL ist halt für den Moment etwas sperriger, wenn mans nicht gewohnt ist.
1. Zeitstempel: PHPs time() gibt es ja bei SQL nicht, UNIX_TIME/TIMESTAMP hat ja ein anderes Format. Nehm ich dann für time() aber BIGINT oder VARCHAR?
2. eine URL, ist es schlau die mit VARCHAR(30) zu beschränken? Oder raubt VARCHAR keinen Platz, wenn es nicht voll ausgenutzt wird?
3. Felder hinzufügen mit ALTER TABLE ist wohl kein Problem?
4. Den Typ BOOLEAN gibt es nicht? Nehm ich lieber CHAR(1) mit 0 und 1 oder hab ich was übersehen? Wie speicher ich denn on/off - Werte gescheit?
Dank und Gruß,
Robet aka
Moin!
»» den gesamten Datenbestand im Speicher rumschleppst. Das kann sinnvoll sein,
Was wäre denn ein Paradebeispiel für Sinnvollsein in dem Zusammenhang?
Ich hab mal ein Skript geschrieben, das regelmäßig jede Minute einen Börsenkurs abgefragt hat. Weil der Kurs u.a. auf der Startseite eingebunden wurde, und auch per AJAX aktualisiert werden sollte, und weil es blöd war, für diese kleine Datenmenge irgendeinen anderen Speicher zu verwenden, hab' ich die Werte per Cronjob via PHP-CLI abgefragt und dann als include-Datei passenden PHP-Code auf Platte geschrieben.
Merkmale der Lösung: Winziges Problem, keinerlei Aussicht auf unendliche Ausdehnung, winzige Datenmenge, keine Möglichkeit, alternative Speicherlösungen zu nutzen.
3000+ Datensätze hätte ich damit nicht mehr verwalten wollen, die Aufgabe schreit eigentlich schon direkt nach einer Datenbank. Und insbesondere, wenn PHP mit SQLite schon eine integrierte Lösung mitbringt (sofern sie verfügbar ist), und man nicht noch separat eine z.B. MySQL-Datenbank beschaffen muss, wäre das definitiv meine Wahl.
Mit den entsprechenden DB-Abstraktions-Layern wie PDO ist auch der Zugriff verhältnismäßig standardisiert.
Eben drum. SQL ist halt für den Moment etwas sperriger, wenn mans nicht gewohnt ist.
Da kommst du aber kaum drum herum, bzw. du solltest es kennen. Entwickler-Grundwissen.
- Zeitstempel: PHPs time() gibt es ja bei SQL nicht, UNIX_TIME/TIMESTAMP hat ja ein anderes Format. Nehm ich dann für time() aber BIGINT oder VARCHAR?
Du verwendest den von der DB angebotenen Datentypen für Zeitpunkte, und wandelst, sofern der Bedarf besteht, im SELECT in die passende Ausgabeform, bzw. rückwärts beim Schreibzugriff aus dieser Form. In der Regel haben Datenbanken für beide Richtungen Transformationsfunktionen.
- eine URL, ist es schlau die mit VARCHAR(30) zu beschränken? Oder raubt VARCHAR keinen Platz, wenn es nicht voll ausgenutzt wird?
URLs können länger als 30 Zeichen werden - sollen die abgeschnitten werden? VARCHAR belegt in der DB soviel Speicher, wie Zeichen in der Spalte stehen (plus ein festes Offset - siehe DB-Doku). Der einzige Grund, warum man VARCHAR-Felder meiden würde, wäre Performance. Wenn die DB-Tabelle nur aus Datentypen besteht, die feste Feldlängen haben, kann die Position der einzelnen Datensätze evtl. leichter berechnet werden.
- Felder hinzufügen mit ALTER TABLE ist wohl kein Problem?
Sowas ist im Prinzip richtig, aber es sollte nur passieren, wenn sich die Applikation verändert - nicht nur die Daten an sich.
- Den Typ BOOLEAN gibt es nicht? Nehm ich lieber CHAR(1) mit 0 und 1 oder hab ich was übersehen? Wie speicher ich denn on/off - Werte gescheit?
CHAR(1) mit den Werten '0' und '1' ist eine gültige Alternative zu BOOLEAN.
- Sven Rautenberg
Ahoi,
Du verwendest den von der DB angebotenen Datentypen für Zeitpunkte, und wandelst, sofern der Bedarf besteht, im SELECT in die passende Ausgabeform, bzw. rückwärts beim Schreibzugriff aus dieser Form. In der Regel haben Datenbanken für beide Richtungen Transformationsfunktionen.
Naja, wie ich grad auch dedlfix schrieb: mit CURRENT_TIMESTAMP als Default bekomme ich einen Eintrag my_cts in der Form "2009-03-09 12:38:30", durch DATE(my_cts) und TIME(my_cts) erhalte ich dann eben 2009-03-09 bzw 12:38:30, aber ich finde keine Funktion, die mir die Sekunden ab 1.1.1970 ausgibt, wie ich sie für PHPs date() brauchen würde.
Dank und Gruß,
Moin!
»» Du verwendest den von der DB angebotenen Datentypen für Zeitpunkte, und wandelst, sofern der Bedarf besteht, im SELECT in die passende Ausgabeform, bzw. rückwärts beim Schreibzugriff aus dieser Form. In der Regel haben Datenbanken für beide Richtungen Transformationsfunktionen.
Naja, wie ich grad auch dedlfix schrieb: mit CURRENT_TIMESTAMP als Default bekomme ich einen Eintrag my_cts in der Form "2009-03-09 12:38:30", durch DATE(my_cts) und TIME(my_cts) erhalte ich dann eben 2009-03-09 bzw 12:38:30, aber ich finde keine Funktion, die mir die Sekunden ab 1.1.1970 ausgibt, wie ich sie für PHPs date() brauchen würde.
SQLite kennt keinen expliziten Datumstypen. http://www.sqlite.org/datatype3.html SQLite kennt grundsätzlich keine strenge Typisierung von Spalten. Man kann offensichtlich auch Text in Integer-Spalten speichern, ohne dass das zu Zerwürfnissen führen würde, weil SQLite den Datentyp nicht mit der Spalte speichert, sondern mit der einzelnen Zelle.
Dementsprechend schwach ist SQLite auch hinsichtlich der Datumsfunktionen, verglichen z.B. mit MySQL.
Daraus könnte man jetzt folgern, dass die Verwendung von Datumsfunktionen in SQLite eigentlich eher Sache des aufrufenden Programms sein sollte. Dem würde ich allerdings nicht unbedingt zustimmen. strftime() liefert beliebig schön formatierbare Datumsstrings, und die DB versteht insgesamt 12 verschiedene Datumsformate, so dass eigentlich keine Notwendigkeit besteht, dass die Applikation ihrerseits eine Umrechung in UNIX-Timestamps vornimmt.
Wenn die Unix-Timestamps allerdings unumgänglich sind (was in meinen Augen eher eine schlechte Designentscheidung wäre - Datumsbehandlung würde ich immer möglichst komplett in die DB auslagern, und die Werte in der Applikation nur in alle Richtungen "durchreichen"), dann wird SQLite diese Werte ohnehin als Integer speichern.
- Sven Rautenberg
Ahoi Sven,
Daraus könnte man jetzt folgern, dass die Verwendung von Datumsfunktionen in SQLite eigentlich eher Sache des aufrufenden Programms sein sollte. Dem würde ich allerdings nicht unbedingt zustimmen. strftime() liefert beliebig schön formatierbare Datumsstrings, und die DB versteht insgesamt 12 verschiedene Datumsformate, so dass eigentlich keine Notwendigkeit besteht, dass die Applikation ihrerseits eine Umrechung in UNIX-Timestamps vornimmt.
Aber strftime() erwartet doch einen Unix-Zeitstempel, welcher in PHP mit der Funktion time() erzeugt wird und die Sekunden seit 1.1.1970 angibt, oder? Mit 2009-03-09 12:11:10 kann ich den nicht füttern, gelle?
Wenn die Unix-Timestamps allerdings unumgänglich sind (was in meinen Augen eher eine schlechte Designentscheidung wäre - Datumsbehandlung würde ich immer möglichst komplett in die DB auslagern, und die Werte in der Applikation nur in alle Richtungen "durchreichen"), dann wird SQLite diese Werte ohnehin als Integer speichern.
Kommt eigentlich eher daher, dass ich mit time() und date() ganz gut hantieren konnte bisher. Auch Verrechnungen mit größer kleiner und ggf. strtotime() oder aber auch 24*60*60*Tagesanzahl machen sich ja ganz galant. Aber Deine Erwägungen haben sicherlich auch was für sich.
Dank und Gruß,
Moin!
Aber strftime() erwartet doch einen Unix-Zeitstempel, welcher in PHP mit der Funktion time() erzeugt wird und die Sekunden seit 1.1.1970 angibt, oder? Mit 2009-03-09 12:11:10 kann ich den nicht füttern, gelle?
strftime() in SQLite nicht, wie mir scheint.
»» Wenn die Unix-Timestamps allerdings unumgänglich sind (was in meinen Augen eher eine schlechte Designentscheidung wäre - Datumsbehandlung würde ich immer möglichst komplett in die DB auslagern, und die Werte in der Applikation nur in alle Richtungen "durchreichen"), dann wird SQLite diese Werte ohnehin als Integer speichern.
Kommt eigentlich eher daher, dass ich mit time() und date() ganz gut hantieren konnte bisher. Auch Verrechnungen mit größer kleiner und ggf. strtotime() oder aber auch 24*60*60*Tagesanzahl machen sich ja ganz galant. Aber Deine Erwägungen haben sicherlich auch was für sich.
Meine oberste Prämisse: Zeitberechnung hat sich in genau EINEM System abzuspielen, niemals in mehreren. Nur so vermeidet man Inkompatibilitäten wegen der Nichtbeachtung irgendeines Kleingedruckten. Wenn du in PHP mit der Zeit rechnen willst, dann nimm PHP. Die Datenbank ist dann reiner Speicher.
Da aber üblicherweise in DB-Abfragen doch wieder Zeitkomponenten reinkommen, die man eventuell nicht vorberechnen kann, besteht die Tendenz, Zeitberechnung AUCH in der DB zu machen. Dann aber sollte man sie AUSSCHLIESSLICH in der DB machen, nicht mehr in PHP.
- Sven Rautenberg
Hallo,
Da aber üblicherweise in DB-Abfragen doch wieder Zeitkomponenten reinkommen, die man eventuell nicht vorberechnen kann, besteht die Tendenz, Zeitberechnung AUCH in der DB zu machen. Dann aber sollte man sie AUSSCHLIESSLICH in der DB machen, nicht mehr in PHP.
... und dann wären wir an einem Punkt der Ausgangsfragestellung angelangt:
dies wäre ein Grund, SQLite nicht zu benutzen, so wie es auch im Handbuch steht:
<zitat>
"In order to achieve simplicity, SQLite has had to sacrifice other
characteristics that some people find useful, such as high concurrency,
fine-grained access control, a rich set of built-in functions, stored
procedures, esoteric SQL language features, XML and/or Java extensions,
tera- or peta-byte scalability, and so forth. If you need some of these
features and do not mind the added complexity that they bring, then
SQLite is probably not the database for you.
[...]
Another way to look at SQLite is this: SQLite is not designed to replace
Oracle. It is designed to replace fopen()."
</zitat>
Freundliche Grüße
Vinzenz
Ahoi Vinzenz,
»» Da aber üblicherweise in DB-Abfragen doch wieder Zeitkomponenten reinkommen, die man eventuell nicht vorberechnen kann, besteht die Tendenz, Zeitberechnung AUCH in der DB zu machen. Dann aber sollte man sie AUSSCHLIESSLICH in der DB machen, nicht mehr in PHP.
... und dann wären wir an einem Punkt der Ausgangsfragestellung angelangt:
dies wäre ein Grund, SQLite nicht zu benutzen, so wie es auch im Handbuch steht:<zitat>
"In order to achieve simplicity, SQLite has had to sacrifice other
characteristics that some people find useful, such as high concurrency,
fine-grained access control, a rich set of built-in functions, stored
procedures, esoteric SQL language features, XML and/or Java extensions,
tera- or peta-byte scalability, and so forth. If you need some of these
features and do not mind the added complexity that they bring, then
SQLite is probably not the database for you.
[...]
Another way to look at SQLite is this: SQLite is not designed to replace
Oracle. It is designed to replace fopen()."
</zitat>
Ja. In dem Fall entscheide ich mich vermutlich dafür, die wenn überhaupt nötige Logik bei PHP zu belassen, und zB. einen Zeitstempel mit PHPs time() zu erstellen, wobei ich mittlerweile sogar zweifle, ob das Erstellungsdatum für mich Relevanz hat. Simples Fazit: für reines Speichern und Basic SQL taugt das ganze, ist dann zB. auch mit Zend_DB "kompatibel", bzw. dort aus dem Quickstartbeispiel vom Zend-Framework ja auch entnommen, als Vorbild.
Dank und Gruß,
Moin!
»» Da aber üblicherweise in DB-Abfragen doch wieder Zeitkomponenten reinkommen, die man eventuell nicht vorberechnen kann, besteht die Tendenz, Zeitberechnung AUCH in der DB zu machen. Dann aber sollte man sie AUSSCHLIESSLICH in der DB machen, nicht mehr in PHP.
Auf der anderen Seite sind SQL-Abfragen, die dynamisch mit Funktionsergebnissen rechnen, wie sie naturgemäß von Funktionen wie NOW() zurückgegeben werden, immer ein Kandidat für schlechtere Performance, weil aufgrund des dynamischen Funktionsergebnisses der Query-Cache vermutlich nicht genutzt werden kann. Abfragen mit konkret statischem Datum, selbst wenn es vom abfragenden Skript nur dynamisch vorberechnet ist, aber dann statisch im Query landet, lassen sich, sofern die betreffenden Tabellen nicht verändert werden, aus dem Cache bedienen, was erheblich die Performance steigert.
Diese Überlegungen treffen aber natürlich nur zu, wenn man wirklich ein DB-Performanceproblem hat. Wenn man vor der Wahl steht, irgendein Eigengebräu als Speicher zu verwenden, oder eine Datenbank, dann steht man vermutlich noch nicht vor einer Performancefrage.
... und dann wären wir an einem Punkt der Ausgangsfragestellung angelangt:
dies wäre ein Grund, SQLite nicht zu benutzen, so wie es auch im Handbuch steht:<zitat>
"In order to achieve simplicity, SQLite has had to sacrifice other
characteristics that some people find useful, such as high concurrency,
fine-grained access control, a rich set of built-in functions, stored
procedures, esoteric SQL language features, XML and/or Java extensions,
tera- or peta-byte scalability, and so forth. If you need some of these
features and do not mind the added complexity that they bring, then
SQLite is probably not the database for you.
[...]
Another way to look at SQLite is this: SQLite is not designed to replace
Oracle. It is designed to replace fopen()."
</zitat>
Wenn ich die Wahl hätte, ein Eigengewächs mit fopen() zu nutzen, oder SQLite, dann fiele meine Wahl vermutlich oftmals auf SQLite.
Bestünde die Wahl zwischen SQLite und MySQL, wählte ich vermutlich MySQL.
:)
- Sven Rautenberg
Ahoi,
Wenn ich die Wahl hätte, ein Eigengewächs mit fopen() zu nutzen, oder SQLite, dann fiele meine Wahl vermutlich oftmals auf SQLite.
Na wenn dann unserialize(file_get_contents("bla.blub")),
naja, oder fgetcsv() in Kombination mit fopen();
Dank und Gruß,
Hallo Robert,
» Wenn ich die Wahl hätte, ein Eigengewächs mit fopen() zu nutzen, oder SQLite, dann fiele meine Wahl vermutlich oftmals auf SQLite.
ich sehe das genauso.
Na wenn dann unserialize(file_get_contents("bla.blub")),
naja, oder fgetcsv() in Kombination mit fopen();
ziehe ich beides nicht ernsthaft in Betracht. Wozu?
Wie ich neulich schon schrieb: selbst für einen simplen Counter (so ich einen wollte), nutze ich eine DB und nicht komplizierten Textdateizugriff. Ich sähe den DB-Einsatz, insbesondere den von SQLite, auch nicht als "mit Kanonen auf Spatzen schießen" an.
Freundliche Grüße
Vinzenz
Hi,
Wie ich neulich schon schrieb: selbst für einen simplen Counter (so ich einen wollte), nutze ich eine DB und nicht komplizierten Textdateizugriff.
Dafür kann man doch auch so schön PHPs Sessions missbrauchen :-)
MfG ChrisB
Moin!
Na wenn dann unserialize(file_get_contents("bla.blub")),
Locking, anyone?
naja, oder fgetcsv() in Kombination mit fopen();
CSV ist kein Dateiformat, es ist eine Krankheit! Also: Meiden!
- Sven Rautenberg
Ahoi,
»» Na wenn dann unserialize(file_get_contents("bla.blub")),
Locking, anyone?
Wenn nur einer schreibt und der Rest nur liest?
»» naja, oder fgetcsv() in Kombination mit fopen();
CSV ist kein Dateiformat, es ist eine Krankheit! Also: Meiden!
Naja, Vinzenz sieht das nicht ganz so http://forum.de.selfhtml.org/archiv/2007/11/t161538/#m1051658 (;-).
Es ist gut geeignet für Contentpflege bei sich schnell änderenden Daten (Veranstaltungsdaten) die vom Halbkundigen Kunden gepflegt werden wollen.
Der macht das sowieso in Excel, das kann er. Dan nimmt man OpenOffice um eine "echtes" CSV draus zu machen und lädt das Teil hoch, fertig. Macht der Kunde komplett selbst. Und das Format ist, wenn stringent umgesetzt http://tools.ietf.org/html/rfc4180 doch wirklich prima. Und schlank.
Dank und Gruß,
Moin!
»» »» Na wenn dann unserialize(file_get_contents("bla.blub")),
»»
»» Locking, anyone?Wenn nur einer schreibt und der Rest nur liest?
Ich wollt's nur mal erwähnt haben. SQLite macht das von alleine, und sobald es um größere Datenmengen geht, wird's ja beim Neuschreiben auch interessant, ob während des Schreibvorgangs Lesen auf halbfertige Daten möglich sind - und was das für Folgen hat.
»» »» naja, oder fgetcsv() in Kombination mit fopen();
»»
»» CSV ist kein Dateiformat, es ist eine Krankheit! Also: Meiden!Es ist gut geeignet für Contentpflege bei sich schnell änderenden Daten (Veranstaltungsdaten) die vom Halbkundigen Kunden gepflegt werden wollen.
Der macht das sowieso in Excel, das kann er. Dan nimmt man OpenOffice um eine "echtes" CSV draus zu machen und lädt das Teil hoch, fertig. Macht der Kunde komplett selbst.
Excel, OpenOffice, Upload - und wenn dabei irgendwo etwas schief geht, dann ist die K... am d...
Ok, vielleicht rettet dir OpenOffice ein wenig den Arsch, wenn es "vernünftiges", d.h. erwartungskonform einheitliches CSV ausspuckt - aber wenn es darum geht, einen allgemeinen CSV-Import herzustellen, dann zerhaut es dich regelmäßig wegen der diversen als CSV bezeichneten Formate. Excel ist da ganz besonders schlimm, nach meiner Erinnerung, weil die Hirnis auch den CSV-Export lokalisiert haben.
Fragen wie "Welches Encoding wurde benutzt, und wie kriege ich das raus?" stellen sich natürlich irgendwann auch.
Und das Format ist, wenn stringent umgesetzt http://tools.ietf.org/html/rfc4180 doch wirklich prima. Und schlank.
Die Spec lässt eindeutig zu viel Raum für Optionales:
Darüber hinaus trifft man in freier Wildbahn viele eklige Varianten an:
Wenn du exakt EINE definierte Applikation hast, die dir dein persönliches CSV-Format auswirft, kannst du den Import auf diese Daten exakt abstimmen. Aber wehe, das Format ändert sich aus irgendeinem Grund...
- Sven Rautenberg
Ahoi,
»» »» »» Na wenn dann unserialize(file_get_contents("bla.blub")),
»» »»
»» »» Locking, anyone?
»»
»» Wenn nur einer schreibt und der Rest nur liest?Ich wollt's nur mal erwähnt haben. SQLite macht das von alleine, und sobald es um größere Datenmengen geht, wird's ja beim Neuschreiben auch interessant, ob während des Schreibvorgangs Lesen auf halbfertige Daten möglich sind - und was das für Folgen hat.
Dann bleibt nur unserialize($row = $mysql->query("SELECT my_ser_data from single_table WHERE id = 1"))) oder in der Art (;-).
Die Spec lässt eindeutig zu viel Raum für Optionales:
- Die letzte Zeile kann CRLF am Ende haben, oder nicht.
Das lässt sich ja noch recht simpel workarrounden, aber eigentlich kein CRLF am Ende
- Die erste Zeile kann eine Header-Zeile sein, oder direkt Daten enthalten.
Das ist doch aber o.k., die Freiheit des Users/Programmierers.
- Felder können in Anführungszeichen stehen, müssen aber nicht.
Naja, eigentlich sollten sie nicht, es sei denn, es kommt Spalten oder Zeilentrenner drin vor.
Wenn du exakt EINE definierte Applikation hast, die dir dein persönliches CSV-Format auswirft, kannst du den Import auf diese Daten exakt abstimmen. Aber wehe, das Format ändert sich aus irgendeinem Grund...
Das ist ja immer klar. An die Definition muss man sich halten. Excel spuckt im Export-Modus Daten aus, die es im Import selbst nicht lesen kann. Zudem schaffst Du es nicht, beim exportieren die Delimiter festzulegen. Wenn Du aber VBAs asCSV-Funktion nutzt (oder wie die heißen mag), kommt wieder was anderes raus. Möglich, dass Excel das dann nicht lesen kann, und das andere schon. Excel immerhin verdirbt einem den Spaß daran, hätten die die streng gefasste Definition befolgt, hätte man diese ganze Diskussion vermutlich garnicht. (es gibt übrigens eigentlich drei ASCII-Zeichen, die als Trenner für sowas mal vorgesehen waren 29-31 oder so).
Dank und Gruß,
echo $begrüßung;
- Zeitstempel: PHPs time() gibt es ja bei SQL nicht, UNIX_TIME/TIMESTAMP hat ja ein anderes Format. Nehm ich dann für time() aber BIGINT oder VARCHAR?
Das Format ist unwichtig und nur eine oberflächliche Erscheinung. Für Unix-Timestamps kennt zumindest MySQL Funktionen zum Umwandeln von und in das interne Format.
- eine URL, ist es schlau die mit VARCHAR(30) zu beschränken? Oder raubt VARCHAR keinen Platz, wenn es nicht voll ausgenutzt wird?
Das VAR steht für variabel, was den belegten Speicherplatz angeht. Hast du dir noch nie Gedanken um den Unterschied zwischen VARCHAR und CHAR gemacht? Dann lies mal in der MySQL-Doku zu den Datentypen nach.
- Felder hinzufügen mit ALTER TABLE ist wohl kein Problem?
Das macht man nicht im laufenden Betrieb. Wenn das nötig ist, hat man ein schlechtes Design gewählt.
- Den Typ BOOLEAN gibt es nicht? Nehm ich lieber CHAR(1) mit 0 und 1 oder hab ich was übersehen? Wie speicher ich denn on/off - Werte gescheit?
Du hast etwas übersehen. BOOLEAN ist (zwar als Alias, aber immerhin) vorhanden. Ansonsten geibt es auch noch ENUM.
echo "$verabschiedung $name";
Ahoi dedlfix und Sven,
»» 1. Zeitstempel: PHPs time() gibt es ja bei SQL nicht, UNIX_TIME/TIMESTAMP hat ja ein anderes Format. Nehm ich dann für time() aber BIGINT oder VARCHAR?
Das Format ist unwichtig und nur eine oberflächliche Erscheinung. Für Unix-Timestamps kennt zumindest MySQL Funktionen zum Umwandeln von und in das interne Format.
$sql_create = "CREATE TABLE anytime (
name VARCHAR(255),
mydate TIMESTAMP DEFAULT CURRENT_TIMESTAMP)";
$sql_insert = "INSERT INTO 'anytime' ('name') VALUES ('hansel')";
$sql_all = "SELECT name, DATE(mydate) AS date, TIME(mydate) AS time FROM 'anytime' WHERE 1";
$pdo = new PDO("sqlite:sqlite4.db");
foreach ($pdo->query($sql_all) as $row) {
echo $row["name"] ."-".$row["date"] ."-".$row["time"] ."\n";
//~ var_dump($row);
}
bringt mir:
hansel-2009-03-09-12:43:05 - so far so good.
Aber UNIX_TIMESTAMP(mydate) bringt mir garnix, (btw auch nicht NOW() as newdate in der SELECT-Anweisung - ich dachte, sowas würde gehen).
Mag mir jemand noch einen Tip geben, wie ich den CURRENT-TIMESTAMP in Sekunden seit 1970 bekomme, um ihn mit PHPs date-Funktion zu verarzten? http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
Dank und Gruß,
echo $begrüßung;
Aber UNIX_TIMESTAMP(mydate) bringt mir garnix, (btw auch nicht NOW() as newdate in der SELECT-Anweisung - ich dachte, sowas würde gehen).
Nichtmal einen Syntax-Fehler? SQLite kennt keine Datums- und Zeit-Typen. Überhaupt ist es, was die Datentypen anbelangt, eingeschränkt. Insofern kannst du es zur Speicherung in beliebigem Format aber kaum zum Verarbeiten der Datums- und Zeitwerte verwenden.
Mag mir jemand noch einen Tip geben, wie ich den CURRENT-TIMESTAMP in Sekunden seit 1970 bekomme, um ihn mit PHPs date-Funktion zu verarzten? http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
Nicht mit SQLite. PHPs strtotime() kann helfen.
echo "$verabschiedung $name";
Ahoi,
»» Aber UNIX_TIMESTAMP(mydate) bringt mir garnix, (btw auch nicht NOW() as newdate in der SELECT-Anweisung - ich dachte, sowas würde gehen).
Nichtmal einen Syntax-Fehler? SQLite kennt keine Datums- und Zeit-Typen.
Aber DATE() und TIME() funktionieren doch (mit CURRENT_TIMESTAMP als Variableninhalt in er Form 2009-03-09 12:38:30).
Und Sven schrub:"Du verwendest den von der DB angebotenen Datentypen für Zeitpunkte, und wandelst, sofern der Bedarf besteht, im SELECT in die passende Ausgabeform, bzw. rückwärts beim Schreibzugriff aus dieser Form. In der Regel haben Datenbanken für beide Richtungen Transformationsfunktionen."
Nicht mit SQLite. PHPs strtotime() kann helfen.
Na dann nehm ich doch lieber gleich time() beim INSERT, oder?
Dank und Gruß,
echo $begrüßung;
Und Sven schrub:"Du verwendest den von der DB angebotenen Datentypen für Zeitpunkte, und wandelst, sofern der Bedarf besteht, im SELECT in die passende Ausgabeform, bzw. rückwärts beim Schreibzugriff aus dieser Form. In der Regel haben Datenbanken für beide Richtungen Transformationsfunktionen."
Ich nehme an, er hat sich genausowenig mit SQLite beschäftigt wie ich. Dem (SQLite) fehlt einfach zu viel um sich großartig darüber Gedanken zu machen, solange Alternativen zur Verfügung stehen.
echo "$verabschiedung $name";
Ahoi,
»» 3. Felder hinzufügen mit ALTER TABLE ist wohl kein Problem?
Das macht man nicht im laufenden Betrieb. Wenn das nötig ist, hat man ein schlechtes Design gewählt.
Wenn man (z.B. für sowas) aber noch nicht weiß, was man schlussendlich in einem Personenprofil für Daten einsammeln möchte, macht man sich dann ein TEXT oder VARCHAR Feld, in das man serialisierte PHP-Arrays schreibt. Vielliecht entsteht ja irgendwann doch der Wunsch nach einem Telefonnummernfeld, oder man möchte für Profile bei Xing oder Facebook (und das wäre ja erweiterbar im laufenden Betrieb) eigenen Felder zur Verfügung stellen, oder irgendwas, was mir eben jetzt noch nicht einfällt. Ein Design ist doch nix "lebensländgliches". Das ist doch vermutlich sogar egal, ob man eher einen Architekturstil oder einen Xtrem-Stil propagiert.
Dank und Gruß,
echo $begrüßung;
Wenn man (z.B. für sowas) aber noch nicht weiß, was man schlussendlich in einem Personenprofil für Daten einsammeln möchte, macht man sich dann ein TEXT oder VARCHAR Feld, in das man serialisierte PHP-Arrays schreibt.
Ein Serialized LOB sozusagen. Kann man machen, aber dann sollte es einen triftigen Grund geben, beispielweise den, dass die Informationen weniger als Feldinhalt sondern mehr in ihren Beziehungen zueinander enthalten ist. Denn suchen kann man in solch einem S-LOB nicht besonders gut. Dann schon eher das Datenbanklayout ändern. Und wenn das im Rahmen einer Updateprozedur stattfindet, ist das vertretbar.
Vielliecht entsteht ja irgendwann doch der Wunsch nach einem Telefonnummernfeld, oder man möchte für Profile bei Xing oder Facebook (und das wäre ja erweiterbar im laufenden Betrieb) eigenen Felder zur Verfügung stellen, oder irgendwas, was mir eben jetzt noch nicht einfällt.
Mit der CouchDB bist du so flexibel, so etwas tun zu können. Dann allerdings sollte auch die Anwendung so geschrieben sein, dass sie mit jeder flexiblen Datenansammlung umgehen kann. Wenn du die Anwendung ändern musst, um das Profil X einfügen zu können und dasselbe in grün für Profil Y machen musst, dann kannst du auch beim Update das DB-Layout anpassen.
echo "$verabschiedung $name";