फ्लैट फ़ाइल डेटाबेस

PHP में फ्लैट फ़ाइल डेटाबेस संरचनाओं को बनाने के आसपास सबसे अच्छा अभ्यास क्या हैं? अधिकतर परिपक्व PHP फ्लैट फ़ाइल ढांचे में मैं एसक्यूएल-जैसी क्वेरी सिंटैक्स को लागू करने का प्रयास करता हूं, जो ज्यादातर मामलों में मेरे उद्देश्यों के लिए शीर्ष पर है (मैं उस बिंदु पर केवल डेटाबेस का उपयोग करता हूं)।

क्या इस समस्या को पहली जगह पर ले जाकर एक छोटे कोड ओवरहेड के साथ अच्छे प्रदर्शन और सुविधाओं को पाने के लिए वहां कोई सुरुचिपूर्ण चाल है?

0
जोड़ा संपादित
विचारों: 7
मैं यह जोड़ना चाहता हूं कि फ्लैट फ़ाइल डेटाबेस के लिए यहां एक पैकेज है github.com/tmarois/Filebase मुझे पता है कि यह एक पुराना सवाल है, लेकिन यह पैकेज सबसे हालिया निर्माण और रखरखाव है, साथ ही सुविधाओं से भरा शामिल करने के लिए सबसे उपेक्षा है।
जोड़ा लेखक timothymarois, स्रोत

12 उत्तर

एक फ्रेमवर्क जो मैं विचार कर रहा हूं वह ब्लॉगिंग प्लेटफ़ॉर्म के लिए होगा। चूंकि डेटा के बारे में किसी भी संभावित दृश्य के बारे में आप चाहते हैं कि तिथि के अनुसार क्रमबद्ध किया जाए, मैं इस संरचना के बारे में सोच रहा था:

प्रति सामग्री नोड में एक निर्देशिका:

./content/YYYYMMDDHHMMSS/

प्रत्येक नोड के उपनिर्देशिका सहित

/tags  
/authors  
/comments  

पूर्व-और बाद में प्रस्तुत सामग्री और जैसे के लिए नोड निर्देशिका में सरल पाठ फ़ाइलों के साथ-साथ।

यह एक साधारण PHP glob() कॉल (और शायद एक उलटा होने की अनुमति देगा परिणाम सरणी) सामग्री संरचना के भीतर बस कुछ भी पूछने के लिए:

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

"हास्यास्पद" टैग किए गए सभी लेखों सहित पथ वापस कर देंगे।

0
जोड़ा

यह सच है। serialize() इसके लिए भी बहुत उपयोगी हो सकता है।

मुझे लगता है कि एक व्यावहारिक प्रणाली के साथ आने की चाल जटिलता के साथ खुद को मारने के बिना डेटा नोड्स को इंडेक्स करने का कोई तरीका ढूंढ रही है।

0
जोड़ा

खैर, फ्लैट डेटाबेस की प्रकृति क्या है। क्या वे बड़े या छोटे हैं। क्या यह उन सरणी के साथ सरल सरणी है? यदि यह कुछ सरल कहता है तो उपयोगकर्ता प्रोफाइल इस प्रकार बनाया गया है:

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

और उस उपयोगकर्ता के लिए डीबी रिकॉर्ड को सहेजने या अपडेट करने के लिए।

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

और उपयोगकर्ता के लिए रिकॉर्ड लोड करने के लिए

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

लेकिन फिर यह कार्यान्वयन आपको आवश्यक डेटाबेस के आवेदन और प्रकृति पर अलग-अलग होगा।

0
जोड़ा

आप SQLite पर विचार कर सकते हैं। यह फ्लैट फ़ाइलों के रूप में लगभग सरल है, लेकिन आप पूछताछ के लिए एक एसक्यूएल इंजन मिलता है। यह PHP के साथ भी अच्छी तरह से काम करता है ।

