Flat-File-Datenbanken

stimmen
101

Was sind die besten Praktiken Flat-File-Datenbankstrukturen in PHP um zu erstellen?

Viele des reiferen PHP Flat-File-Frameworks ich da draußen zu sehen versuchen, SQL-ähnliche Abfragesyntax zu implementieren, die für meine Zwecke in den meisten Fällen über die Spitze ist (ich würde nur eine Datenbank zu diesem Zeitpunkt verwenden).

Gibt es elegante Tricks gibt gute Leistung und Funktionen mit einem kleinen Code-Overhead zu bekommen?

Veröffentlicht am 01/08/2008 um 15:19
quelle vom benutzer
In anderen Sprachen...                            


12 antworten

stimmen
68

Nun, was ist das Wesen der flachen Datenbanken. Sind sie groß oder klein. Ist es einfacher Arrays mit Arrays in ihnen? Wenn es einfach etwas Userprofiles als solche gebaut sagen:

$user = array("name" => "dubayou", 
              "age" => 20,
              "websites" => array("dubayou.com","willwharton.com","codecream.com"),
              "and_one" => "more");

und zu speichern oder die Aktualisierung db Rekord für diesen Benutzer.

$dir = "../userdata/";  //make sure to put it bellow what the server can reach.
file_put_contents($dir.$user['name'],serialize($user));

und das laden Datensatz für den Benutzer

function &get_user($name){
    return unserialize(file_get_contents("../userdata/".$name));
}

aber auch hier wird diese Umsetzung in Abhängigkeit von der Anwendung und die Art der Datenbank, die Sie benötigen.

Beantwortet am 01/08/2008 um 18:45
quelle vom benutzer

stimmen
46

Sie sollten erwägen SQLite . Es ist fast so einfach wie flache Dateien, aber Sie tun für die Abfrage einer SQL - Engine erhalten. Es funktioniert gut mit PHP zu.

Beantwortet am 09/08/2008 um 00:00
quelle vom benutzer

stimmen
20

Meiner Meinung nach , im Sinne einer „Flat File - Datenbank“ können Sie Sinn (und die Antwort , die Sie angenommen haben) nicht neccesarily der beste Weg , um Dinge zu gehen. Zunächst einmal verwendet serialize()und unserialize()kann MAJOR Kopfschmerzen verursachen , wenn jemand in bekommt und bearbeitet die Datei (sie können in der Tat, arbiträren Code in Ihrer „Datenbank“ setzen , um jedes Mal ausgeführt werden.)

Persönlich würde ich sagen - warum nicht in die Zukunft blicken? Es gibt so viele Male, dass ich Probleme habe, weil ich habe meine eigenen „proprietär“ Dateien wurde Erstellen und das Projekt bis zu einem Punkt, wo es explodiert eine Datenbank benötigt, und ich denke, „Sie wissen, ich wünsche ich habe dies für eine Datenbank geschrieben mit“beginnen - weil das Refactoring des Codes viel zu viel Zeit und Mühe.

Daraus habe ich die Zukunft Proofing meine Anwendung gelernt, so dass, wenn es größer wird muss ich nach vorne gehen nicht und Tage Refactoring ist der Weg zu gehen zu verbringen. Wie mache ich das?

SQLite. Es funktioniert wie eine Datenbank verwendet SQL und ist recht einfach zu mySQL wechseln (espescially wenn Sie abstrahierten Klassen für Datenbankmanipulation verwenden wie ich!)

In der Tat, espescially mit der „akzeptierte Antwort“ 's Methode, es drastisch die Speichernutzung Ihrer App schneiden können (Sie müssen alle nicht laden die ‚RECORDS‘ in PHP)

Beantwortet am 21/09/2008 um 19:21
quelle vom benutzer

stimmen
15

Das ist richtig. serialize()kann für das auch recht nützlich sein.

Ich denke, der Trick mit einem lebensfähiges System zu kommen ist in gewisser Weise zu indizieren den Datenknoten zu finden, ohne sich mit der Komplexität zu töten.

