bases de données de fichiers plats

voix
101

Quelles sont les meilleures pratiques autour de la création de structures de base de données de fichiers plats en PHP?

Beaucoup des cadres plus de fichiers plats PHP matures que je vois essayer là-bas pour mettre en œuvre la syntaxe de requête SQL comme, qui est sur le dessus pour mes besoins dans la plupart des cas (je voudrais simplement utiliser une base de données à ce moment-là).

Y a-t-il des astuces élégantes là-bas pour obtenir de bonnes performances et de fonctionnalités avec une petite tête de code?

Créé 01/08/2008 à 15:19
source utilisateur
Dans d'autres langues...                            


12 réponses

voix
68

Eh bien, quelle est la nature des bases de données plates. Sont-ils grands ou petits. Est-il de simples tableaux avec des tableaux en eux? si son simple construit dire quelque chose UserProfiles comme tel:

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

et pour sauver ou mettre à jour l' enregistrement db pour cet utilisateur.

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

et de charger le dossier pour l'utilisateur

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

mais encore une fois cette mise en œuvre varie sur l'application et la nature de la base de données dont vous avez besoin.

Créé 01/08/2008 à 18:45
source utilisateur

voix
46

Vous pourriez envisager SQLite . Il est presque aussi simple que des fichiers plats, mais vous obtenez un moteur SQL pour effectuer des requêtes. Il fonctionne bien avec PHP aussi.

Créé 09/08/2008 à 00:00
source utilisateur

voix
20

À mon avis, en utilisant une « base de données de fichier plat » dans le sens que vous avez un sens (et la réponse que vous avez accepté) n'est pas neccesarily la meilleure façon d'aborder les choses. Tout en utilisant d' abord serialize()et unserialize()peut causer des maux de tête importants si quelqu'un obtient et édite le fichier (ils peuvent, en effet, mettre le code arbritrary dans votre « base de données » à exécuter à chaque fois.)

Personnellement, je dirais - pourquoi ne pas l'avenir? Il y a eu tant de fois que j'ai eu des problèmes parce que j'ai mes propres fichiers crée « propriétaires », et le projet a explosé à un point où elle a besoin d'une base de données, et je pense « tu sais, je souhaite Je l'avais écrit cela pour une base de données pour commencer » - parce que le refactoring du code prend trop de temps et d'efforts.

De cela, je l'ai appris que l'avenir épreuvage ma demande pour que quand il est plus grand que je ne dois pas aller passer des jours refactoring est la manière d'aller de l'avant. Comment puis-je faire cela?

SQLite. Il fonctionne comme une base de données, utilise SQL, et il est assez facile de passer à mySQL (espescially si vous utilisez des classes abstraites pour la manipulation de base de données comme je le fais!)

En fait, espescially avec la méthode de « réponse acceptée », il peut réduire radicalement l'utilisation de la mémoire de votre application (vous ne devez pas charger tous les « enregistrements » en PHP)

Créé 21/09/2008 à 19:21
source utilisateur

voix
15

C'est vrai. serialize()peut être très utile pour cela aussi.

Je pense que le truc pour venir avec un système viable est de trouver un moyen d'indexer les noeuds de données sans tuer vous-même avec la complexité.

Créé 01/08/2008 à 15:58
source utilisateur

voix
11

Un cadre J'envisage serait une plate-forme de blogs. Depuis à peu près tout vue possible de données que vous voulez serait trié par date, je pensais à cette structure:

Un répertoire par nœud de contenu:

./content/YYYYMMDDHHMMSS/

Les sous-répertoires de chaque noeud comprenant

/tags  
/authors  
/comments  

Ainsi que de simples fichiers texte dans le répertoire des noeuds pour le contenu pré et post-rendus et autres.

Cela permettrait d' un simple PHP glob()appel (et probablement un renversement du tableau de résultat) pour interroger sur à peu près tout dans la structure du contenu:

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

Renverrait chemins y compris tous les articles étiquetés « drôle ».

Créé 01/08/2008 à 15:26
source utilisateur

voix
8

Voici le code que nous utilisons pour 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);
    }
}

?>

Il stocke chaque entrée dans un fichier séparé, que nous avons trouvé est assez efficace pour une utilisation (pas de données inutiles est chargé et il est plus rapide pour sauver).

Créé 28/10/2008 à 11:45
source utilisateur

voix
8

Si vous allez utiliser un fichier plat pour maintenir les données, utiliser XML pour structurer les données. PHP dispose d' un analyseur XML intégré .

Créé 18/09/2008 à 07:40
source utilisateur

voix
7

J'ai écrit deux fonctions simples conçues pour stocker des données dans un fichier. Vous pouvez juger par vous-même si elle est utile dans ce cas. Le point est d'enregistrer une variable php (si elle est soit un tableau d'une chaîne ou un objet) dans un fichier.

<?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;
}
Créé 19/12/2012 à 21:48
source utilisateur

voix
6

Celui - ci est source d' inspiration comme une solution pratique:
https://github.com/mhgolkar/FlatFire
Il utilise plusieurs stratégies pour la gestion des données ...
[Copié à partir du fichier Lisez - moi]

Libre ou structuré ou mixte

- 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
Créé 02/05/2013 à 14:57
source utilisateur

voix
6

, Vous avez deux options à mon humble avis, si vous voulez éviter homebrewing quelque chose:

  1. SQLite

    Si vous êtes familier avec PDO, vous pouvez installer un pilote PDO qui prend en charge SQLite. Jamais utilisé, mais j'ai utilisé une tonne PDO avec MySQL. Je vais donner un coup de feu ce sur un projet en cours.

  2. XML

    Fait cela plusieurs fois pour des quantités relativement faibles de données. XMLReader est un poids léger, lecture avant, classe de style curseur. SimpleXML rend simple à lire un document XML dans un objet que vous pouvez accéder comme tout autre instance de classe.

Créé 02/12/2012 à 16:49
source utilisateur

voix
6

Si vous voulez un résultat lisible par l'homme, vous pouvez également utiliser ce type de fichier:

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

De cette façon, vous avez un seul fichier, vous pouvez le déboguer (et corriger manuellement) facilement, vous pouvez ajouter des champs plus tard (à la fin de chaque ligne) et le code PHP est simple (pour chaque ligne, divisé selon |).

Toutefois, les inconvénients est que vous devez analyser l'intégralité du fichier pour rechercher quelque chose (si vous avez des millions d'entrée, il ne va pas bien) et vous devez gérer le séparateur des données (par exemple si le pseudo est WaR | ordz).

Créé 18/09/2008 à 08:51
source utilisateur

voix
4

Il suffit de remarquer un problème potentiel avec une base de données de fichier plat avec ce type de système:

data|some text|more data

row 2 data|bla hbalh|more data

...etc

Le problème est que les données de cellule contient un « | » ou un « \ n », alors les données seront perdues. Parfois, il serait plus facile de diviser par des combinaisons de lettres que la plupart des gens ne seraient pas utiliser.

Par exemple:

séparateur de colonne: #$% (Shift+345)

séparateur de ligne: ^&* (Shift+678)

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

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

Ou tout le long de ces lignes. Je pourrais ajouter que les bases de données de fichiers plats sont bons pour les systèmes avec de petites quantités de données (par exemple. Moins de 20 lignes), mais deviennent énormes porcs de mémoire pour les bases de données plus grandes.

Créé 04/01/2013 à 01:14
source utilisateur

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