Flat fil databaser

stemmer
103

Hva er de beste praksis rundt skape flat fil database strukturer i PHP?

Mange av de mer modne PHP flat fil rammeverk jeg ser der ute prøver å implementere SQL-lignende forespørsel syntaks, som er over toppen for mitt formål i de fleste tilfeller (jeg ville bare bruke en database på det tidspunktet).

Er det noen elegante triks der ute for å få god ytelse og funksjoner med en liten kode overhead?

Publisert på 01/08/2008 klokken 14:19
kilden bruker
På andre språk...                            


12 svar

stemmer
70

Vel, hva er innholdet i de flate databaser. Er de store eller små. Er det enkle matriser med arrays i dem? hvis noe enkelt si userprofiles bygget som sådan:

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

og for å spare eller oppdatere db rekord for den brukeren.

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

og å laste posten for brukeren

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

men igjen denne implementeringen vil variere på programmet og innholdet i databasen du trenger.

Svarte 01/08/2008 kl. 17:45
kilden bruker

stemmer
46

Du kan vurdere SQLite . Det er nesten så enkelt som flate filer, men du får en SQL-motoren for spørring. Det fungerer godt med PHP også.

Svarte 08/08/2008 kl. 23:00
kilden bruker

stemmer
20

Etter min mening, ved hjelp av en "flat fil database" i den forstand du betyr (og svaret du har godtatt) er ikke nødvendigvis den beste måten å gå om ting. Først av alt, bruke serialize()og unserialize()kan forårsake store hodepine hvis noen kommer inn og redigerer filen (de kan faktisk sette arbritrary koden i "database" som skal kjøres hver gang.)

Personlig vil jeg si - hvorfor ikke se inn i fremtiden? Det har vært så mange ganger at jeg har hatt problemer fordi jeg har vært å skape mine egne "proprietære" filer, og prosjektet har eksplodert til et punkt hvor det er behov for en database, og jeg tenker "du vet, jeg ønsker jeg hadde skrevet dette for en database til å begynne med" - fordi refactoring av koden tar altfor mye tid og krefter.

Fra dette har jeg lært at fremtiden korrektur min søknad slik at når det blir større trenger jeg ikke å gå og tilbringe dager refactoring er veien å gå fremover. Hvordan gjør jeg dette?

SQLite. Det fungerer som en database, bruker SQL, og er ganske lett å gå over til MySQL (espescially hvis du bruker abstrahert klasser for database manipulasjon som jeg gjør!)

Faktisk espescially med "aksepterte svaret" 's metode, det kan drastisk redusere minnebruken på appen din (du trenger ikke å laste alle 'poster' i PHP)

Svarte 21/09/2008 kl. 18:21
kilden bruker

stemmer
15

Det er sant. serialize()kan være ganske nyttig for det også.

Jeg tror trikset å komme opp med et levedyktig system er å finne en måte å indeksere datanoder uten å drepe deg selv med kompleksitet.

Svarte 01/08/2008 kl. 14:58
kilden bruker

stemmer
12

En ramme jeg vurderer ville være for en blogging plattform. Siden nesten alle mulige visning av data du ønsker ville bli sortert etter dato, tenkte jeg på denne strukturen:

En katalog for hvert innhold node:

./content/YYYYMMDDHHMMSS/

Underkataloger for hver node, inkludert

/tags  
/authors  
/comments  

Samt enkle tekstfiler i nodekatalogen for pre- og post-gjengitte innholdet og lignende.

Dette vil gi et enkelt PHP glob()samtale (og sannsynligvis en reversering av resultatet array) til å spørre om det meste innen innholdsstrukturen:

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

Ville tilbake stier inkludert alle artikler merket "morsomt".

Svarte 01/08/2008 kl. 14:26
kilden bruker

stemmer
9

Her er koden vi bruker for 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);
    }
}

?>

Den lagrer hver oppføring som en egen fil, som vi har funnet er effektiv nok til bruk (ingen unødvendige data er lastet, og det er raskere å spare).

Svarte 28/10/2008 kl. 10:45
kilden bruker

stemmer
8

Hvis du kommer til å bruke en flat fil til å vedvare data, bruker XML for å strukturere dataene. PHP har en innebygd XML parser .

Svarte 18/09/2008 kl. 06:40
kilden bruker

stemmer
7

Jeg har skrevet to enkle funksjoner utviklet for å lagre dataene i en fil. Du kan dømme selv om det er nyttig i dette tilfellet. Poenget er å lagre en php variabel (dersom det er enten en matrise en streng eller et objekt) til en fil.

<?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;
}
Svarte 19/12/2012 kl. 20:48
kilden bruker

stemmer
6

Dette er inspirerende som en praktisk løsning:
https://github.com/mhgolkar/FlatFire
Den bruker flere strategier for å håndtere data ...
[Kopiert fra Readme fil]

Gratis eller Structured eller 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
Svarte 02/05/2013 kl. 13:57
kilden bruker

stemmer
6

IMHO, har du to alternativer hvis du vil unngå homebrewing noe:

  1. SQLite

    Hvis du er kjent med PUD, kan du installere en PUD driver som støtter SQLite. Aldri brukt det, men jeg har brukt PUD massevis med MySQL. Jeg kommer til å gi dette en sjanse på en nåværende prosjekt.

  2. XML

    Gjort dette mange ganger for relativt små mengder data. XMLReader er en lett, lese fremover, markør-stil klasse. SimpleXML gjør det enkelt å lese et XML-dokument til et objekt som du kan få tilgang til akkurat som alle andre klassen forekomst.

Svarte 02/12/2012 kl. 15:49
kilden bruker

stemmer
6

Hvis du vil ha et resultat lesbar, kan du også bruke denne filtypen:

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

På denne måten har du bare en fil, kan du feilsøke det (og fikse manuelt) lett, kan du legge til felt senere (i slutten av hver linje) og PHP-koden er enkel (for hver linje, delt i henhold til |).

Imidlertid er ulempene at du bør analysere hele filen for å søke noe (hvis du har millioner av oppføring, er det ikke fint), og du bør håndtere separator i data (for eksempel hvis nick er krig | ordz).

Svarte 18/09/2008 kl. 07:51
kilden bruker

stemmer
4

Bare å peke ut et potensielt problem med en flat fil database med denne type system:

data|some text|more data

row 2 data|bla hbalh|more data

...etc

Problemet er at cellen data inneholder en "|" eller en "\ n" så dataene vil gå tapt. Noen ganger vil det være lettere å splitte ved kombinasjoner av bokstaver som folk flest ikke ville bruke.

For eksempel:

Kolonne klyv: #$% (Shift+345)

Row klyv: ^&* (Shift+678)

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

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

Eller noe langs disse linjene. Også, jeg kan legge til at flat fil databaser er bra for systemer med små mengder data (ie. Mindre enn 20 p), men blir store minne svin for større databaser.

Svarte 04/01/2013 kl. 00:14
kilden bruker

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