Beantwortet am 01/08/2008 um 15:58
quelle vom benutzer

stimmen
11

Ein Rahmen Ich erwäge wäre für eine Blogging-Plattform. Da fast jede mögliche Ansicht der Daten würden Sie nach dem Datum sortiert werden würde, dachte ich an dieser Struktur:

Ein Verzeichnis pro Inhaltsknoten:

./content/YYYYMMDDHHMMSS/

Unterverzeichnisse jedes Knotens einschließlich

/tags  
/authors  
/comments  

Neben einfache Textdateien im Knotenverzeichnis für Pre- und Post-gerenderten Inhalt und dergleichen.

Dies würde eine einfache PHP erlaubt glob()Anruf (und wahrscheinlich auch eine Umkehrung des Ergebnis Array) nur um etwas in der Inhaltsstruktur zur Abfrage auf:

glob("content/*/tags/funny");  

Würden Rückweg einschließlich aller Artikel getaggt „funny“.

Beantwortet am 01/08/2008 um 15:26
quelle vom benutzer

stimmen
8

Hier ist der Code, den wir für Lilina verwenden:

<?php
/**
 * Handler for persistent data files
 *
 * @author Ryan McCue <cubegames@gmail.com>
 * @package Lilina
 * @version 1.0
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */

/**
 * Handler for persistent data files
 *
 * @package Lilina
 */
class DataHandler {
    /**
     * Directory to store data.
     *
     * @since 1.0
     *
     * @var string
     */
    protected $directory;

    /**
     * Constructor, duh.
     *
     * @since 1.0
     * @uses $directory Holds the data directory, which the constructor sets.
     *
     * @param string $directory 
     */
    public function __construct($directory = null) {
        if ($directory === null)
            $directory = get_data_dir();

        if (substr($directory, -1) != '/')
            $directory .= '/';

        $this->directory = (string) $directory;
    }

    /**
     * Prepares filename and content for saving
     *
     * @since 1.0
     * @uses $directory
     * @uses put()
     *
     * @param string $filename Filename to save to
     * @param string $content Content to save to cache
     */
    public function save($filename, $content) {
        $file = $this->directory . $filename;

        if(!$this->put($file, $content)) {
            trigger_error(get_class($this) . " error: Couldn't write to $file", E_USER_WARNING);
            return false;
        }

        return true;
    }

    /**
     * Saves data to file
     *
     * @since 1.0
     * @uses $directory
     *
     * @param string $file Filename to save to
     * @param string $data Data to save into $file
     */
    protected function put($file, $data, $mode = false) {
        if(file_exists($file) && file_get_contents($file) === $data) {
            touch($file);
            return true;
        }

        if(!$fp = @fopen($file, 'wb')) {
            return false;
        }

        fwrite($fp, $data);
        fclose($fp);

        $this->chmod($file, $mode);
        return true;

    }

    /**
     * Change the file permissions
     *
     * @since 1.0
     *
     * @param string $file Absolute path to file
     * @param integer $mode Octal mode
     */
    protected function chmod($file, $mode = false){
        if(!$mode)
            $mode = 0644;
        return @chmod($file, $mode);
    }

    /**
     * Returns the content of the cached file if it is still valid
     *
     * @since 1.0
     * @uses $directory
     * @uses check() Check if cache file is still valid
     *
     * @param string $id Unique ID for content type, used to distinguish between different caches
     * @return null|string Content of the cached file if valid, otherwise null
     */
    public function load($filename) {
        return $this->get($this->directory . $filename);
    }

    /**
     * Returns the content of the file
     *
     * @since 1.0
     * @uses $directory
     * @uses check() Check if file is valid
     *
     * @param string $id Filename to load data from
     * @return bool|string Content of the file if valid, otherwise null
     */
    protected function get($filename) {
        if(!$this->check($filename))
            return null;

        return file_get_contents($filename);
    }