0
जोड़ा
SQLite डिफ़ॉल्ट रूप से 5.0+ में बनाया गया था, लेकिन PHP 5.4+ से छूट (!) !!! जैसा कि मैंने जुलाई 2012 में लिखा था, SQLite डिफ़ॉल्ट रूप से अप-टू-डेट सिस्टम पर काम नहीं करेगा। आधिकारिक बयान यहां
जोड़ा लेखक Sliq, स्रोत
यदि आपके पास सर्वर पहुंच है तो SQLite PDO ड्राइवर स्थापित करना बहुत छोटा है। उबंटू / डेबियन पर Apache2 चल रहा है बस app-get php5-sqlite सेवा apache2 पुनरारंभ करें
जोड़ा लेखक siliconrockstar, स्रोत
@Sliq की टिप्पणी पर प्रतिक्रिया में, यह बताते हुए कि "SQLite था ... बंद कर दिया गया" सत्य है: "SQLite" नाम का एक्सटेंशन बंद कर दिया गया था और "SQLite3" अब डिफ़ॉल्ट रूप से सक्षम है। php.net/manual/en/sqlite.installation.php "PHP के बाद से 5.0 यह एक्सटेंशन PHP के साथ बंडल किया गया था। PHP 5.4 के साथ शुरुआत, यह एक्सटेंशन केवल पीईसीएल के माध्यम से उपलब्ध है। " php.net/manual/en/sqlite3.installation.php "SQLite3 विस्ता
जोड़ा लेखक Paul van Leeuwen, स्रोत

आईएमएचओ, यदि आप होमब्रीविंग से बचना चाहते हैं तो आपके पास दो विकल्प हैं:

  1. SQLite

    If you're familiar with PDO, you can install a PDO driver that supports SQLite. Never used it, but I have used PDO a ton with MySQL. I'm going to give this a shot on a current project.

  2. XML

    Done this many times for relatively small amounts of data. XMLReader is a lightweight, read-forward, cursor-style class. SimpleXML makes it simple to read an xml document into an object that you can access just like any other class instance.

0
जोड़ा

यदि आप मानव-पठनीय परिणाम चाहते हैं, तो आप इस प्रकार की फ़ाइल का भी उपयोग कर सकते हैं:

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

इस तरह, आपके पास केवल एक फ़ाइल है, आप इसे आसानी से डीबग कर सकते हैं (और मैन्युअल रूप से ठीक कर सकते हैं), आप बाद में फ़ील्ड (प्रत्येक पंक्ति के अंत में) जोड़ सकते हैं और PHP कोड सरल है (प्रत्येक पंक्ति के लिए, के अनुसार विभाजित करें |)।

हालांकि, दोष यह है कि आपको पूरी फ़ाइल को कुछ खोजने के लिए पार्स करना चाहिए (यदि आपके पास लाखों प्रविष्टियां हैं, तो यह ठीक नहीं है) और आपको डेटा में विभाजक को संभालना चाहिए (उदाहरण के लिए यदि निक वाईआर | ordz है)।

0
जोड़ा

यदि आप डेटा को बनाए रखने के लिए एक फ्लैट फ़ाइल का उपयोग करने जा रहे हैं, तो डेटा को ढांचे के लिए एक्सएमएल का उपयोग करें। PHP में एक अंतर्निहित xml पार्सर है।

0
जोड़ा
और मानव-पठनीयता के एक्सएमएल नियमों का पालन करें या आप धारावाहिक या जेसन या कुछ भी उपयोग कर सकते हैं।
जोड़ा लेखक Ben, स्रोत

मेरी राय में, अर्थ में "फ़्लैट फ़ाइल डेटाबेस" का उपयोग करके आप अर्थ (और आपके द्वारा स्वीकार किए गए उत्तर) को चीजों के बारे में जाने का सबसे अच्छा तरीका नहीं है। सबसे पहले, serialize() और unserialize() का उपयोग करके प्रमुख सिरदर्द का कारण बन सकता है अगर कोई फ़ाइल में प्रवेश करता है और संपादित करता है (वास्तव में, आप अपने आप में मनमानी कोड डाल सकते हैं "डेटाबेस" हर बार चलाने के लिए।)

निजी तौर पर, मैं कहूंगा - भविष्य को क्यों न देखें? ऐसे कई बार हुए हैं जिनके पास मुझे समस्याएं थीं क्योंकि मैं अपनी खुद की "स्वामित्व" फाइलें बना रहा हूं, और परियोजना उस बिंदु पर विस्फोट हो गई है जहां इसे डेटाबेस की आवश्यकता है, और मैं सोच रहा हूं "आप जानते हैं, मेरी इच्छा है मैं इसे डेटाबेस के लिए शुरू करने के लिए लिखा था "- क्योंकि कोड का रिफैक्टरिंग बहुत अधिक समय और प्रयास करता है।

इससे मैंने सीखा है कि भविष्य में मेरे आवेदन का सबूत है ताकि जब यह बड़ा हो जाए तो मुझे आगे बढ़ने और दिन में रिफैक्टरिंग करने का समय नहीं जाना है। मैं यह कैसे करु?

