database file flat

voti
101

Quali sono le migliori pratiche in giro per la creazione di strutture di database di file flat in PHP?

Un sacco di quadri di file flat PHP più mature vedo là fuori tentare di implementare sintassi di query SQL-like, che è sopra le righe per i miei scopi nella maggior parte dei casi (vorrei solo utilizzare un database in quel punto).

Ci sono eleganti trucchi là fuori per ottenere buone prestazioni e le caratteristiche di un piccolo overhead codice?

È pubblicato 01/08/2008 alle 15:19
fonte dall'utente
In altre lingue...                            


12 risposte

voti
11

Un quadro Sto pensando sarebbe per una piattaforma di blogging. Dal momento che quasi ogni eventuale visualizzazione dei dati che si vorrebbe sarebbe ordinato per data, stavo pensando a questa struttura:

Una directory per nodo contenuti:

./content/YYYYMMDDHHMMSS/

Sottodirectory di ogni nodo compreso

/tags  
/authors  
/comments  

Così come semplici file di testo nella directory del nodo per i contenuti pre e post-resa e simili.

Ciò consentirebbe una semplice PHP glob()chiamata (e probabilmente un'inversione della matrice risultato) per interrogare su qualsiasi cosa all'interno della struttura dei contenuti:

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

Sarebbe tornato percorsi tra cui tutti gli articoli con tag "divertente".

Risposto il 01/08/2008 a 15:26
fonte dall'utente

voti
15

È vero. serialize()può essere molto utile per quello.

Credo che il trucco per venire con un sistema vitale è trovare un modo per indicizzare i nodi di dati senza uccidere te stesso con la complessità.

Risposto il 01/08/2008 a 15:58
fonte dall'utente

voti
68

Ebbene, qual è la natura delle basi di dati flat. Sono grandi o piccole. E 'semplice array con gli array in loro? se qualcosa di semplice dire UserProfiles costruite in quanto tale:

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

e di salvare o aggiornare il record di db per quell'utente.

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

e per caricare il disco per l'utente

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

ma ancora una volta questa implementazione varierà sull'applicazione e la natura del database è necessario.

Risposto il 01/08/2008 a 18:45
fonte dall'utente

voti
46

Si potrebbe prendere in considerazione SQLite . E 'quasi come semplice file flat, ma ottieni un motore SQL per l'interrogazione. E funziona bene con PHP troppo.

Risposto il 09/08/2008 a 00:00
fonte dall'utente

voti
8

Se avete intenzione di utilizzare un file flat a persistere i dati, utilizzare XML per strutturare i dati. PHP ha un parser XML integrato .

Risposto il 18/09/2008 a 07:40
fonte dall'utente

voti
6

Se si desidera un risultato leggibile, è anche possibile utilizzare questo tipo di file:

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

In questo modo, si dispone di un solo file, è possibile eseguire il debug (e correggere manualmente) in modo semplice, è possibile aggiungere campi in seguito (alla fine di ogni riga) e il codice PHP è semplice (per ogni linea, suddiviso in base alle |).

Tuttavia, gli svantaggi è che si dovrebbe analizzare l'intero file per cercare qualcosa (se si dispone di milioni di ingresso, non è bene) e si dovrebbe gestire il separatore di dati (ad esempio, se il nick è la guerra | ordz).

Risposto il 18/09/2008 a 08:51
fonte dall'utente

voti
20

A mio parere, utilizzando un "Flat Database File", nel senso che stai significato (e la risposta che hai accettato) non è neccesarily il modo migliore per andare su cose. Prima di tutto, utilizzando serialize()e unserialize()può causare mal di testa PRINCIPALI se qualcuno entra e modifica il file (possono, infatti, inserire il codice arbritrary nel "database" di essere eseguito ogni volta.)

Personalmente, direi - perché non guardare al futuro? Ci sono state così tante volte che ho avuto problemi perché sono stato creare il mio file "proprietarie", e il progetto è esploso ad un punto in cui ha bisogno di una banca dati, e sto pensando "sai, desidero avevo scritto questo per un database per iniziare con" - perché il refactoring del codice richiede troppo tempo e fatica.

Da questo ho imparato che prova di futuro la mia applicazione in modo che quando si diventa più grande non devo andare a trascorrere giornate refactoring è il modo per andare avanti. Come faccio a fare questo?

SQLite. Funziona come un database, utilizza SQL, ed è abbastanza facile da cambiare nel corso di mySQL (espescially se si sta utilizzando le classi astratte per la manipolazione di database come faccio io!)

In realtà, espescially con la "risposta accettata" 's metodo, è possibile ridurre drasticamente l'utilizzo della memoria della vostra applicazione (non c'è bisogno di caricare tutti i 'record' in PHP)

Risposto il 21/09/2008 a 19:21
fonte dall'utente

voti
8

Ecco il codice che utilizziamo per Lilina:

<?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);
    }
}

?>

Memorizza ogni voce in un file separato, che abbiamo trovato è abbastanza efficiente per l'uso (non ci sono dati non necessari viene caricato ed è più veloce per salvare).

Risposto il 28/10/2008 a 11:45
fonte dall'utente

voti
6

IMHO, avete due opzioni, se si vuole evitare di homebrewing qualcosa:

  1. SQLite

    Se si ha familiarità con DOP, è possibile installare un driver PDO che supporta SQLite. Mai usato, ma ho usato una tonnellata DOP con MySQL. Ho intenzione di dare a questo un colpo su un progetto in corso.

  2. XML

    Fatto questo molte volte per relativamente piccole quantità di dati. XMLReader è una, classe leggera read-forward cursore-style. SimpleXML rende semplice per leggere un documento XML in un oggetto che è possibile accedere come qualsiasi altra istanza di classe.

Risposto il 02/12/2012 a 16:49
fonte dall'utente

voti
7

Ho scritto due semplici funzioni progettate per memorizzare i dati in un file. Potete giudicare voi stessi se è utile in questo caso. Il punto è quello di salvare una variabile PHP (se si tratta di una matrice o una stringa o un oggetto) in un file.

<?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;
}
Risposto il 19/12/2012 a 21:48
fonte dall'utente

voti
4

Solo sottolineando un potenziale problema con un database di file flat con questo tipo di sistema:

data|some text|more data

row 2 data|bla hbalh|more data

...eccetera

Il problema è che i dati cella contiene un "|" o un "\ n", allora i dati saranno persi. A volte sarebbe più facile raggruppati per combinazioni di lettere che la maggior parte delle persone non avrebbe usato.

Per esempio:

splitter Colonna: #$% (Shift+345)

splitter fila: ^&* (Shift+678)

File di testo: test data#$%blah blah#$%^&*new row#$%new row data 2

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

O qualcosa lungo queste linee. Inoltre, potrei aggiungere che i database di file flat sono buone per i sistemi con piccole quantità di dati (es. Meno di 20 righe), ma diventano enormi maiali di memoria per i database di grandi dimensioni.

Risposto il 04/01/2013 a 01:14
fonte dall'utente

voti
6

Questo sta ispirando come una soluzione pratica:
https://github.com/mhgolkar/FlatFire
Esso utilizza strategie multiple per la gestione dei dati ...
[Copiato da Readme file]

Gratuito o strutturato o misto

- 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
Risposto il 02/05/2013 a 14:57
fonte dall'utente

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