    /**
     * Check a file for validity
     *
     * Basically just a fancy alias for file_exists(), made primarily to be
     * overriden.
     *
     * @since 1.0
     * @uses $directory
     *
     * @param string $id Unique ID for content type, used to distinguish between different caches
     * @return bool False if the cache doesn't exist or is invalid, otherwise true
     */
    protected function check($filename){
        return file_exists($filename);
    }

    /**
     * Delete a file
     *
     * @param string $filename Unique ID
     */
    public function delete($filename) {
        return unlink($this->directory . $filename);
    }
}

?>

Es speichert jeden Eintrag als eine separate Datei, die wir effizient genug gefunden für den Einsatz ist (keine nicht benötigten Daten geladen und es ist schneller zu sparen).

Beantwortet am 28/10/2008 um 11:45
quelle vom benutzer

stimmen
8

Wenn Sie eine flache Datei verwenden werden Daten bestehen bleiben, verwenden XML die Daten zu strukturieren. PHP hat einen integrierten XML - Parser .

Beantwortet am 18/09/2008 um 07:40
quelle vom benutzer

stimmen
7

Ich habe zwei einfache Funktionen geschrieben entwickelt, um Daten in einer Datei zu speichern. Sie können selbst beurteilen, ob es in diesem Fall nützlich ist. Der Punkt ist ein PHP-Variable zu speichern (wenn es entweder ein Array eines String oder ein Objekt) in eine Datei.

<?php
function varname(&$var) {
    $oldvalue=$var;
    $var='AAAAB3NzaC1yc2EAAAABIwAAAQEAqytmUAQKMOj24lAjqKJC2Gyqhbhb+DmB9eDDb8+QcFI+QOySUpYDn884rgKB6EAtoFyOZVMA6HlNj0VxMKAGE+sLTJ40rLTcieGRCeHJ/TI37e66OrjxgB+7tngKdvoG5EF9hnoGc4eTMpVUDdpAK3ykqR1FIclgk0whV7cEn/6K4697zgwwb5R2yva/zuTX+xKRqcZvyaF3Ur0Q8T+gvrAX8ktmpE18MjnA5JuGuZFZGFzQbvzCVdN52nu8i003GEFmzp0Ny57pWClKkAy3Q5P5AR2BCUwk8V0iEX3iu7J+b9pv4LRZBQkDujaAtSiAaeG2cjfzL9xIgWPf+J05IQ==';
    foreach($GLOBALS as $var_name => $value) {
        if ($value === 'AAAAB3NzaC1yc2EAAAABIwAAAQEAqytmUAQKMOj24lAjqKJC2Gyqhbhb+DmB9eDDb8+QcFI+QOySUpYDn884rgKB6EAtoFyOZVMA6HlNj0VxMKAGE+sLTJ40rLTcieGRCeHJ/TI37e66OrjxgB+7tngKdvoG5EF9hnoGc4eTMpVUDdpAK3ykqR1FIclgk0whV7cEn/6K4697zgwwb5R2yva/zuTX+xKRqcZvyaF3Ur0Q8T+gvrAX8ktmpE18MjnA5JuGuZFZGFzQbvzCVdN52nu8i003GEFmzp0Ny57pWClKkAy3Q5P5AR2BCUwk8V0iEX3iu7J+b9pv4LRZBQkDujaAtSiAaeG2cjfzL9xIgWPf+J05IQ==')
        {
            $var=$oldvalue;
            return $var_name;
        }
    }
    $var=$oldvalue;
    return false;
}

function putphp(&$var, $file=false)
    {
    $varname=varname($var);
    if(!$file)
    {
        $file=$varname.'.php';
    }
    $pathinfo=pathinfo($file);
    if(file_exists($file))
    {
        if(is_dir($file))
        {
            $file=$pathinfo['dirname'].'/'.$pathinfo['basename'].'/'.$varname.'.php';
        }
    }
    file_put_contents($file,'<?php'."\n\$".$varname.'='.var_export($var, true).";\n");
    return true;
}
Beantwortet am 19/12/2012 um 21:48
quelle vom benutzer

stimmen
6