SQLite। यह डेटाबेस के रूप में काम करता है, एसक्यूएल का उपयोग करता है, और mySQL पर बदलने के लिए बहुत आसान है (espscially अगर आप डेटाबेस मैनिपुलेशन के लिए सार तत्वों का उपयोग कर रहे हैं जैसे मैं करता हूं!)

वास्तव में, "स्वीकार्य उत्तर" विधि के साथ espscially, यह आपके ऐप के स्मृति उपयोग में भारी कटौती कर सकते हैं (आपको सभी "रिकॉर्ड" को PHP में लोड करने की आवश्यकता नहीं है)

0
जोड़ा

यहां कोड है जिसे हम लिलिना के लिए उपयोग करते हैं:

<?php
/**
 * Handler for persistent data files
 *
 * @author Ryan McCue 
 * @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);
    }
}

?>

यह प्रत्येक प्रविष्टि को एक अलग फ़ाइल के रूप में संग्रहीत करता है, जिसे हमने पाया है उपयोग के लिए पर्याप्त कुशल है (कोई अनियंत्रित डेटा लोड नहीं होता है और यह सहेजने में तेज़ है)।

0
जोड़ा

मैंने फ़ाइल में डेटा स्टोर करने के लिए डिज़ाइन किए गए दो सरल फ़ंक्शन लिखे हैं। यदि आप इस मामले में उपयोगी हैं तो आप अपने लिए न्याय कर सकते हैं। बिंदु एक फ़ाइल में एक PHP वैरिएबल को सहेजना है (यदि यह या तो सरणी या ऑब्जेक्ट सरणी है)।

<?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;
}
0
जोड़ा
मैंने पाया कि यह दिलचस्प है और यह बेहतर तरीका है, क्योंकि हम सिर्फ स्वरूपित सरणी को फ़ाइल में डंप करते हैं। हमें इसे फिर से बनाने की जरूरत नहीं है, बस पढ़ें। इसके अलावा, चर संपादित करें यह थोड़ा आसान है। मैं इसका उपयोग कभी भी बड़े डेटा को स्टोर करने के लिए नहीं करूंगा, लेकिन मुझे डेटाबेस के बिना प्रोग्राम के मॉड्यूल को स्टोर करना व्यावहारिक लगता है। धन्यवाद।
जोड़ा लेखक erm3nda, स्रोत
यह एक स्वीकृत उत्तर और कई अतिरिक्त उत्तरों के साथ एक चार वर्षीय प्रश्न है। नए प्रश्नों पर ध्यान केंद्रित करने पर विचार करें जब तक कि यहां स्वीकृत उत्तर स्पष्ट रूप से गलत या अपर्याप्त नहीं है।
जोड़ा लेखक mcknz, स्रोत

इस प्रकार के सिस्टम के साथ एक फ्लैट फ़ाइल डेटाबेस के साथ एक संभावित समस्या को इंगित करना:

data|some text|more data

row 2 data|bla hbalh|more data

...आदि

समस्या यह है कि सेल डेटा में "|" होता है या एक "\ n" तो डेटा खो जाएगा। कभी-कभी उन अक्षरों के संयोजन से विभाजित करना आसान होता है जो अधिकांश लोग उपयोग नहीं करेंगे।

उदाहरण के लिए:

Column splitter: #$% (Shift+345)

Row splitter: ^&* (Shift+678)

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

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

या इन लाइनों के साथ कुछ भी। साथ ही, मैं जोड़ सकता हूं कि फ्लैट फ़ाइल डेटाबेस छोटे मात्रा में डेटा (यानी 20 पंक्तियों से कम) वाले सिस्टम के लिए अच्छे हैं, लेकिन बड़े डेटाबेस के लिए बड़ी मेमोरी होग बन जाते हैं।

0
जोड़ा
अच्छे अंक। इसे एक कदम आगे लेते हुए, PHP वास्तव में JSON को क्रमबद्ध कर सकता है। इनपुट से बचना बहुत आसान है, इसलिए आपको अजीब स्ट्रिंग संयोजनों का उपयोग करने की आवश्यकता नहीं है, इसलिए फ़ाइल अधिक पठनीय है।
जोड़ा लेखक Cypher, स्रोत

This one is inspiring as a practical solution:
https://github.com/mhgolkar/FlatFire
It uses multiple strategies to handling data...
[Copied from Readme File]

नि: शुल्क या संरचित या मिश्रित

- 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
0
जोड़ा