Dieser ist inspirierender als praktische Lösung:
https://github.com/mhgolkar/FlatFire
Es mehrere Strategien zum Umgang mit Daten verwendet , ...
[aus Readme - Datei kopiert]

Free oder Structured oder Mixed

- STRUCTURED
Regular (table, row, column) format.
[DATABASE]
/   \
TX  TableY
    \_____________________________
    |ROW_0 Colum_0 Colum_1 Colum_2|
    |ROW_1 Colum_0 Colum_1 Colum_2|
    |_____________________________|
- FREE
More creative data storing. You can store data in any structure you want for each (free) element, its similar to storing an array with a unique "Id".
[DATABASE]
/   \
EX  ElementY (ID)
    \________________
    |Field_0 Value_0 |
    |Field_1 Value_1 |
    |Field_2 Value_2 |
    |________________|
recall [ID]: get_free("ElementY") --> array([Field_0]=>Value_0,[Field_1]=>Value_1...
- MIXD (Mixed)
Mixed databases can store both free elements and tables.If you add a table to a free db or a free element to a structured db, flat fire will automatically convert FREE or SRCT to MIXD database.
[DATABASE]
/   \
EX  TY
Beantwortet am 02/05/2013 um 14:57
quelle vom benutzer

stimmen
6

IMHO, haben Sie zwei Möglichkeiten, wenn Sie homebrewing etwas vermeiden wollen:

  1. SQLite

    Wenn Sie mit PDO vertraut sind, können Sie ein PDO-Treiber installieren, die SQLite unterstützt. Nie benutzt, aber ich habe verwendet PDO eine Tonne mit MySQL. Ich werde dies einen Schuss an einem aktuellen Projekt geben.

  2. XML

    Fertig dies viele Male für relativ kleine Datenmengen. XMLReader ist eine leichte, schreib vorwärts, Cursor-Stil - Klasse. SimpleXML macht es einfach , ein XML - Dokument in ein Objekt zu lesen , dass Sie wie jede andere Klasse Instanz zugreifen können.

Beantwortet am 02/12/2012 um 16:49
quelle vom benutzer

stimmen
6

Wenn Sie einen Menschen lesbaren Ergebnis möchten, können Sie auch diese Art von Datei:

ofaurax|27|male|something|
another|24|unknown||
...

Auf diese Weise haben Sie nur eine Datei, können Sie es debuggen (und beheben manuell) leicht, können Sie Felder hinzufügen später (am Ende jeder Zeile) und der PHP-Code ist einfach (für jede Zeile, aufgeteilt nach |).

Allerdings sind die Nachteile, dass Sie die gesamte Datei etwas zu suchen, analysieren sollen (wenn Sie Millionen Eintrag haben, ist es nicht in Ordnung), und Sie sollen den Separator in Daten (zum Beispiel, wenn der nick ist ist | ordz) behandeln.

Beantwortet am 18/09/2008 um 08:51
quelle vom benutzer

stimmen
4

zeigt nur ein mögliches Problem mit einer flachen Datei Datenbank mit dieser Art von System aus:

data|some text|more data

row 2 data|bla hbalh|more data

...etc

Das Problem ist, dass die Zelle Daten enthält ein „|“ oder ein „\ n“ dann werden die Daten verloren. Manchmal wäre es einfacher, durch Kombinationen von Buchstaben zu spalten, die die meisten Leute würden nicht verwenden.

Beispielsweise:

Spalte Splitter: #$% (Shift+345)

Row-Splitter: ^&* (Shift+678)

Textdatei: test data#$%blah blah#$%^&*new row#$%new row data 2

Dann benutze: explode("#$%", $data); use foreach, the explode again to separate columns

Oder irgendetwas in dieser Richtung. Ich könnte auch hinzufügen, dass Flat-File-Datenbanken sind gut für Systeme mit geringen Mengen an Daten (dh. Weniger als 20 Zeilen), aber werden große Speicherfresser für größere Datenbanken.

Beantwortet am 04/01/2013 um 01:14
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more